Thursday, October 04, 2012

Web-scale Arduino

There are a number of projects that allow one to control an Arduino using node.js.  For example, there's Noduino and Johnny-Five. To my mind these things are an abomination(*) because they are teaching people to use Arduino at the wrong level of abstraction. If you are going to learn Arduino, learn some C.

One can always argue that they get more people using Arduino, but all these people would be better off learning some C for the joy of Arduino is not (to my mind) controlling it using a massive desktop or laptop machine. The joy of Arduino is small, embedded projects that do stuff. Such as Simonoids:
And if they learn some C they'll get more out of Arduino because they'll be able to do things that the node.js layers don't allow: cool stuff. And once they've learnt some C and need to control the Arduino from the host they'll be able to do even more cool stuff. If you are going to learn Arduino, learn some C.

To get an idea of what's problematic about 'web-scale Arduino' take a look at the canonical Hello, World! of Arduinoland: flashing the LED attached to pin 13.  Here's the code to do that in Noduino:

And here's the code to do that in C on the Arduino:
The first problem is that the Noduino code is nothing like the code on the Arduino. So, anyone learning to use Noduino is learning almost nothing about programming Arduino. The skill of using the duino library is not transferrable to writing code on the device itself. That's a problem because these node.js Arduino wrappers have limitations that can only be overcome by using C.

For example, LED.blink() takes care of all the flipping on and off of the LED and it performs the timing. And it's not just that it's doing the work, all the concepts in node.js (particularly of events) just don't exist on the Arduino. What you learn with Noduino is how to use Noduino; similarly for Johnny-Five.

(Aside: for a fun puzzle work out how to stop the LED from blinking in the node.js example.)

The other issue is that the really cool thing in node.js (the same code on the server and browser) just isn't true here. None of that JavaScript is running on the Arduino. You can't take your JavaScript and run it on the Arduino and so you can't, for example, take your LED-flashing Arduino, attach a battery to it and see it run.

Now, that might seem like a minor issue but doing things that are time sensitive (such as bit banging) means your code needs to be on the Arduino. Projects like the Cansole need to have very precise timing to generate the TV signal in software. That needs doing in C.
The way these systems work is by having a serial protocol defined between the Arduino and the host. Noduino uses duino and Johnny-Five uses Firmata. Projects that can live within the restrictions of those protocols will get along fine, but it means giving up access to the vast world of Arduino libraries.

(Aside: if you know C then you can use Firmata as a communication mechanism between your host program and Arduino and get the benefits of both worlds.)

As an example, if you wanted to connect a serial device (say a GPS) to some of the Arduino digital pins using SoftwareSerial you'd be in trouble. Or suppose you want to use TVout to generate a PAL or NTSC signal, you can't. If you know C you can hack that stuff into your project even if you use node.js to control the Arduino. C is the core language used by Arduino and it's worth learning.

Of course, having gone on about this there is a good reason to control an Arduino from a node.js program: if you are writing a web app that needs to control some external device then Arduino is a handy interface box.

And I'm not against doing that. In fact, the standard Arduino examples include many ways of combining a Processing program with an Arduino program. One example allows the user to move the mouse on their computer to control the brightness of an LED. All of these involve communicating using the serial connection (which is what Firmata and duino do under the hood) and require writing a simple Arduino program in C.  Another example uses the Arduino to read analog data and Processing to graph it.  In both case the programs used are small, simple and native and can take full advantage of the Arduino and the host.

In summary, I think you're missing a lot if you start with node.js as your way of learning Arduino. Flash an LED in C: it's easy.

(*) I am exaggerating for effect.

No comments: