Introduction
This article provides the necessary steps in allowing your Arduino board to be interfaced to the web using novel but Open Source technologies everyone can use. This has long been available but using other alternative ways of doing things by using LAN, or Zigbee modules/shields for Arduino, and they can be quite expensive. However, depending on the purpose, this simple solution may be sufficient enough.
You can watch this simple video as a simple demonstration of what can be done using your Arduino and the Web.
Background
Using the USB, the Arduino Board is connected to the PC serially to a certain COM port which the OS allocates. Node.JS, the asynchronous server side JavaScript engine then listens for the port using a Node.JS module called SerialPort2. When a signal is received, using the Node.JS Socket.IO module, data is then served also asynchronously to the web providing a real time feed of the Arduino signal.
The following are the key technologies being used to present the feasibility of this approach to the particular problem:
- Arduino - A small electronics prototyping board. Available in multiple versions but in this article the one being used is the Arduino Mega 2560 Version 1. The same methods can be applied to other versions of the Arduino as long as it has means to output data serially.
- NodeJS - A server side JavaScript interpreter.
- NodeJS SerialPort2 - A Node.JS module for listening to COM ports.
- NodeJS Socket.IO - A Node.JS module for serving async data to the web using technologies such as WebSockets.
- NPM - Is a Node.JS package manager already included with the official installer of Node.JS.
- jQuery - A JavaScript library for easier scripting.
- Flot - Flot is a pure JavaScript plotting library for jQuery.
- Apache - Used in this project for serving static content. The WAMP pack is the suggested package for easy installation. The user can also use the WAMP pack for hosting PHP and MySQL.
For Windows users, SerialPort2 requires the following for a successful build:
- Python 2.7.3
- Visual Studio 2010
- Windows SDK 7.1
The Solution
It is considered that the user already has a working knowledge of an Arduino. For the purpose of this article, we will create a certain scenario for which we will create a solution. A potentiometer is connected to the Arduino board to Analog pin 0 (from now on referred to as A0). We will want to stream the analog signal levels to the web and view it using a web browser such as Google Chrome, Firefox, or Internet Explorer. The signal levels must update in real time as the potentiometer is rotated.
Preparation of the Arduino Board
You can refer to the following schematic in order to setup the potentiometer and your Arduino board.
Programming your Arduino
You can use the following code for you Arduino. The code is sufficiently commented. It is recommended that the reader understand how the code works with respect to the Arduino in order to fully understand the next steps.
const int analogInPin = A0;
int sensorValue = 0;
int prevsensorValue = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(analogInPin);
if (prevsensorValue != sensorValue) {
Serial.print("A");
Serial.print(sensorValue);
Serial.print("B");
prevsensorValue = sensorValue;
}
delay(100);
}
Preparing Node.JS
You can download the official installer of Node.JS from its official website. The recommended version is Node.JS v0.7.8. Also, in order to successfully build SerialPort2 on Windows, you are required to install Python 2.7.3 and Microsoft Visual Studio 2010 with the Microsoft Windows SDK 7.1. The NPM module which is already a part of the Node.JS v0.7.8 will take care of the build process. However, to make things easier, you may need to add the python.exe directory path to the PATH environment variable.
In order to install the required Node.JS modules using your command prompt, go to your working directory. The following command will download, build, and install the necessary Node.JS modules.
npm install serialport2 socket.io
You should have an output that will appear similar to this.
Preparing the Server Side
Create a file called server.js on the working directory.
The following lines of code prepares the necessary connections for Node.JS and the port. Data received is the global variable:
var SerialPort = require('serialport2').SerialPort;
var portName = 'COM3';
...
Then the following code opens the serial port connection:
...
var sp = new SerialPort();
sp.open(portName, {
baudRate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
...
The following code is triggered only when the serial port is receiving messages from the specified port.
...
var cleanData = '';
var readData = '';
sp.on('data', function (data) {
readData += data.toString();
if (readData.indexOf('B') >= 0 && readData.indexOf('A') >= 0) {
cleanData = readData.substring(readData.indexOf('A') + 1, readData.indexOf('B'));
readData = '';
}
});
...
We are now ready to send the clean data to the web. In order to do this, we must first setup the Socket.IO module. On the top part of the file, insert the instantiation of the Socket.IO module.
var SerialPort = require('serialport2').SerialPort;
var portName = 'COM3';
var io = require('socket.io').listen(8000);
io.set('log level', 1);
...
The next step is to turn on Socket.IO.
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log(msg);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
});
The last step is to allow the server side Socket.IO to emit a message to all listening clients if there is new sensor data. In order to do this, insert the following line to sp.on('data')
.
...
io.sockets.emit('message', cleanData);
...
After updating the code, sp.on('data')
will look like this:
...
var cleanData = '';
var readData = '';
sp.on('data', function (data) {
readData += data.toString();
if (readData.indexOf('B') >= 0 && readData.indexOf('A') >= 0) {
cleanData = readData.substring(readData.indexOf('A') + 1, readData.indexOf('B'));
readData = '';
io.sockets.emit('message', cleanData);
}
});
...
Your entire server side source code server.js will look like the following:
var SerialPort = require('serialport2').SerialPort;
var portName = 'COM3';
var io = require('socket.io').listen(8000);
io.set('log level', 1);
var sp = new SerialPort();
sp.open(portName, {
baudRate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log(msg);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
});
var cleanData = '';
var readData = '';
sp.on('data', function (data) {
readData += data.toString();
if (readData.indexOf('B') >= 0 && readData.indexOf('A') >= 0) {
cleanData = readData.substring(readData.indexOf('A') + 1, readData.indexOf('B'));
readData = '';
io.sockets.emit('message', cleanData);
}
});
Preparing the Client Side
This is how we will want the client side to look like:
The progress bar is powered by jQuery. The graph output is powered by Flot. The value, progress bar, and graph updates in real time as shown in this video.
You must have the jQuery library, and an appropriate jQuery UI library on your working directory to make this work. Also, the Flot library is required to make the graph work.
Refer to the source code section for the exact coding of the index.html.
Final Step
Connect your Arduino to your PC using the USB and determine the correct port which it was assigned to. You can usually easily do this by using the Arduino programmer software and checking the available ports. For Windows, it is usually higher than COM Port 1.
Setup the Apache config to point to your working directory and have it serve the index.html for the clients.
Using the command prompt pointed at your working directory, you can run server.js by issuing the following command:
node server.js
You can then rotate your potentiometer and see the potentiometer value, bar graph, and the line graph respond to changes in real time.
Recent Updates
NodeJS SerialPort2 is think now is merged with the original SerialPort project. You may check the projects here and the message by the author of those great modules here.
Points of Interest
Of course if you want an easier solution, you can buy the Ethernet Shield or the ZigBee shield for an even more sophisticated implementation.
History
- Aug 19, 2012 01:03 AM PHT - Edited links and added some more information.
- May 22, 2012 7:02 AM PHT - Submitted for posting.