Node.js on the Arduino Yún

Recently, Federico Fissore added node.js to the package repository for the Arduino Yún. Here’s how you get node to communicate with the Arduino processor on the Yún via the Bridge library.

To do this, you’ll need an Arduino Yún, a microSD card, a microUSB cable and a wifi connection. You should be familiar with the basics of the Arduino Yún and node.js in order to get the most out of this post.

All of the code for this post can be found on my GitHub repository.

First you’ll need to install node on the Yún. Make sure you’ve upgraded to the current Yún software image and have connected to the internet via wifi. Then ssh into your Yún, or connect to the command line interface using the the YunSerialTerminal sketch, and issue the following commands:


$ opkg update
$ opkg install node

That’s it. Now you have node.js onboard. You can check that it’s okay by checking the version:

$ node -v

You should get the version number in reply.

Once you’ve got that working, you’ll undoubtedly want to communicate with the Yún’s Arduino processor from node. You can do this using the Bridge library. On a microSD drive, make a directory for your node scripts. I called mine /arduino/node. Then insert it into your Yún. For reference, its path from the command line is /mnt/sda1/arduino/node.

Note: The Yún automatically treats the microSD card’s /arduino/www/ directory as a public web directory. Anything you put in there will be served out as static HTML. So you may not want to put your node scripts in this directory, so they’re not visible via the browser. That’s why I created a node directory at the same level as the www directory, but outside it.

Running a Simple Server

Once you know node’s working, try running a simple server on it. Create the following file in the /arduino/node/ directory, called server.js:


var http = require("http"),							// require HTTP library
	server = http.createServer(respondToClient);	// create a server with a callback

server.listen(8080);				// start the server listening

// let the user know you started:
console.log('Server is listening on port 8080');

// this is the callback function that's called
// whenever a client makes a request:
function respondToClient(request, response) {  
	console.log("request from: ");
	console.log(request.connection.remoteAddress);
		
	console.log("URL:");
	console.log(request.url);
		
	// write back to the client:
	response.writeHead(200, {"Content-Type": "text/html"});  
	response.write("Hello, " + request.connection.remoteAddress);
	response.end();
};


To run this, make sure you’re in the /arduino/node directory and type the following on the command line:

$ node server.js

Then in the browser, go to your Yún’s IP address, port 8080. For my machine on my network, it’s 192.168.1.110:8080. You’ll get a hello web page that tells you your client address, and you’ll see the same info on the command line of the Yún. Congratulations, you’ve got your first node script working on the Yún!

File Transfer to the Yún

You may find it tedious to edit text on the Yún, and equally tedious to continually remove your SD card to save files. You can use scp to transfer files as well. To do this, change directories on your local machine to your project directory, then to transfer the server.js file to the /arduino/node directory on the Yún, type the following:

scp server.js root@yournode.local:/mnt/sda1/arduino/node/.

You’ll be prompted for your Yún’s password and the file will automatically overwrite whatever’s there.

Communicating from Bridge to Node

Starting a node script from the Arduino processor using Bridge is easy. You use the Bridge library’s Process class and call the node script using Process.runShellCommandAsynchronously(). Anything that node sends via console.log will be sent to your Arduino sketch, and you can read it using Process.read(). Here’s how you’d launch the server.js script:


Process nodejs;
nodejs.runShellCommandAsynchronously("node /mnt/sda1/arduino/node/server.js");

You can use this BridgeToNode sketch, and replace echo.js with server.js


/*
  Running Node.js processes asynchronously using
  the Process class.

 This sketch shows how to run a node.js script as a linux shell command
 using an Arduino Yún. It starts a process running asynchronously,
 then passes bytes from the STDOUT of the process to the Arduino's
 serial port.  Any bytes from the Arduino's serial port
 are sent to the STDIN of the process.

 created 21 Jun 2014

 by Tom Igoe

 */

#include <Process.h>
Process nodejs;    // make a new Process for calling Node


void setup() {
  Bridge.begin();	// Initialize the Bridge
  Serial.begin(9600);	// Initialize the Serial

  // Wait until a Serial Monitor is connected.
  while (!Serial);
  
  // launch the echo.js script asynchronously:
  nodejs.runShellCommandAsynchronously("node /mnt/sda1/arduino/node/echo.js");

  Serial.println("Started process");
}

void loop() {
  // pass any bytes that come in from the serial port
  // to the running node process:
  if (Serial.available()) {
    if (nodejs.running()) {
      nodejs.write(Serial.read());
    }
  }

  // pass any incoming bytes from the running node process
  // to the serial port:
  while (nodejs.available()) {
    Serial.write(nodejs.read());
  }
}





When you run this, it will launch server.js once you open the Serial Monitor (the line while (!Serial); stops the sketch until you do so), and if you go to the server in a browser as you did above, you’ll see the console.log results in the Serial monitor. Node is now talking to the Arduino processor.

The Process.runShellCommandAsynchronously() is important in the sketch above. It tells Arduino to launch the sketch but not to wait for a result. This way, node can do its business and the Arduino sketch can do its business, and they’re not waiting for each other.

Communicating from Node to Bridge

Now that you have a server running and communicating with the Arduino processor it’s time to get the Arduino processor communicating back to node. Create the following node script in the node directory on your Yún:


var readline = require('readline');	// include the readline module

console.log("Hello Arduino");			// send an intial message on startup
   
// create an interface to read lines from the Arduino:
var lineReader = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

// when you get a newline in the stdin (ends with \n),
// send a reply out the stdout:
lineReader.on('line', function (data) {
  console.log('You sent me: '+ data);
});

This node script uses the readline module to exchange data with the stdin and stdout. When the Bridge library calls this script, anything you print to console.log will get sent to Bridge, and anything that you send from the Arduino via Bridge with a newline at the end (for example, if you used println()) will appear as data in the linereader.on() function. Save this sketch to your node directory on your Yún.

Run the NodeToSerial sketch above again, this time replacing server.js with echo.js again. The Arduino will launch echo.js. This script starts by saying hello, then echoes back to you anything you send it. It doesn’t do much by itself, but it shows you how to effect two-way communication between node and the Arduino processor.

Conclusion

Being able to communicate between a node script and the Arduino processor has lots of uses. You can write scripts in node to make http calls and filter the results for you, or write node servers as an alternative to the Yún’s built in REST server. With control of the programming on both the Arduino and the Linux processors, you can decide how you want to structure the communication between them, to take best advantage of both.

All of the code for this post can be found on my GitHub repository.

This entry was posted in arduino/wiring, code, javascript, node.js and tagged , , , . Bookmark the permalink.

Comments are closed.