Playing With Arduino, IoT, Crossbar, and WebSockets
Learn how to display in a webpage one value from your Arduino board; for example, one piece of analog data using a potentiometer.
Join the DZone community and get the full member experience.
Join For FreeYes! Finally, I’ve got an Arduino board. It’s time to hack a little bit. Today, I want to try a few different things. I want to display in a webpage one value from my Arduino board; for example, one piece of analog data using a potentiometer. Let’s start.
We are going to use one potentiometer. A potentiometer is a resistor with a rotating contact that forms an adjustable voltage divider. It has three pins. If we connect one pin to 5V power source of our Arduino, another one to the ground, and another to one A0 (analog input 0), we can read different values depending on the position of the potentiometer’s rotating contact.
Arduino has 10-bit analog resolution. That means 1,024 possible values, from 0 to 1,023. So when our potentiometer gives us five volts, we’ll obtain 1,024, and when our it gives us 0V, we’ll read 0. Here, we can see a simple Arduino program to read this analog input and send data via serial port:
int mem;
void setup() {
Serial.begin(9600);
}
void loop() {
int value = analogRead(A0);
if (value != mem) {
Serial.println(value);
}
mem = value;
delay(100);
}
This program is simple loop with a delay of 100 milliseconds that reads A0 and if the value is different than previously read (to avoid sending the same value when nobody is touching the potentiometer), we send the value via the serial port (with 9,600 bauds)
We can test our program using the serial monitor of our Arduino IDE our using another serial monitor.
Now, we’re going to create one script to read this serial port data. We’re going to use Python. I’ll use my laptop, and my serial port is /dev/tty.usbmodem14231.
import serial
arduino = serial.Serial('/dev/tty.usbmodem14231', 9600)
while 1:
print arduino.readline().strip()
Basically, we’ve got our backend running. Now, we can create a simple frontend.
...
<div id='display'></div>
...
We’ll need WebSockets. I normally use socket.io but today, I’ll use Crossbar.io. Since I heard about it in a Ronny’s talk at the deSymfony Conference, I've wanted to use it.
I’ll change a little bit of our backend to emit one event:
import serial
from os import environ
from twisted.internet.defer import inlineCallbacks
from twisted.internet.task import LoopingCall
from autobahn.twisted.wamp import ApplicationSession, ApplicationRunner
arduino = serial.Serial('/dev/tty.usbmodem14231', 9600)
class SeriaReader(ApplicationSession):
@inlineCallbacks
def onJoin(self, details):
def publish():
return self.publish(u'iot.serial.reader', arduino.readline().strip())
yield LoopingCall(publish).start(0.1)
if __name__ == '__main__':
runner = ApplicationRunner(environ.get("GONZALO_ROUTER", u"ws://127.0.0.1:8080/ws"), u"iot")
runner.run(SeriaReader)
Now I only need to create a crossbar.io server. I will use a node to do it:
var autobahn = require('autobahn'),
connection = new autobahn.Connection({
url: 'ws://0.0.0.0:8080/ws',
realm: 'iot'
}
);
connection.open();
Now, we only need to connect our frontend to the WebSocket server:
$(function () {
var connection = new autobahn.Connection({
url: "ws://192.168.1.104:8080/ws",
realm: "iot"
});
connection.onopen = function (session) {
session.subscribe('iot.serial.reader', function (args) {
$('#display').html(args[0]);
});
};
connection.open();
});
It works — but thre’s a problem. The first time we connect with our browser, we won’t see the display value until we change the position of the potentiometer. That’s because the iot.serial.reader
event is only emitted when potentiometer changes. No change means no new value. To solve this problem, we only need to change a little bit of our crossbar.io server. We’ll “memorize” the last value and we’ll expose one method iot.serial.get
to ask about this value:
var autobahn = require('autobahn'),
connection = new autobahn.Connection({
url: 'ws://0.0.0.0:8080/ws',
realm: 'iot'
}
),
mem;
connection.onopen = function (session) {
session.register('iot.serial.get', function () {
return mem;
});
session.subscribe('iot.serial.reader', function javascript:void(0)(args) {
mem = args[0];
});
};
connection.open();
And now, in the frontend, we ask for iot.serial.get
when we connect to the socket:
$(function () {
var connection = new autobahn.Connection({
url: "ws://192.168.1.104:8080/ws",
realm: "iot"
});
connection.onopen = function (session) {
session.subscribe('iot.serial.reader', function (args) {
$('#display').html(args[0]);
}).then(function () {
session.call('iot.serial.get').then(
function (result) {
$('#display').htmlresult);
}
);
}
);
};
connection.open();
});
And that's all! The source code is available at my GitHub account. You also can see a demo of the working prototype in the below video:
Published at DZone with permission of Gonzalo Ayuso, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Observability Architecture: Financial Payments Introduction
-
A Complete Guide to Agile Software Development
-
Understanding Data Compaction in 3 Minutes
-
DevOps vs. DevSecOps: The Debate
Comments