Friday, May 15, 2015

Johnny-five and node-red in a Docker container

Picking up where I've left off in my previous post, I tried to get the simple Blink 2 flow (bottom of the page) working inside a Docker container. And in the end I did, but I had to get over a couple issues first.

My first tries, nothing happened: every time when node-red would start, I see in the console "looking for connected device..." and that was it. Seeing that johnny-five would not connect and getting errors running the flow (cannot read property 'type' of null), I exited the container without stopping it as described in my previous post (Ctrl+PQ followed by Ctrl+C and docker exec -it mynodered /bin/bash), and tried to run the johnny-five board.js example app in node_modules/node-red/eg with:

node board.js

Again, "looking for connected device..." was displayed and nothing else happened no matter how long I waited. Wondering what could be wrong, I checked /sys/class/tty and indeed there was no ttyUSB0 there; I remembered then the --privileged docker run option mentioned in my previous post and in the Docker docs so I restarted the container using this command:

docker run -it -p 1880:1880 --privileged -v ~/my-node-red:/root/.node-red --name mynodered --rm claudiuo/node-red

Unfortunately this didn't change anything, same message showed up both when node-red and board.js started. ttyUSB0 was now present so I knew I was on the right track but still had no idea how to make things work. In a last attempt, I decided to modify board.js and specify the port explicitly as var board = new five.Board({ port: "/dev/ttyUSB0" }); as mentioned somewhere in the johnny-five docs and this time board.js connected to my Arduino and the LED on pin 13 started blinking. This was an awesome moment!

Next step was to modify settings.js and do the same thing, changing the default global context entry:

j5board:require("johnny-five").Board({repl:false})
to:
j5board:require("johnny-five").Board({port: "/dev/ttyUSB0", repl:false})

and restarting the Docker container this time I saw johnny-five connecting and the blink flow worked right away. I can't say I like this solution very much because ttyUSB0 may change on a different machine (or maybe even if I plug in my Arduino in a different USB port) but the fact that it works is awesome. (As a side note, not setting the port explicitly in settings.js works great with node-red outside Docker; not sure why this is the case). Now I need to take the next step and figure out how to use callbacks in a flow (callbacks are key to some of johnny-five functionality but luckily the awesome node-red team added them in node-red 0.10.6 as described here).

One cool thing that needs mentioned is that while I was searching the web for solutions to my issues, I found out a book about johnny-five was just published a few days ago on May 8: Make: JavaScript Robotics: Building NodeBots with Johnny-Five, Raspberry Pi, Arduino, and BeagleBone - I'm sure it is great and I will be getting it very soon.

Wednesday, May 13, 2015

Node-red and Docker update

This is sort of a follow up to my earlier post related to running node-red inside a Docker container. I said "sort of" a follow up because that post was about a Docker container for Raspberry Pi; this one will talk about a container to run on my laptop. A lot of the stuff here applies to Raspberry Pi directly, some needs changes (like the base image, for example). Since that post I learned some things that make building and customizing a Docker container for node-red a lot easier, all thanks to one of the main contributors to node-red, Dave C-J.

All this started because I wanted to build a Docker container with custom packages installed (case in point, I am talking about johnny-five) and I wanted to start with theceejay's master node-red image thinking I will create my own Dockerfile to add the new packages and build a custom image. While looking on Docker hub I noticed theceejay's write up to his other node-red image which is really awesome: it explains things I didn't know about (like using package.json along with Dockerfile) which makes installing new npm packages very easy; also, it talks about overriding the settings.js file when building the custom image and not at runtime as I was doing it previously. This write up is linked to a github repo which I forked and cloned on my local machine, then I modified a little bit by adding johnny-five to package.json. I then built my own custom node-red Docker image (which is basically identical with theceejay's one with the addition of johnny-five package) and started the container mapping a local directory to /root/.node-red so I get a copy of the flow.json and all flows saved in the library:

docker build -t claudiuo/node-red .
docker run -it -p 1880:1880 -v ~/my-node-red:/root/.node-red --name mynodered --rm claudiuo/node-red

Once the container started, Ctrl+PQ followed by Ctrl+C exists the container without shutting it down after which I was able to connect to it using:

docker exec -it mynodered /bin/bash

and confirmed johnny-five was installed. More, looking at the node_modules/node-red/settings.js file, I noticed that jfive and j5Board were already added to the global context, commented out. This was a surprise to me, I had no idea the latest version of node-red comes with these modules already added; this is really cool.

In my previous post, I mentioned that I was also placing a settings.js in my local dir to change the name of the flow file: this is not needed because package.json specifies flow.json as the filename. However, the write up also mentions: "This also copies any files in the same directory as the Dockerfile to the /usr/src/app directory in the container… this means you can also add other node_modules or pre-configured libraries - or indeed overwrite the node_modules/node-red/settings.js file if you wish." So I made a copy of the settings.js in the dir mentioned above, uncommented the 2 johnny-five entries in the global context, placed the file alongside Dockerfile as seen in my repo clone and rebuilt the image. Started the container again and checked it and indeed, the new settings.js is in place.

I was thinking at some point to publish my new custom node-red image to Docker hub but since building it from scratch is as easy as cloning the repo and running docker build, I won't do it. In fact, rebuilding the image will take care of upgrading node-red as well so I rather not publish an image which will be out of date when next release comes out.

Now I need to figure out how to use johnny-five with node-red and build some cool little robot; at this point I have no idea how but I will start with the notes in the second half of this page and go from there. Until then, again, big thanks to Dave C-J for all his awesome work and help.

Friday, May 01, 2015

HC Bluetooth module - quick notes

A while ago I bought a cheap Bluetooth module off ebay and for some reason, I always thought it is a HC-05 module: not only that this is what the ebay page said but also because a long time ago when I tried Amarino on my phone, it connected to the Bluetooth module and its name was HC-05. It works great with Amarino and my custom sketches but only at 9600 which seems to be the default (most people on the web say the default is a higher baud rate but I discovered this being my case by trying different settings in a test sketch) but Firmata needs 57600 (in my opinion, both BT module and Firmata sketch set at 9600 should work fine but I tried and for some reason it doesn't).

Thinking I have a HC-05 I tried to change its default speed to 57600 by following this instructables - my module didn't have a wire on the KEY pin so I soldered one. However, after all connection were done and I ran the sketch, I noticed that no commands worked with one exception "AT+NAME=MYBLUE" - it was the only command that received a response from the module, "OKsetname". To check if something changed, I paired the module with my phone and to my surprise the name was "=MYBLUE" not just MYBLUE so something was not quite right.

Digging more on the web, found another instructables. The module I have doesn't have the same markings on the back (mine says V1.04) and it has 6 pins (only 4 with a connector soldered) so it's not really the same thing, however the name AT command is "AT+NAMExxxx" which is exactly what happens in my case (where = becomes part of the name). Unfortunately, again the only command that works is ATNAME, none of the other get an answer so I am really at a loss of what to do to change the baud rate of my module.

I think for now I will leave it at 9600 - it works with Amarino and it works with my custom sketches so at least is not totally unusable. I would like to use it with Firmata so I can do some Scratch for Arduino or Snap4Arduino or Johhny-Five without having the Arduino connected to the laptop but maybe I'll just try to buy another BT module one that I may be luckier with and be able to change its speed.

[Update] I tried again: changed the StandardFirmata sketch to 9600, uploaded it to my SparkFun RedBoard (UNO compatible), installed my custom Bluetooth and RGB LED shield, and tried again Arduino Commander and this time it connected and the RGB LED works great, both as digital and analog (PWM) output! I don't know what is different than last time, I am puzzled but happy. My Windows machine was able to connect to the module, hopefully my Linux Mint box and Raspberry Pi will work as well so I can be on to the next step, probably a Johhny-Five little robot.