Serial to Browser using node.js

Updated 28 July 2015

This is a brief introduction to using node.js and websockets to connect a serial device, like an Arduino microcontroller, to a browser.

To make this happen you’ll need:

This post assumes you understand:

Install node.js on your computer. It’s a server-side engine for javaScript, it allows you to write web servers in JavaScript. There’s lots of great tutorials on it on the web, but the main Node site has pretty good instructions on getting started.

Make a directory to keep all your node projects in. On my mac, I went with the predictable: ~/Documents/node/

Open a command line application (Terminal on OSX, for me). Change directories to the node directory:

cd Documents/node/

Now you need to install a few node libraries. The first is express.js, a library that simplifies writing nice RESTful web servers in node. Node has an easy package manager that will do it for you. Type:

npm install express

You’ll get a lot of feedback in the terminal while the package manager downloads and installs the express.js library. Once it’s done, you’ll have a new directory called node_modules inside Documents/node/. Now install two more libraries, ws.js and node-serialport. The former allows you to read to and write from webSockets using node:

npm install ws

then when it’s done:

npm install serialport

Node-serialport allows you to access your computer’s serial port, and read to and write from them.

You can also add the libraries all at once by adding a file to your project directory called package.json, containing the required libraries.  For more on this, see the npm guide to making packages. The gitHub repository for this project contains a package.json file, so you can just type

npm install

and it will install all the required packages for you. You can thank Steve Klise for making me do that.

Once you have the libraries installed, put a sketch on your Arduino that sends something out the serial port. I used the AnalogReadSerial example, which comes with Arduino. Look under File-> Examples-> 01.Basics->AnalogReadSerial. Once you know it’s working, you’re ready to write the server script. Anything will do, as long as it sends a carriage return and newline, like Serial.println() does.

Make a new directory inside Documents/node/ for your application. Call it nodeSerialServer, or anything else you like. Inside that folder you’ll save two files, an index.html page that you’ll view in a browser, and SerialServer.js, a javaScript server that you’ll run using node.

I chose to make my index page and JavaScript page with p5.js.  Here’s the index page. It loads the sketch.js script, written with P5.js, that handles the socket communication. It opens a webSocket back to the server, and listens for events from the server. Whatever data it gets from the event, it prints to a DIV inside itself. See the inline comments for more details. Save these in a new subdirectory /nodeSerialServer/public.

Note the project structure in the gitHub repo: the server lives in the root of the project directory, and all the documents that will be passed to the client: the index.html and the sketch.js page and any additional js pages for p5.js, are in the /public subdirectory.

Here’s the server. It starts a web server and listens for HTTP requests for public/index.html, and serves it out when asked. It also listens for incoming webSocket requests, and opens them. When it does so, it start listening for serial events. If it gets a carriage return and newline in the serial port, it sends what it got out to the websocket. Save this in your main project directory.

To run this,  change directories to Save this in /nodeSerialServer:

cd /nodeSerialServer

then run the server.js script using node. To invoke this script, you need to give it the name of the serial port you want to open on the command line like so:

node server.js /dev/tty.usbmodem621

Substitute the name of your port for the name of my port above.You’ll get a message that the script started. Now open a browser and open this address:

http://localhost:8080

The server will deliver index.html to your browser and start listening to the serial port.  The index page will listen for serial events from the server, and update the DIV with the new data.  Voila! You’re serving serial data to a web page.

To stop the server, hold down the control key then type C on the command line.

This is only a beginning, and a crude one at that.  It can be improved a lot. But hopefully it gives you enough of an idea to get started. For more on node.js, check out the Node Beginners Book.

To write this example, I borrowed from the examples included with ws.js, express.js, and node-serialport, all of which provide excellent starts.  Enjoy.

Update:  Though I only wrote and tested this on localhost, reader Sam Royston mailed me to tell me that it will work just fine from a remote client, if you have no firewall and a public IP address on the machine on which you are running Node.  I’ve updated the code to account for this.  Thanks, Sam for the note.

Update 2: Thanks to Lia Martinez and Will Jennings, this now works with Express 3.0.  Thanks to Steve Klise, it has a package.json file for your installing convenience.

Update 3: I changed the index.js script so that you can pass it the serial port from the command line.

Update 4: I changed this from socket.io to ws.js because nowadays I find ws.js faster and easier to work with then socket.io.