Mobilizing the Internet of Things (IoT) Part 1 -- BeagleBone Black

We’ve done some recent posts showing how to deploy Synchro Server in various ways (Docker containers) and to various cloud environments (IBM BlueMix). In the spirit of "Synchro can run anywhere Node.js can run", and in honor of March is for Makers, we’re going to do a series of blog entries that go in entirely the opposite direction. We’re going to show you how you can run Synchro Server on the current generation of low-cost, single board computers, allowing you to quickly build and deploy native mobile apps that control those devices. What's more, you will actually be serving those apps directly from the device.

With a simple install and a few lines of JavaScript, you can be controlling the “things” in your "Internet of Things" right from your phone. The example below uses the BeagleBone Black as the host and culminates in a simple Synchro app, running on your mobile device, that lets you turn an LED on and off (in about a dozen lines of JavaScript code).

Future blog entries will cover using Arduino and Raspberry Pi boards to do increasingly cool stuff (all from your phone).

BeagleBone Black

The BeagleBone Black is a small, inexpensive, single board computer often used by hobbyists and developers. You can pick one of these up for around $55.

The BeagleBone Black gets even more interesting when you start hooking it up to things - sensors, motors, switches, etc. It can drive anything from an automatic chicken coop door to a CNC machine.

Getting up and running on the BeagleBone Black

One mode of interacting with the BeagleBone Black is to use Node.js combined with the BoneScript library. Because the BeagleBone Black supports Node.js, it is capable of hosting a Synchro environment.

With this combination of Synchro and BoneScript, you can easily mobile-enable the BeagleBone Black and create interactive mobile interfaces for any existing BoneScript application, or create your own mobile-centric applications.

Install an OS that supports Node 0.12 or later

In my case, I built an SD card with the 8.3 Debian image and flashed that to eMMC. Earlier versions of Debian do not support Node 0.12 or later.

Hook up to the network

I plugged in the Ethernet cable. I have DHCP, so the network "just worked."

Connect to your BeagleBone Black

On my network, I was able to find my BeagleBone Black using the name "beaglebone.local".

If you need to find it, you can use nmap to find any machine that has port 22 (SSH) open:

$ nmap -p 22 --open -sV 192.168.0.* -Pn

Starting Nmap 7.01 ( https://nmap.org ) at 2016-03-06 16:22 PST  
...
Nmap scan report for beaglebone (192.168.0.22)  
Host is up (0.00083s latency).  
PORT   STATE SERVICE VERSION  
22/tcp open  ssh     OpenSSH 6.7p1 Debian 5+deb8u1 (protocol 2.0)  
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel  

Then I logged in using ssh to the default "debian" user account (you may get an SSH warning about the keypair, feel free to validate the fingerprint.)

$ ssh debian@192.168.0.22
Debian GNU/Linux 8

BeagleBoard.org Debian Image 2016-01-24

Support/FAQ: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian

default username:password is [debian:temppwd]

debian@192.168.0.22's password:  

Install Node 0.12 or later

First I updated all of my packages on the system and rebooted (you know, just in case.)

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo shutdown -r now

Now, the version of Node that comes with the current Debian (Wheezy or Jessie) distributions isn't... contemporary:

$ node --version
v0.10.42  

The "co" library used in Synchro requires Node 0.12 or later, so Node will need to be updated. I followed the instructions from https://nodejs.org/en/download/package-manager/ to install a more recent version of Node on a Debian installation:

$ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
$ sudo apt-get install nodejs
$ node --version
v4.3.2  

I used the 4.X branch -- it's possible 5.X will work fine on this platform.

And updated npm while I was at it.

$ sudo npm install -g npm
$ npm --version
3.8.0  

Install Synchro

The instructions for installing Synchro, creating a project and creating an app are just the steps from https://synchro.io/getstarted

$ sudo npm install -g synchro
$ synchro --version
2.2.5  

Create a new Synchro project

$ mkdir SynchroBeagleboneBlack
$ cd SynchroBeagleboneBlack/
$ synchro init

Create a new Synchro app

$ synchro new bb-demo
Got config from synchro-api - Using default configuration file: config.json  
App description: Synchro BeagleBone Demo  
Processing file: main.js  
Processing file: package.json  
Synchro application 'bb-demo' created  

Install the latest BoneScript

Currently the current BoneScript release is not compatible with Node 4.X, so you need to install a special version.

$ npm install bonescript@0.5.0-beta3

Run your Node instance

$ sudo node app.js
[2016-03-10 05:34:46.901] [INFO] app - Synchro server loading - Using default configuration file: config.json
[2016-03-10 05:34:50.320] [INFO] synchro-api - Creating API processor for app at path: bb-demo, debug port is: 6868
[2016-03-10 05:34:54.551] [INFO] api-request-processor - API request processor for app container: bb-demo at path: bb-demo - ready
[2016-03-10 05:34:54.697] [INFO] app - Synchro server listening on port 1337, node version: v4.3.2

Fire up Synchro Studio

Connect to your server IP from your web browser, port 1337, you should see Synchro Studio running on your BeagleBone Black:

An LED example

Based on the BoneScript example for blinking an LED, replace your main.js with the following:

var b = require("bonescript");

// Main page
//
exports.View =  
{
    title: "bb-demo",
    elements:
    [
        { control: "toggle", caption: "Toggle LED {led}", fontsize: 12, binding: { value: "ledState", onToggle: "toggleLed" } },
    ]
}

exports.InitializeViewModel = function(context, session)  
{
    var viewModel =
    {
        ledState: false,
        led: "USR3"
    }
    b.pinMode(viewModel.led, 'out');
    return viewModel;
}

exports.Commands =  
{
    toggleLed: function(context, session, viewModel, params)
    {
        b.digitalWrite(viewModel.led, viewModel.ledState);
    }
}

Let's walk through the interesting parts of this.

var b = require("bonescript");  

Top-level require for BoneScript to use later.

{ control: "toggle", caption: "Toggle LED {led}", fontsize: 12, binding: { value: "ledState", onToggle: "toggleLed" } },

This sets up the toggle control with a caption containing "Toggle LED" followed by the BoneScript identifier for the LED. This is in the viewModel which we will discuss in a minute. It also sets up a binding for the current state of the toggle (off or on) with the "ledState" member of the viewModel. Finally, it sets up a Javascript function that will be called when the state is changed (toggleLed).

var viewModel =  
{
    ledState: false,
    led: "USR3"
}

These are the current toggle state and the BoneScript identifier for the LED we will be using, stored in our viewModel.

b.pinMode(viewModel.led, 'out');  

Set the pin mode of the LED to output, called once when initializing the viewModel.

toggleLed: function(context, session, viewModel, params)  
{
    b.digitalWrite(viewModel.led, viewModel.ledState);
}

Change the state of the LED based on the current state from the viewModel. Called when the control is toggled via the onToggle binding in the view definition.

View your new UI with Synchro Explorer

Point to your new app in Synchro Explorer by adding an endpoint for http://hostip:1337/api/bb-demo (substitute the local host IP address for 'hostip'). When you navigate to the app, you should see your new UI:

When you tap on the toggle control, the LED USR3 (right next to the Ethernet jack on the BeagleBone Black) should turn on or off depending on the toggle control state.

Congratulations! You now have BoneScript functionality in your Synchro environment. You can now access GPIOs, UARTs, I2C, SPI, everything you can do on a BeagleBone Black with JavaScript.