Sunday, September 10, 2017

Moving the Raspberry PI away from Swing

Rationale

This starts from a simple observation. A Raspberry PI can run on a boat, and consumes a very small amount of energy. It can do a lot of computations, logging, and multiplexing, among many others. It can run 24x7, without you noticing. It makes no noise, almost no light, and requires ridiculous amount of energy to run. Even a Raspberry PI Zero does this kind of job (for even less power), successfully.
One thing it is not good at is graphical UI. A graphical desktop is often too demanding on a small board like the Raspberry PI Zero. It becomes some times really slow, and cumbersome.
Running on it a program like OpenCPN seems absurd to me. Such a program runs fine on a bigger device, with several gigabytes of RAM available.
But, running a laptop 24x7 would be in many cases too demanding, specially on a sailboat, where everyone hates to run the engine ;)
I observed that at sea, I spend only a couple hours a day in front of the laptop, but it is often running by itself, doing some logging or calculations.
This is where it comes together, you could have a Raspberry PI Zero doing logging, multiplexing and what not, broadcasting require data on its own network (see the NMEA Multiplexer about that), then you would use a laptop whenever necessary, connecting on the Raspberry PI's network to get NMEA Data and more.
In addition, you can also use tablets and smart-phones, those devices know how to connect to a network, and have great rendering capabilities.
A problem is that writing a native application on those devices requires specific knowledge of the operating system, those skills are often redundant. iOS, Android, JavaFx, Swing all have UI rendering capabilities, but they're all totally different, and the learning curve for each of them is not always smooth.
A solution would be to write the UI part of the applications using HTML. Whatever OS runs on your laptop, tablet or smartphone (Windows, MacOS, iOS, Linux, Android, etc), you have a browser available, supporting HTML5 (if it does not, you should really upgrade it).
HTML5 and JavaScript have been gaining a lot of momentum in the recent years, new frameworks like jQuery, ionic, ReactJS, ...) appear every day, and provide really rich and nice UI.
My feeling would be to go down this route whenever possible, that would save a lot of efforts, and provide a pretty cool Graphical User Interface (GUI). I have written a lot of GUI in Swing. It would be now time to upgrade it. Re-writing them using JavaFX does not sound like the right choice. If I have to learn a new language to build a modern GUI, for now I'd rather use JavaScript and HTML5. This way, the same code runs whenever a browser exists... You have REST APIs available on the server (again, a Raspberry PI, even the Zero does the job well), and you use AJAX and Promises to get to them from the Web UI (WebSockets are also a realistic option, tested). The computation required to produce the payload returned by the REST services (often in json format) is easily supported by a Raspberry PI, and the complexity of the UI rendering is 100% taken care of by the browser, running on a more powerful device.

Implementation

To make sure all this is realistic, we have a REST implementation of a Tide Server, available here.
First, we have defined the REST Services, like
 /GET /tide-stations
 /GET /tide-stations/{station}
 /POST /tide-stations/{station}/wh?from=XXX&to=YYY
 /POST /tide-stations/{station}/wh/details?from=XXX&to=YYY
this is the easy part - and then an HTML5/JavaScript User Interface.


Harmonic coefficients are available for display


Period of time goes - in this UI - up to 1 month.


For one month, with harmonic coefficients, the volume of data transferred from the server is about 10Mb, it took about 14 seconds to get them.


In a most common case, it is around 25Kb.


This is running on a Raspberry PI, even a Raspberry PI Zero does the job without complaining.
There are a couple of challenges to address, JavaScript is not very well TimeZone equipped. But there are ways to get it to work.
That seems to be a viable approach.
Interestingly, even if we are trying here to address an energy problem - and not a budget one - a Raspberry PI Zero today cost just $10.

Saturday, December 31, 2016

NMEA Multiplexer, OpenCPN, GPSd...

I have been working on an NMEA Multiplexer that can run on small boards, like the Raspberry PI Zero. The code is available on github, see the documentation in the README.md.

It allows to mix all kinds of NMEA Sources into a single (or multiple) stream(s). You can read from Serial Ports, Log file(s), TCP, WebSocket, Sensors (like BME280, HTU21DF, LSM303, etc), merge those data and rebroadcast them on Serial port, TCP, Log file, WebSocket, GPSd, etc. UDP is being worked on.

Data can also be computed and injected in the output stream, like True Wind, Current direction and speed, etc.

As a graphical desktop can be cumbersome on small boards, the Multiplexer comes with a tiny HTTP server that provides a Web UI and REST services to allow remote Admin.

It also comes with several demos and samples
This all works just fine with OpenCPN, SeaWi, that can take TCP streams as NMEA Data Input.
I was also wondering about GPSd. I had some mixed feelings about it. Mostly, I was asking myself "Why should I parse GPSd json objects if I can parse NMEA Sentences?", and could not find any satisfying reason. The topic is mentioned on the GPSd web site's FAQ pages, but nothing clear (to me) came up from that.
Interestingly, OpenCPN can also take GPSd streams as input. But there is a trick.
The first GPSd exchange begins with a ?WATCH request. It is followed by a JSON Object like this:
  ?WATCH={"enable":true,"json":true}
... and here is the trick, OpenCPN sends a
 ?WATCH={"enable":true,"nmea":true}
This nmea option is "poorly" documented, but very useful. Instead of sending JSON objects, GPSd spits out the raw NMEA sentences, as they were read. Then GPSd is just a regular TCP stream, and OpenCPN already knows how to parse the NMEA sentences it delivers. This way, GPSd is not limited to strictly GPS-related sentences. It can convey all NMEA sentences, Boat Speed related, Wind related, etc. This is what the GPSd forwarder that comes with the Multiplexer is doing.
Happy Streaming, happy new year!

Sunday, July 24, 2016

Live Wallpaper, offline

The Live Wallpaper (in the navigation console) has been improved. Several bugs were fixed (like the one for the daylight), and you can now use it offline, like when no NMEA data are coming. This can be useful when you are not on the boat (like at home).

You can give a default position (in the preferences), and it will be used when no GPS Data is available.
New features:
  • The tilt is based on the Sun declination
  • You can have Moonlight and Sunlight
  • The tide curve of the closest station is displayed (closest in a radius of 100 nautical miles)
  • Sun and Moon positions are displayed (when the body is visible)
Code and (some) doc are available on GitHub.

Sunday, March 13, 2016

IoT for dummies

Internet of things, what's the big deal?
We have a device, that can read sensors on one side, and connect to the Internet on the other, nothing revolutionary here. The challenge is to reach the device, from somewhere on the Internet, the device that reads the sensors does not necessary have a public IP address.
This is why the key component is the IoT server.
The device (the one with sensors) pushes data on the IoT server. The server can then be read from anywhere on the net.

On top of that, you can push data to the IoT device. For example, in a room:
  • the device is connected to a temperature sensor, and pushes temperature data to the IoT server (and so, they can be read from a browser, smartphone...)
  • the device is connected to a relay, data can be sent to the device (like from a browser, smartphone...), to drive the relay. If the relay is connected to a heater, you can manage the room temperature.


Typically, you can have a Raspberry PI, Arduino, or similar board, reading - at home - a temperature sensor to publish the air temperature onto the IoT server. You access those data from a browser (from your office, your smart-phone, whatever). Then you may decide to turn the heater on at home, the Raspberry PI (or its friends) has a relay that drives the heater.

Many server also use some push technology (like WebSocket or similar), so a client can be notified. A server like Adafruit IO provides this service for free, Particle also does it to some extend.

In addition, Adafruit IO provides a REST interface, very slick.
See an example of a REST client - in Java - on github. It shows how to read and write data on the server.

A real IoT application is also featured here in github, along with its Adafruit IO dashboard. It reads a BME280 (for the air temperature), and provides a toggle button (switch) that drives a relay on the Raspberry PI, to turn a heater on or off.

Friday, December 11, 2015

Raspberry PI Zero is here

I just received mine. And it just works. It takes a ridiculous amount of energy, and works just like its bigger brothers. Just a couple of things to keep in mind:
  • Use the latest RasPian image, I used - successfully - the one from Nov-11, 2015 (2015-11-21-raspbian-jessie.img)
  • If you use a desktop USB keyboard, you need a powered USB hub
  • Once started, do not forget to expand your file system, so it uses all the space available on your SD card
I used it with the small Edimax Wireless USB dongle (the powered hub is not required for this one), I got started in no time. I was able to ssh to it and run everything on it! So far, it is an amazing machine. A real fully featured Linux computer for $5. And 20 times more memory than the one I had in my desk 25 years back...
Check out Eben Upton's video about that:

That would remind many things to some of us... Amstrad, Amiga, Atari, wow! I must be getting old.

PS: About the pinout: Put the SD Card on top, the biggest Raspberry design under the board. The pin #1 (3V3) is at the top left of the header.

Thursday, November 19, 2015

Monitor the Boat, remotely

With a FONA connected on the Raspberry PI (where the NMEA Console is running), you can remotely monitor what's going on.
Sending a '?' returns the menu, all subsequent available commands are 1 or 2 character long.

The feature has been implemented - as usual - as a UserExit. This UserExit is in the Desktop repo, the FONA Java interface is here.
Add the following parameter to the command line:
 -ue:olivsoftdesktopuserexits.FONAUserExit

Just by sending an SMS, you can retrieve the data read by the Raspberry PI on board, like True Wind Speed, Battery Voltage, Air and Water Temperature, etc, all you need is a smart phone that can send and receive SMSs.

That sounds promising...

This assumes that the boat is docked in a place where there is SMS coverage, of course. I'm working on an Internet version, with a Particle Photon, or an ESP8266...

Saturday, June 06, 2015

Scala on the Raspberry PI

As Scala compiles its files as Java class-files, they run on a regular JVM, with a few Scala-specific jar-files in the classpath.
Even if it is not the most productive way to get work done, it is possible to compile Java files on the Raspberry PI, as well as Scala files. Personally, I prefer to develop in an IDE, and use FTP to push the classes to the Raspberry PI, it's much faster, and the IDE is much more productive than vi.
The explanations I found here got me started.
And again, as Scala runs on a Java Virtual Machine (JVM), all the work done with PI4J is fully available from Scala.
The following code (available on github) shows how to read a BMP180 from Scala:
 import adafruiti2c.sensor.AdafruitBMP180

 object Scala_101 {
   def main(args: Array[String]) {
     println("Hello, Scala world!")
     val bmp180 = new AdafruitBMP180
     try
     {
       val temp  = bmp180.readTemperature
       val press = bmp180.readPressure / 100
       println(s"CPU Temperature   :  ${SystemInfo.getCpuTemperature}\272C")
       println(s"Temp:${temp}\272C, Press:${press} hPa")
     }
     catch
     {
       case ex: Exception => {
         println(ex.toString())
       }
     }
   }
 }
  
To run it, I used a script like this:
 #!/bin/bash
 # 
 SCALA_HOME=/home/pi/.sbt/boot/scala-2.10.3
 PI4J_HOME=/opt/pi4j
 #
 CP=$SCALA_HOME/lib/scala-library.jar
 # 
 CP=$CP:$PI4J_HOME/lib/pi4j-core.jar
 CP=$CP:../AdafruitI2C/classes
 CP=$CP:./out/production/Scala.101
 # 
 sudo java -classpath "$CP" Scala_101
  
And all is good, the output is
 Hello,Scala world!
 CPU Temperature  :40.6°C
 Temp:22.5°C, Press:1010.73 hPa