Today is Tuesday, May 15th 2012. Just over a year ago, I discovered node-serialport by Chris Williams and went immediately to the closest Microcenter and purchased the Getting Started with Arduino kit.

With my new kit and Chris’s serialport code, I was able to produce a JavaScript program and an Arduino program coupled to produce a simple Light Dependant Resistor demo (Arduino programs are written in the Arduino programming language which is based on C/C++, which is then compiled with avr-gcc and shipped to the microcontroller. The program was simple: print the current value of the LDR to the terminal via interactive REPL. Take a look:
Pretty cool, right? Maybe, but I don’t want to write Processing, C or C++. I want make robots that are driven by JavaScript programs.
About a month later at JSConf 2011 in Porland Oregon, while sitting on the floor in the hallway, Max Ogden and I hacked together a rad demo that allowed him to slide his finger back and forth over a Soft Potentiometer Membrane to control video playback. The sensor was attached to an Arduino board, the board then connected via USB to his laptop, which was running a Node.js program that listened for serialport data events and pushed the sensor data back out to a web browser client via Socket.IO, which was processed into time and handed off to Popcorn.js.
Soft Pot > Arduino > USB > Node Serialport > Socket.IO > Popcorn.js
Once the touch data reached the client on the browser, which was being displayed on my laptop, we used Popcorn.js and the data values to fast-forward and rewind a video of a Monkey Riding a Dog. That code is available here and you can watch the demo here (jump to 22:34).
Neat, isn’t it? Maybe, but I don’t want to write Processing, C or C++. I want make robots that are driven by JavaScript programs.
After returning from JSConf, things got very busy at Bocoup and I simply didn’t have time, nor interest, to spend on my ideas. My kit collected dust for nearly a year, occassionally I would come across interesting JavaScript, Node and Arduino projects, but I was too busy to really spend any time with them.
In December 2011, Duino was released, but I didn’t discover it until March of 2012. This was very exciting, because it was doing all of the things I had hoped to do with JavaScript and Arduino – so I cloned the repo and tried out a few of the demos. Then I started writing code and making pull requests. There was still a problem however – Duino expected me to extend the protocol written in C++ that it shipped with, in order to add new features. I sucked it up and wrote several modules including GPS, Ping, PIR and Sensor.
So this was cool, but I don’t want to write Processing, C or C++. I want make robots that are driven by JavaScript programs.
Then this happened…
@paultag @rwaldron @campedersen wouldnt that basically be this github.com/jgautier/firma… ?
— julian gautier (@Jagautier) March 29, 2012
@rwaldron lol! you do know you have a fork right 😛 github.com/rwldrn/firmata
— julian gautier (@Jagautier) March 29, 2012
And everything changed.
The package Julian had created was a JavaScript implementation of Firmata, which is a protocol for communicating with Arduino microcontrollers from software on a host computer, written in any language. Free of Processing, C and C++ bondage, and using Firmata as the baseline communication channel, I rebooted and started from scratch. First, I endeavored to write a Board
constructor that, while inspired by and conceptually similar to Cam’s duino.Board()
, had finer abstractions for instance management, active serial/USB discovery and by-default REPL sessions built in to every program. This is the foundation of Johnny-Five.
Once I had the initial Board
constructor, I created a slightly modified version of Julian’s servo-sweep.js as a proof of concept for baseline of the framework:
claw-original.js
var five = require("../lib/johnny-five.js"),
board;
board = new five.Board();
board.on("ready", function() {
var claw = 9,
arm = 11,
degrees = 10,
incrementer = 10,
last;
this.board.pinMode( claw, 3 );
this.board.pinMode( arm, 3 );
setInterval(function() {
if ( degrees >= 180 || degrees === 0 ) {
incrementer *= -1;
}
degrees += incrementer;
if ( degrees === 180 ) {
if ( !last || last === 90 ) {
last = 180;
} else {
last = 90;
}
this.board.servoWrite( arm, last );
}
this.board.servoWrite( claw, degrees );
}.bind(this), 50);
});
With a stronger Board
constructor, porting all of the modules I had created for Duino into this new framework was mostly a breeze. A few days later, the Servo
module emerged, transforming the code into this:
claw-servo-api.js
var five = require("../lib/johnny-five.js"),
board;
board = new five.Board();
board.on("ready", function() {
var claw = new five.Servo( 9 ),
arm = new five.Servo( 10 ),
degrees = 10,
incrementer = 10,
last;
this.loop( 25, function() {
if ( degrees >= 180 || degrees === 0 ) {
incrementer *= -1;
}
degrees += incrementer;
if ( degrees === 180 ) {
if ( !last || last === 90 ) {
last = 180;
} else {
last = 90;
}
arm.move( last );
}
claw.move( degrees );
});
});
Over the next few weeks as I acquired new hardware and sensors, each new piece brought with it a new physical engineering and software engineering challenge. Several times I found myself revisiting a stable module and starting over when a useful abstraction presented itself. One of the most important refactorings that occurred had nothing to do with code. Early on it became clear that I would need to document the hardware that I was building, especially if I was to continue creating sans permanence. Arduino tutorials are often published with colorful illustrations of the microcontroller connected to a breadboard and various gadgets – this is what I wanted and what I found in Fritzing. With Fritzing, I now had the tools to quickly and easily create detailed, visually appealing documentation of the hardware that accompanied each of the example programs that I created.
led-strobe.js
var five = require("johnny-five"),
board, led;
board = new five.Board();
board.on("ready", function() {
// Create a standard `led` on pin 13
led = new five.Led(13);
// "strobe" the led in 100ms on-off phases
led.strobe(100);
});
Once assembled, the program can be run from the command line as
node led-strobe.js
and should look like this:
Admittedly, this example is less-then-mind-blowing — but it’s just one piece of a larger whole.
My goal for Johnny-Five is to create a framework for programming Arduino Robots with nothing more then JavaScript. I believe that JavaScript, inherently asynchronous and the platform that Node.js has built around this paradigm, is the perfect environment for writing evented, streaming programs for controlling the highly synchronous world of hardware.
As part of Johnny-Five’s development process, I’ve created 28 component-centric mini-programs. I intend to publish these along with breadboard schematics and parts lists, twice each week over the next few months.
…And this is how I’ll make robots that are driven by JavaScript programs.
As the language continues to prove itself worthy of high performance use beyond the browser and its lower level capabilities improve, I don’t think it’s unreasonable to at least open our minds and imagine a future where we control things like home and vehicle automation, assembly lines, meteorological equipment, robotics… etc. with programs written in JavaScript.
References: [0] node-serialport[1] Chris Williams[2] Microcenter[3] Getting Started with Arduino[4] Arduino[5] Arduino LDR Demo[6] Arduino program[7] Arduino programming language[8] C[9] C++[10] avr-gcc[11] Node REPL[12] JSConf 2011[13] Max Ogden[14] Soft Potentiometer[15] Soft Potentiometer Membrane[16] Socket.IO[17] Popcorn.js[18] Monkey Riding a Dog[19] Monkey Riding a Dog Demo Code[20] Duino[22] GPS[23] Ping[24] PIR[25] Sensor[26] Firmata JavaScript implementation[27] Firmata[28] Johnny-Five[29] servo-sweep.js[30] Hardware and Sensors[31] Fritzing[32] int64/uint64 value objects prototyped in SpiderMonkey[33] JavaScript Today and Tomorrow: Evolving the Ambient Language of the Ambient Computing Era[34] Controlling Big, Mean, Devices…..With Javascript!
Comments
We moved off of Disqus for data privacy and consent concerns, and are currently searching for a new commenting tool.
I need to come down for the next arduino hack night. \u00a0I have a great idea which involves shock collars!\u00a0
This is very interesting. I have played with audrino a bit, but I’m more comfortable with javascript than C. Glad you put the detail into this post.
Have you been playing around with RF or XBees at all? After a certain point with Duino, I got discouraged and realized I was going to have to keep the Arduino in proximity to the computer at all times. I’d really like to get a 3G module going!
check out freaklabs… 😉
Sorry, I’m an idiot and replied to you in a new comment, instead of a real reply.
Cam Pedersen\u00a0 The issues I’ve been running into with Xbee and Bluetooth is that they overtake the RX/TX pins and Firmata isn’t down with that. We’re working on extended Firmata to support software serial lines.
This should really help boost\u00a0enthusiast\u00a0contributions to the Arduino Platform. Congrats!\u00a0
AWESOME, love this. \u00a0Can’t wait to try it out.
Wow, I think you found and started the holy grail to robotics programming. Was waiting for this before getting my hands dirty with Arduino.
Or you could just buy a Netduino for $40 (or a number of other .NET Micro devices) and run .NET code out of the box with all the type safety and goodness of C# and more recently VB.NET. It’s even compatible with arduino shields.
Thanks for the additional info Jim, but the whole point is that I\u00a0don’t want to write .NET, C# or VB.NET.\u00a0
\u00a0The stated point is that you didn’t want to write in C or C++ which is much different…
I was trying to be nice, but I feel like this is just an attempt to detract from the point of my post.
Jim, you’re an asshole.
Both JavaScript and C# are piles of cancer anyway.
Thanks for the incredibly insightful commentary
Honestly, I’m not a big fan of javascript, but as a roboticist, I can tell you I usually avoid .NET, C#, VB.NET and, sometimes, even C++.
There exists robotic frameworks in Erlang:
http://dl.acm.org/citation….
and in Python, as well:
http://www.springerlink.com…
Especially Erlang makes really easy to handle to source code, even when the project grows dramatically in size. 🙂
Cool, thanks for sharing.
This is really cool!
I started writing a mini-framework that I use to control a bunch of Arduino-based wireless gadgets in my house:\u00a0https://github.com/robbles/…
I didn’t know about node-serialport at the time, so I used a wrapper around node’s child processes that made it really easy to wrap programs written in other languages (mostly Python scripts). I tacked on support for XMPP messages, publish/subscribe, and web hooks, which made it simple to build web apps for controlling Arduino projects.
Your approach for controlling the actual hardware sounds much easier though – I’d definitely be interested in helping out with this if you’re interested in contributions. The one downside I ran into with Javascript though is the poor support for binary data – how are you planning on getting around this?
Great work. I’ve written a .js that parses a twitter feed to manipulate elements on a web page. My next step is to send the data from the web page to an Arduino to manipulate real world objects. Your post gave me some ideas on how to accomplish that. I’ll be studying this over the next few days. Thanks.\u00a0
BeagleBone seems to be interesting in that it has a distibution with node running on it, unfortunately not compatible with arduino boards, has this come on your radar? If so I’d be interested in what your thoughts are.
Does anybody here know how hard it would be to get Duino working with a Digispark (http://digistump.com)? I’ve been working on talking to it via USB from nodejs, but no luck yet. Partly because I’m new to Arduino in general, and the Digispark is just different enough that some things don’t work (like the Servo library), and partly because I don’t have a lot of time to play with it.
You might have more luck asking on the Duino repo’s issue thread.
jejejeje excellent..
I’d love to use this framework BUT, sadly, I can’t because I can’t compile node-serial. It has a dependency on Windows that can only be met by installing the expensive, full version of MS Visual Studio. I’ve added a comment to someone elses bug report for the same issue but there is no feedback. Looks like it’s back to Python for now.
You should be aware that the \”serbo-croatian translation\” is a thinly-veiled scam to get you to put a link to their site (WebHostingGeeks), which will improve their Google PageRank.
Don\u2019t you think it\u2019s a little random that they would choose that specific page to translate, and no other pages?
i just think that node js arduino and johnny-five are amazing
Hey can you make SEEED blue tooth communicate IPOD 4G?
Have you tried it.
Is there a way to compile johnny-five node code into machine code and run on the Arduino without the need of a PC, just only standalone? I totally noob for robotics (I have webdesign experience and started to get familier with Node.js, first only with the express, handlebars routing capabilities). I want to create a temperature sensor wich is turn on a switch when it reaches let’s say 1 Celsius. The switch’s other end will be a water pump which is starting to work and creating water vapor on the fruit trees (freeze protection for our farm).
Another question is that multiple temperature sensors will be placed at the different parts of the field. This means lots of electronic cable distance, possibly 100 meters. The arudino will be placed next to the water pump and all of the temp sensor’s cables meet in this arduino. Can the long distance create loose of signal or high resistance? (I know, lack of electronics knowledge.)
Having a Raspberry pi running with Debian I think a little bit overshoot for a microcontroller project, is it?
-\”Is there a way to compile johnny-five node code into machine code and run on the Arduino without the need of a PC, just only standalone\”
I also would like to know this 🙂
No, that’s not how Johnny-Five works when controlling an Arduino and it’s not possible to compile JS to C in the way you’re asking.
If you want to run JS directly on a board, you’ll need to use a board that supports a full Node.js runtime, for example Intel Edison, Beagle Bone, Raspberry Pi or Tessel 2. (I currently prefer the last)
Thanks for clearing that up! Time to go shopping.
😀
I am just a beginner and I have a question: is that important to have always a host PC?? if yes, how could I use Javascript with RC project ??