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:
- An Arduino, and the Arduino IDE
- an HTML5-capable browser. I used Chrome, but Opera or Firefox or Safari will work too)
- node.js and the following libraries for node:
- How to use Arduino, including how to send serial data
- How to write a web page, and what a server is
- A little about the command line
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:
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, socket.io and node-serialport. The former allows you to read to and write from WebSockets using node:
npm install socket.io
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
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.
Here’s the index page. It loads the client.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.
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 /nodeSerialServer.
To run this, change directories to Save this in /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.
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. You just need to change
var socket = io.connect('http://localhost:8080');
var socket = io.connect('http://yourMachinesIPAddress:8080');
Thanks, Sam for the note. (I’m not sure this still works in socket.io 1.0 and later)
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.