Monday, November 26, 2018
Saturday, August 25, 2018
Smart watch..., who's smart, who's watching?
Then a while back, Pebble got acquired by Fitbit. And now, the Cloud IDE of Pebble is not available anymore. Than means I cannot develop new apps for my Pebble, even if it is still working just fine.
Why would I buy a new watch (twice as expensive), and re-write all my apps? This is quite frustrating...
In fact, there was something wrong from the beginning.
All those so-called smart watches need a Bluetooth cell-phone to connect to, and from there it will reach other data. Why not a TCP-based protocol from the watch, to bypass the phone? Power consumption? I doubt it.
This is not about accessibility or configuration either, I do it all the time for Raspberry Pis and similar boards,
ssh and similar protocols have been here for this kind of remote access, for ages, and for good reasons.
Smart glasses, head-up displays (HUD), smart watches, all those devices are just displays, all they need is to connect to a data bus and display what they mean to (just like an NMEA bus).
I suspect some marketing bullshit behind the scene..., again.
If this kind of TCP watch does not show up soon, I'll build one. Bam!
Saturday, July 14, 2018
Raspberry PI, PWM, servos, and PCA9685
Pulse Width Modulation (PWM) is the technique used from a digital source to simulate an analog output.
For example, imagine that you want to dim an
led from a digital device, to make it look like it is glowing.
The digital device only has pins that can take 2 values: 0 or 3V3.
0 means that the led will be off, 3V3 means it will be on, at 100% of its brightness.
In short, it is on or off, and there is nothing in between.
But here is an idea to work around that issue:
To show it at
50% of its brightness, the idea is to turn it off 50% of the time, and on 50% of the time.
To show it at
25% of its brightness, it will be on 25% of the time, and off 75% of the time.
If the on-off cycles are short and fast enough, a human eye will no be able to see them, it will only have the illusion of the resulting brightness.
A human eye cannot make the distinction between images separated by less than one 10th of a second. That is why the movies are shot at 24 images per second, so you cannot tell the difference between the frames.
This technique is call Persistence of Vision (POV).
The #1 parameter of PoV is the human retina. To have an idea of how much it is important, just put your cat in front of a TV, and see how much he/she reacts. To a cat, it might just be a fuzzy screen...
- The early movies - like Charlie Chaplin's silent ones - were shot at 16 images per second, fast enough to induce POV. They were later projected by faster projectors - 24 frames per second. That is why the characters seem to move faster. They were originally moving normally.
Here are examples of PWM applied to POV:
The Raspberry PI does not have analog pins, we need to use Pulse Width Modulation to simulate analog values, a servo is an analog device.
We use for that the method
setPWM(channel, 0, pulse), that will eventually write to the registers
of the device.
An instruction like
setPWM(channel, 0, pulse) means:
- On channel
channel(0to15on thePCA9685) - in each cycle, turn the power
onbetween0andpulse.
pulse has a value between 0 and 4095, that is 4096 distinct values, 4096 is 212, the PCA9685 is a 12 bit device.
The frequency
The frequency is provided in Hertz (Hz). A frequency of 60 means 60 cycles per second.At 60 Hz, a cycle will be
1 / 60 second, which is 0.01666666 second, or 16.66666 milli-second (ms).
The pulse
For each of the cycles set above by setting the frequency, we need to determine theint value,
between 0 and 4095, corresponding to the pulse in milliseconds we want to simulate with PWM.
In the class
i2c.servo.pwm.PCA9685.java, this is done in this method:
public static int getServoValueFromPulse(int freq, float targetPulse) {
double pulseLength = 1_000_000; // 1s = 1,000,000 us per pulse. "us" is to be read "micro (mu) sec".
pulseLength /= freq; // 40..1000 Hz
pulseLength /= 4_096; // 12 bits of resolution. 4096 = 2^12
int pulse = (int) Math.round((targetPulse * 1_000) / pulseLength); // in millisec
if (verbose) {
System.out.println(String.format("%.04f \u00b5s per bit, pulse: %d", pulseLength, pulse));
}
return pulse;
}
The cycle length (in ms) obviously depends on the frequency.
The pulse required for the servo to work is emitted once per cycle.
Example
As an example, let us calculate for a60 Hz frequency the pulse value to send to setPWM(channel, 0, pulse)
for a 1.5 millisecond PWM:
- 1 cycle has a duration of
1 / 60second, or16.66666milliseconds. - each cycle is divided in
4096slots, we can say that4096bits =16.6666ms. - the solution is provided by a rule of three:
value=4096* (pulse/16.66666), which is368.64, rounded to369.
A comment about servos' compliance and reliability
Theoretically, servos follow those rules:| Pulse | Standard | Continuous |
|---|---|---|
| 1.5 ms | 0 ° | Stop |
| 2.0 ms | 90 ° | FullSpeed forward |
| 1.0 ms | -90 ° | FullSpeed backward |
0.5 ms and 2.5 ms.
Before using them, servos should be calibrated. You can use the class
i2c.samples.IntercativeServo.java can be used for that,
you set the pulse values interactively, and you see what the servo is doing.
$> ./inter.servo Connected to bus. OK. Connected to device. OK. freq (40-1000) ? > 60 Setting PWM frequency to 60 Hz Estimated pre-scale: 100.72526 Final pre-scale: 101.0 Servo Channel (0-15) : 1 Entry method: T for Ticks (0..4095), P for Pulse (in ms) > p Enter 'quit' to exit. Pulse in ms > 1.5 setServoPulse(1, 1.5) 4.0690 μs per bit, pulse:369 ------------------- Pulse in ms > 0.5 setServoPulse(1, 0.5) 4.0690 μs per bit, pulse:122 ------------------- Pulse in ms > 0.6 setServoPulse(1, 0.6) 4.0690 μs per bit, pulse:147 ------------------- Pulse in ms > 2.4 setServoPulse(1, 2.4) 4.0690 μs per bit, pulse:589 ------------------- Pulse in ms > 2.5 setServoPulse(1, 2.5) 4.0690 μs per bit, pulse:614 ------------------- ... etc.Once you have determined the appropriate min and max values, you also have the
int values
to feed the setPWM with.
Some links:
- https://github.com/OlivierLD/raspberry-pi4j-samples/blob/master/I2C.SPI/PWM.md
- http://raspberrypi.lediouris.net/servo/readme.html
- POV at work
Tuesday, June 12, 2018
Languages Comparison
For the fun: Same problem addressed in several languages, read the paper here.
It is about matrix and systems of equations resolution, curve smoothing, etc.
Done in C, Java, Processing, Scala, Kotlin, Python, JavaScript, Groovy, Go, Clojure (in progress), ...
Tuesday, April 24, 2018
Controlling invisible machines with emails, from Java
Here is the problem
You have your network at home, with several machines connected to it (laptops, tablets, Raspberry PIs, phones, etc). Your home network is a Local Area Network (aka LAN), the machines can see each other, but they cannot be seen from outside, from the Internet.You may very well want to deal with those machines while away from home, to restart services, launch a new program, or even reboot.
In the configuration mentioned above, this is simple, you just cannot do it. And that is frustrating!
There is a way though. Those machines on your home LAN can send and receive emails...
Using JavaMail
JavaMail is a Java package that has been available for ever, it understands the email protocols (IMAP, POP3, SMTP, etc), and can be used to interact with email accounts programmatically.
An example
There is an example of such an interaction on this github repository.The fastest way to get it running is to run the following commands (these are for Linux - and MacOS - on Windows, use the git shell):
$ git clone https://github.com/OlivierLD/raspberry-coffee.git $ cd raspberry-coffee $ cd common-utils $ ../gradlew shadowJar $ cp email.properties.sample email.properties $ vi email.properties $ # Here you modify your properties file to match your email account $ java -cp ./build/libs/common-utils-1.0-all.jar email.examples.EmailWatcher -send:google -receive:googleThe
-send:google -receive:google depends on the settings in your email.properties.
Then, to the account mentioned in the
email.properties, send a message like this:
Subject: execute Content: whoami ifconfig uname -aNote: this example requires the content to be in
plain/text.
Once the message is received by the
EmailWatcher, it sends you an acknowledgement:
Then, the 3 commands are processed by the EmailWatcher, you would see in its console an output like that:
Start receiving. Received: whoami ifconfig uname -a Operation: [execute], sent for processing... pi lo0: flags=8049And finally, you receive an email like that: ... meaning that the commands you've sent have been executed.mtu 16384 options=1203 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 ...
You can also attach the script to execute to a blank email, with topic execute-script:
Attach a file like this:
#!/bin/bash whoami ifconfig ps -ef | grep EmailWatcher... and just wait for the result to come back to you:
Scripts execution returned: pi eth0: flags=4099mtu 1500 ether a4:ba:db:c9:04:2e txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 18 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1 (Local Loopback) RX packets 9215 bytes 2022884 (1.9 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 9215 bytes 2022884 (1.9 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlan0: flags=4163 mtu 1500 inet 192.168.42.3 netmask 255.255.255.0 broadcast 192.168.42.255 inet6 fe80::4038:1f53:b94f:ccc2 prefixlen 64 scopeid 0x20 ether 78:e4:00:78:ad:8f txqueuelen 1000 (Ethernet) RX packets 8848724 bytes 696021134 (663.7 MiB) RX errors 0 dropped 0 overruns 0 frame 18848059 TX packets 6040965 bytes 795472510 (758.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 17 base 0xc000 pi 12476 12472 1 16:39 pts/0 00:00:53 java -cp ./build/libs/RasPISamples-1.0-all.jar weatherstation.email.EmailWatcher -send:google -receive:google pi 16204 16199 0 18:04 pts/0 00:00:00 grep EmailWatcher >> sh ./attachments/2018-04-26_18-04-27/sample.sh returned status 0
Comments
This process is not synchronous, this could be a drawback... But still, it allows you to interact remotely with machines invisible from the Internet.Having the command
java -cp ./build/libs/common-utils-1.0-all.jar email.examples.EmailWatcher -send:google -receive:googlefired when the machine boots will allow you make sure it is waiting for your emails as soon as the machine is up.
This EmailWatcher as it is also allows you to execute scripts, attached to the email. Look into the code for details ;)
It is even possible to ssh to another machine and execute a bunch of commands stored in a script... The command you send in the email's body would be like
ssh pi@192.148.42.13 bash -s < ~/nodepi.banner.shIf a password is required, use
sshpass:
sshpass -p 'secret-password' ssh pi@192.148.42.13 bash -s < ~/nodepi.sudo.shYou can even
sudo:
echo 'secret-password' | sudo -S privilegedCommandThis can be dangerous, hey? With great power come great responsibilities...
Sunday, April 15, 2018
Head-Up Display (HUD)
The data are displayed on the screen, reflected on the transparent support, and nothing is preventing you from seeing through it. (Click the image to enlarge it)
Here is above an HTML page, tweaked by some CSS classes to mirror the data (as the page is reflected on the screen, the page content has to be displayed as in a mirror, and flipped upside down.). In this case, the page is rendered on Chromium in
kiosk mode, running on a Raspberry PI with a touch screen attached to it.
CSS Classes:
.mirror {
display: block;
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
-o-transform: matrix(-1, 0, 0, 1, 0, 0);
transform: matrix(-1, 0, 0, 1, 0, 0);
}
.upside-down {
height: 100%;
width: 100%;
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
.mirror-upside-down {
display: block;
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg);
-moz-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg);
-o-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg);
transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg);
}
In the picture above, we use the class as follow:
<div id="the-div" class="mirror-upside-down big" style="padding: 0px; text-align: center;">
<hr/>
<table>
<tr>
<td colspan="2">GPS Data</td>
</tr>
<tr>
<td>
<span>Your position:</span>
<br/>
<span>N 37° 44.93'</span>
...
The page on the screen (not on the wind shield) would actually look like this:
| GPS Data | |
|
Your position:
N 37° 44.93' W 122°30.42' |
Your Speed:
12.34 kts |
You can also work around the perspective effect on the reflected page by tweaking the CSS classes:
.mirror-upside-down {
display: block;
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg) perspective(50em) rotateX(-40deg);
-moz-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg) perspective(50em) rotateX(-40deg);
-o-transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg) perspective(50em) rotateX(-40deg);
transform: matrix(-1, 0, 0, 1, 0, 0) rotate(180deg) perspective(50em) rotateX(-40deg);
}
| GPS Data | |
|
Your position:
N 37° 44.93' W 122°30.42' |
Your Speed:
12.34 kts |
Possibilities are endless!
The full page is here.
Wednesday, April 11, 2018
Docker on the Raspberry PI
Docker can work around the "But it works on my machine!.." syndrome.
Let's say you have a
nodejs project you want to share with others.
The application reads GPS data through a Serial port, and feeds a
WebSocket server.
The data can then be visualized through a Web interface.
To enable everything, you need to:
- Have a Raspberry PI
- Flash its SD card and connect it to a network
- Install build tools
- Install
git - Install
NodeJSandnpm - Clone the right
gitrepository - Install all the required
nodemodules - Drill down into the right directory
- Start the
nodeserver with the right script - Access the Raspberry PI from another machine on the same network, and reach the right HTML page.
This is certainly not difficult, but there are many ways to do several mistakes at each step of the process!
Docker can take care of the steps 3 to 9.
It will build the image, and then run it.
The image can also be pushed to a repository, so users would not have to build it.
Just to run it after downloading it.
The only pre-requisite would be to have installed
Docker on the machine (the Raspberry PI here),
as explained here.
Create a
Dockerfile like this (available here):
FROM resin/raspberrypi3-debian:latest LABEL maintainer="Olivier LeDiouris <olivier@lediouris.net>" RUN echo "alias ll='ls -lisah'" >> $HOME/.bashrc RUN apt-get update RUN apt-get install sysvbanner RUN apt-get install -y curl git build-essential RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - RUN apt-get install -y nodejs RUN echo "banner Node-PI" >> $HOME/.bashrc RUN echo "git --version" >> $HOME/.bashrc RUN echo "echo -n 'node:' && node -v" >> $HOME/.bashrc RUN echo "echo -n 'npm:' && npm -v" >> $HOME/.bashrc RUN mkdir /workdir WORKDIR /workdir RUN git clone https://github.com/OlivierLD/node.pi.git WORKDIR /workdir/node.pi RUN npm install EXPOSE 9876 CMD ["npm", "start"]
In this case, the full
Docker image creation (named oliv-nodepi below) comes down to 1 line (the one in bold red):
$ docker build -t oliv-nodepi . Sending build context to Docker daemon 752.6kB Step 1/20 : FROM resin/raspberrypi3-debian:latest ---> c542b8f7a388 Step 2/20 : MAINTAINER Olivier LeDiouris---> Using cache ---> b2ff0d7c489f Step 3/20 : ADD nodepi.banner.sh / ---> 535733298dd1 Step 4/20 : RUN echo "alias ll='ls -lisah'" >> $HOME/.bashrc ---> Running in 09baf7261a55 Removing intermediate container 09baf7261a55 ---> 71e1e4c95663 Step 5/20 : RUN apt-get update ---> Running in 5d817a941a14 Get:1 http://security.debian.org jessie/updates InRelease [94.4 kB] Get:2 http://archive.raspbian.org jessie InRelease [14.9 kB] Get:3 http://archive.raspberrypi.org jessie InRelease [22.9 kB] ... npm notice created a lockfile as package-lock.json. You should commit this file. added 166 packages in 81.166s Removing intermediate container 13986530db28 ---> 051eb94b8a3c Step 19/20 : EXPOSE 9876 ---> Running in 67b587845fe0 Removing intermediate container 67b587845fe0 ---> 46973b7ba9ac Step 20/20 : CMD ["npm", "start"] ---> Running in 153bf2ea02ad Removing intermediate container 153bf2ea02ad ---> 6bf3d76d38ae Successfully built 6bf3d76d38ae Successfully tagged oliv-nodepi:latest ed9a7d9042dddd3939b1788cf0e89d16f5273192a6456266507f072f90ce91bc $
Once the step above is completed, plug in your GPS, and run
$ docker run -p 9876:9876 -t -i --privileged -v /dev/ttyUSB0:/dev/ttyUSB0 -d oliv-nodepi:latestThen from a machine seeing the Raspberry PI on its network (it can be the Raspberry PI itself), reach http://raspi:9876/data/demos/gps.demo.wc.html in a browser.
This shows you the position the GPS has computed, and the satellites in sight.
You can also login to the image:
$ docker run -it oliv-nodepi:latest /bin/bash # # ###### ### ## # #### ##### ###### # # # # # # # # # # # # # # # # # # # # # ##### ##### ###### # # # # # # # # # # # # ## # # # # # # # # # #### ##### ###### # ### git version 2.1.4 node:v9.11.1 npm:5.6.0 root@b9679d0d65a7:/workdir/node.pi#... and do whatever you like.
The build operation needs to be done once.
There is no need to do it again as long as no change in the image is required.
- Quick comment
-
So, with
Docker, you do not deliver a software, you actually deliver an image (a virtual machine), on which a software is running.
This is indeed redefining the concept of portability that made Java and other JVM-aware languages so successful.
This may very well explain the rise of languages like Golang (aka Go).
It runs on my machine? Well, here is my machine! You can download and run it. Enjoy!
Saturday, March 17, 2018
Java Weather Station
This is a SwitchDocLabs SDLWeather80422 Weather Station, installed on the roof.
It is connected to a Raspberry PI A+, all the software is written in Java, no Python, no Arduino-like code, no C++.
There is an optionalnodeJS server that runs on the Raspberry PI too, to enable WebSockets.
Find the core code here, and the example implementation here.
MySQL, PHP, Web Interface Web-Components interface, pings the server every second. WebSocket Web Interface, updated in real-time.See it live here.
|
It even comes with a pebble application. |
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.
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.
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
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)
Sunday, March 13, 2016
IoT for dummies
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
- 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
. . .
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
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
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())
}
}
}
}
#!/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
Hello,Scala world! CPU Temperature :40.6°C Temp:22.5°C, Press:1010.73 hPa
Thursday, May 07, 2015
Web Console improvements
That's why we now have some improvements in the Web Console:
The HTML5 console is accessed from
http://machine:port/html5/console.html, default port being 9999.
If you have installed node.js and the WebSocket user-exit, then you access the WebSocket console from
http://machine:9876/data/console.ws.html
It is still self-contained, no external framework is used (like JQuery et al). Those are great - for sure - but this is to be run on a boat at sea, with Internet out of reach.
Notice on the snapshots that several data come from some sensors hooked-up on the Raspberry PI. They can be shown or hidden from the preferences or from the Console Admin page.
Notice that the Console Admin page has been removed from the Console, it can now be accessed from a separate URL, on the admin port (8080 by default) at
http://machine:port/html5/admin.html, started when the console is in headless mode:
The default values on the pages above come from the Desktop Preferences.
And there is now a CLI (Command Line Interface) for to access those preferences from a non-graphical environment (like on the Raspberry PI).
The class to launch is
olivsoftdesktop.PreferencesCLI. An entry will added soon in the User Interfaces.
All this runs fine on the Raspberry PI, all the snapshots above have been taken with the Raspberry PI run node.js as server.
An idea...
Anyone with a smartphone or a tablet can access those live data. The problem is to type in the right URL...Once you have chosen your configuration (IP address and ports), you can generate QR Code (https://www.the-qrcode-generator.com/ worked for me), print them, and post them somewhere in the boat. Whoever wants to reach the data just uses his QR Scanner - all smart stuffs have at least one - and boom! You're in!
HTML5 console |
HTML5 WebSocket console |
HTML5 Admin console |
theme and border. theme can be 'white' or 'black', border can be 'Y' or 'N'.
Like in
http://machine:9999/html5/console.html?theme=white&border=N
There are several QR Code generators, including some you can run off-line. This one works just fine, and can be installed on the computer on the boat, so you can generate your codes from anywhere. As you can see here.
Thursday, March 05, 2015
OpenCPN on the Raspberry PI model 2
And it seems that OpenCPN runs just fine on it!
I started from the last NOOBS available from the Raspberry PI website.
Here are the steps I had to go through to build it:
Prompt> sudo apt-get update Prompt> sudo apt-get install -y libgtk2.0-dev gettext git-core cmake gpsd gpsd-clients \ libgps-dev build-essential wx-common libwxgtk2.8-dev \ libglu1-mesa-dev libgtk2.0-dev wx2.8-headers \ libbz2-dev libtinyxml-dev libsdl1.2debian xcalib Prompt> git clone https://github.com/seandepagnier/OpenCPN.git Prompt> cd OpenCPN/ Prompt> mkdir build Prompt> cd build Prompt> cmake ../ Prompt> make Prompt> sudo make installAfter that, at the prompt you enter:
Prompt> opencpn &And that's it!
And by the way, it works the same on all the Ubuntu-like distributions I tested.
Thursday, January 08, 2015
Version 3.0.1.5 available
Few new features, minor UI improvements, and big uptake for the Raspberry PI.
A new feature for the Weather Wizard in headless mode, you can download several composites at the same time (one after the other actually). Use the
-composite: and -pattern: parameters, separate each value with a comma.
For example, on Windows:
set PRMS=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn set PRMS=%PRMS%,./patterns/01.Favorites/06.01.AllPac.Faxes.Satellite.ptrn set PRMS=%PRMS% -interval:360 set PRMS=%PRMS% "-pattern:/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific | waz,/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific.SatPic | waz" :: set command=java %JAVA_OPTIONS% -client -classpath "%CP%" -Dheadless=true main.splash.Splasher %PRMS%On Linux and Mac:
PRMS=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn PRMS=$PRMS,./patterns/01.Favorites/06.01.AllPac.Faxes.Satellite.ptrn PRMS=$PRMS -interval:360 PRMS=$PRMS "-pattern:/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific | waz,/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific.SatPic | waz" # command=java $JAVA_OPTIONS -client -classpath "$CP" -Dheadless=true main.splash.Splasher $PRMS





































