BeagleBone Black Rube Goldberg Internet Thing

03Dec13

I spent yesterday at the excellent ThingMonk hack day. Whilst everybody else was playing with Arduinos, Node and Johnny5 I decided to have a play with Node-RED on the BeagleBone Black I’d brought along. The eventual outcome was something that turned an LED on or off every time somebody tweeted ‘Thingmonk’. Our host James Governor tried to tweet a picture of it (which got stuck on his phone).

The flow started with a Twitter parser connected to a MQQT topic running on RabbitMQ running on my next door neighbour’s laptop (thanks Mark). I then had Node-RED subscribed to the topic on Mark’s broker feeding into a function to toggle an LED attached to the P8_13 GPIO pin on the board.

ThingMonk Node-RED TwitterLEDIt all looks pretty simple now, but I had some fun getting going.

Getting online

I’d brought the BeagleBone with me because I could get it up and running with a single USB cable attached to my laptop. In order to get stuff installed on it I had to share my laptop WiFi with the BeagleBone network connection, turn off my firewalls, and make a few incantations on the BeagleBone:

route add default gw 192.168.7.1
echo 'nameserver 8.8.8.8' >> /etc/resolv.conf

It’s also a good idea to make sure that the date and time are correct:

ntpdate pool.ntp.org

Node-RED

The project has specific instructions for the BeagleBone Black, but that’s not the complete story. I had to refer back to the installation guide, because I’d missed the crucial step of:

cd node-red
npm install --production

I also edited settings.js to enable bonescript by commenting out one line and uncommenting another:

    //functionGlobalContext: { }
    functionGlobalContext: { bonescript:require('bonescript') }
     //functionGlobalContext: { arduino:require('duino') }
}

I could then start it up with:

node red.js

Here’s the code that flips the LED when a tweet is received[1]:

var pin = "P8_13"
var b = context.global.bonescript;
context.state = context.state || b.LOW;
b.pinMode(pin, b.OUTPUT);
(context.state == b.LOW) ? context.state = b.HIGH : context.state = b.LOW;
b.digitalWrite(pin, context.state);
return msg;

Mosquitto

Everything was fine with Mark’s MQTT until the power cut. No WiFi meant no connectivity to his laptop. I decided to install my own MQTT broker… Mosquitto is packaged for Debian (and Ubuntu), so if I was running that it would be simple to install, but I was running Angstrom to get bonescript etc. to go with Node-RED. So I had to install Mosquitto from source[2]:

opkg install python-pip tcp-wrappers \
 python-dev python-setuptools coreutils \
 libxslt libxslt-dev packagegroup-core-buildessential
wget http://mosquitto.org/files/source/mosquitto-1.2.3.tar.gz
tar -xvf mosquitto-1.2.3.tar.gz
cd mosquitto-1.2.3
make
make install
cp /etc/mosquitto/mosquitto.conf.example /etc/mosquitto/mosquitto.conf
adduser mosquitto

You’ll probably want to visit the Mosquitto downloads page to make sure you’re getting the latest version (it was 1.2.2 when I did this yesterday).

Notes

[1] Node-RED has a Twitter input element that I could have used, but I couldn’t get authentication to work (and spent no time trying to fix it), and part of the fun of a hack day is joining projects together.
[2] Thanks to Bruce Holmes for pointing me in the right direction here. It looks like pkggroup-core-buildessential became packagegroup-core-buildessential at some stage.



9 Responses to “BeagleBone Black Rube Goldberg Internet Thing”

  1. Nicely done Chris.
    I have updated the instructions to remind folk to read the install instructions at the appropriate point. Thanks

    • 2 Max Hadley

      I’ve tried out the new 1.3 release of mosquito on the BBB, but unfortunately the make fails:

      root@beaglebone:~/mosquitto-1.3# make
      set -e; for d in lib client src; do make -C ${d}; done
      make[1]: Entering directory `/home/root/mosquitto-1.3/lib’
      cc -Wall -ggdb -O2 -I. -I.. -I../lib -fPIC -DWITH_TLS -DWITH_TLS_PSK -DWITH_THREADING -DWITH_SRV -c mosquitto.c -o mosquitto.o
      In file included from mosquitto.c:46:0:
      mosquitto_internal.h:51:20: fatal error: ares.h: No such file or directory
      compilation terminated.
      make[1]: *** [mosquitto.o] Error 1
      make[1]: Leaving directory `/home/root/mosquitto-1.3/lib’
      make: *** [mosquitto] Error 2

      The offending header is included by a WITH_SRV define, and appears to be something to do with DNS service discovery. Any ideas how to get round this?
      Thanks!

  2. 4 Max Hadley

    I tried this out, with success, but while the broker seems to be working, the publish & subscribe command-line tools are giving me an error:

    root@beaglebone:~# mosquitto -d
    root@beaglebone:~# 946684913: mosquitto version 1.2.3 (build date 2014-01-16 21:03:09+0000) starting
    946684913: Using default config.
    946684913: Opening ipv4 listen socket on port 1883.
    946684913: Opening ipv6 listen socket on port 1883.

    root@beaglebone:~# mosquitto_sub -d -t hello/world
    mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory

    It looks like the library has not been installed properly – it is there in ~/mosquitto-1.2.3/lib/

    Where should it be installed to?

    Cheers,

    Max

    • I didn’t run across this myself as I didn’t even try to use the mosquitto command line tools, but I had a dig around anyway…

      The library there in ~/mosquitto-ver/lib/ is the one that you’ve built, but I wouldn’t expect it to be found. To put a copy where it should be found ‘make install’ copies it to /usr/local/lib, which could reasonably be expected to be on LD_LIBRARY_PATH. It’s not found though because out of the box Angstrom doesn’t have any LD_LIBRARY_PATH set. This can be fixed thus:

      root@beaglebone:~# export LD_LIBRARY_PATH=/usr/local/lib
      root@beaglebone:~# mosquitto_sub -d -t hello/world
      Client mosqsub/627-beaglebone sending CONNECT
      Client mosqsub/627-beaglebone received CONNACK
      Client mosqsub/627-beaglebone sending SUBSCRIBE (Mid: 1, Topic: hello/world, QoS: 0)
      Client mosqsub/627-beaglebone received SUBACK
      Subscribed (mid: 1): 0
      Client mosqsub/627-beaglebone sending PINGREQ
      Client mosqsub/627-beaglebone received PINGRESP

      You might want to create a .bashrc containing the export to make things more permanent.

      • 6 Max Hadley

        Thanks! It’s amazing how you can miss the obvious while looking for a more complicated solution. Working nicely now.
        Another question: how do I go about automatically starting mosquito as a daemon? Presumably I have to create a /lib/systemd/system/mosquitto.service file, and use systemctl to enable it, but I’m very uncertain about the contents of such files (my Linux experience predates this sort of thing)

      • Again… not something I’ve tried myself. But I’d start out by just adding a line at the end of rc.local

        Supervisord might also give you an easy way to daemonise it. I’ve been using that recently to get multiple processes running in Docker.

  3. Do you think it’s possible to run an MQTT broker server and a Node.js server (for the purpose of running Node-Red) — at the same time?

    I’m interested in using an arduino to publish to an mqtt broker (local on a bbb) and have a node-red application (also running on the bbb) subscribe to the topic and conditionally send an sms. Is that do-able?

    • That should work just fine. Mosquito isn’t very resource hungry, so there should be plenty of horsepower for both.


Leave a reply to Max Hadley Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.