Much as I know the technology is simple, I still think there is something compelling and slightly magical about bridging the digital and physical worlds.

hello world

So on saturday I joined a crew of slightly bleary-eyed nodejs and hardware enthusiasts at Web Directions HQ for Nodebots Sydney 2013.

Armed with a laptop and an Arduino my goals were pretty simple - I wanted to hang out with some like-minded people; learn a bit about hardware and nodejs; and have node controlling some hardware by the end of the day.

Enter the ED1

As it happens I was lucky enough to have access to a NICTA ED1 for the day, so the Arduino stayed tucked in my bag for another time. The ED1 is much like an Arduino with a number of shields, sensors and inputs pre-attached.

As the ED1 is designed for education, they're mostly used in schools - so it was cool to be able to play with one. While Arduinos are also excellent, the ED1 has several benefits for hardware newbies like me:

  • The one-piece board eliminates lots of hardware variables so you can focus on writing code and exploring the components' capabilities.
  • No teensy pieces of hardware to break, drop or lose.
  • It's USB-powered so it's safe and it would be incredibly hard to fry anything.

Basically it's fun to muck around with and quick to get results, which is great for a hack day (and presumably good for classrooms too). If you're an Australian teacher and you think your students might be interested, you can get in touch with NICTA about the ED1.

Steps to hello world

Some knowledge of node and npm is assumed. Realistically if you are using an ED1 you probably have people to help you, so I won't go into massive detail...

  • Install nodejs
  • Clone or npm install johnny five
  • Install VCP drivers
    • without this, you'll probably just get an error like "No USB devices detected"
  • Create, say, helloworld.js
  • Plunder the demos in /johnn-five/eg/
    • for my demo I pulled some code from lcd.js and shiftregister.js
    • remember to copy the the require and board setup/ready code
    • if you want to try things in the repl, grab an inject example
  • Since johnny five is made for Arduino, you'll need to convert Arduino pin references to ED1 pin references, eg:
    • for the shift register, update data, clock and latch to the values printed on the board
    • for the LCD, update pins to [6, 8, 2, 3, 4, 5]
  • Plug in the ED1 and check things light up ready for action
  • Run the script: node helloworld.js

The main thing to remember is that you need to convert many of the pins from Arduino references to ED1 equivalents. If nothing's happening or the data doesn't look right, check your pins are set correctly.

LCD helloworld.js

var five = require("path/to/johnny-five"),
    board, lcd;

board = new five.Board();

board.on("ready", function() {

  lcd = new five.LCD({
    // Arduino would be:
    // pins: [ 7, 8, 9, 10, 11, 12 ],
    pins: [ 6, 8, 2, 3, 4, 5 ],
    rows: 2,
    cols: 16
  });

  lcd.on("ready", function() {
    lcd.clear();
    // LCD has two rows: setCursor(column,row)
    lcd.setCursor(0,0).print("hello world");
    lcd.setCursor(0,1).print("go team random");
  });

});
  

LEDs, catnip for geeks

The ED1 has a few single LEDs on the board, but since every geek I know is fascinated with LEDs you'll no doubt be drawn to the row of 8 red LEDs.

nodebot demo 1: ready

They form the LED Shift Register. I expected to use binary strings to turn them on and off, eg. 00000000, 11111111, 01010101, 10101010 etc. But actually it works with hex values:

  • 11111111 = 0xFF
  • 10101010 = 0xAA
  • 01010101 = 0x55
  • 00000000 = 0x0

There are a couple of pages out there with converters and more details on the process:

Yikes, maths

I ended up going on some tangents around this... but thanks to some help from people who actually understand maths, I now have this verbose and very-slightly-tested function to convert a binary string to a hex code (ugliness and any errors are mine and not theirs):

function binString2hexString(binaryString) {
    var num1 = binaryString + '';
    var num2 = parseInt(num1, 2);
    var num3 = num2.toString(16).toUpperCase();
    var hex  = "0x" + num3;
    return hex;
}

...that should let you work with something readable, while still sending hex to the board. Alternatively it might actually explode. I don't have an ED1 handy to test it; and on the day I just entered hex values to get the demo finished. We did theJS in the console while we were packing up.

Wait, what about node?

Having got some basic hardware working I made a simple web interface to control it. Unsurprisingly I used Express with socket.io and Jade templates - overkill, but fast to build with Express.

I did have some niggles getting Express and socket.io to talk to each other; the tip there is to double check socket.io is listening to the actual app and not the Express instance named app:

var server = http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

var io = require('socket.io').listen(server);  

Final results

The code's no masterpiece but you're welcome to have a look; and thanks to Damon Oehlman I have a quick demo video just to show it did come together.

If there's a last thought it's simply that hacking with hardware is heaps of fun; if you get a chance to go to a nodebots day I heartily recommend it.