Skip to main content

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.

Comments

Popular posts from this blog

Your last name contains invalid characters

My last name is "Graham-Cumming". But here's a typical form response when I enter it:


Does the web site have any idea how rude it is to claim that my last name contains invalid characters? Clearly not. What they actually meant is: our web site will not accept that hyphen in your last name. But do they say that? No, of course not. They decide to shove in my face the claim that there's something wrong with my name.

There's nothing wrong with my name, just as there's nothing wrong with someone whose first name is Jean-Marie, or someone whose last name is O'Reilly.

What is wrong is that way this is being handled. If the system can't cope with non-letters and spaces it needs to say that. How about the following error message:

Our system is unable to process last names that contain non-letters, please replace them with spaces.

Don't blame me for having a last name that your system doesn't like, whose fault is that? Saying "Your last name …

All the symmetrical watch faces (and code to generate them)

If you ever look at pictures of clocks and watches in advertising they are set to roughly 10:10 which is meant to be the most attractive (smiling!) position for the hands. They are actually set to 10:09.14 if the hands are truly symmetrical. CC BY 2.0image by Shinji
I wanted to know what all the possible symmetrical watch faces are and so I wrote some code using Processing. Here's the output (there's one watch face missing, 00:00 or 12:00, because it's very boring):



The key to writing this is to figure out the relationship between the hour and minute hands when the watch face is symmetrical. In an hour the minute hand moves through 360° and the hour hand moves through 30° (12 hours are shown on the watch face and 360/12 = 30).
The core loop inside the program is this:   for (int h = 0; h <= 12; h++) {
    float m = (360-30*float(h))*2/13;
    int s = round(60*(m-floor(m)));
    int col = h%6;
    int row = floor(h/6);
    draw_clock((r+f)*(2*col+1), (r+f)*(row*2+1), r, h, floor(m…

The Elevator Button Problem

User interface design is hard. It's hard because people perceive apparently simple things very differently. For example, take a look at this interface to an elevator:


From flickr

Now imagine the following situation. You are on the third floor of this building and you wish to go to the tenth. The elevator is on the fifth floor and there's an indicator that tells you where it is. Which button do you press?

Most people probably say: "press up" since they want to go up. Not long ago I watched someone do the opposite and questioned them about their behavior. They said: "well the elevator is on the fifth floor and I am on the third, so I want it to come down to me".

Much can be learnt about the design of user interfaces by considering this, apparently, simple interface. If you think about the elevator button problem you'll find that something so simple has hidden depths. How do people learn about elevator calling? What's the right amount of informati…