How to control arduino wirelessly with WebSockets and Johnny-five

Before we get started i want to point out that this is a follow up article of Control arduino with javascript (getting started with johnny-five). If you are new with johnny-five i recommend reading thru that article first.

Before we start setting up our environment we need to connect the RGB-Led to our arduino see schematic below or read more here

To be able to wirelessly control an RGB-Led we will need to use a couple of things:
First we need Express.js - it’s a framework for node.js that allows us to easily create web and mobile apps as well as API’s.

1
$ npm install express --save

Second we need WebSocket library - WebSocket is a communication protocol over a single TCP connection. It enables interaction between a web client (such as a browser) and a web server in real-time data transfer from and to the server.

1
$ npm install --save ws

Third we need johnny-five library

1
$ npm install --save johnny-five

And last we will use a library called jscolor for our color picker on the frontend part of our app.
Head over to http://jscolor.com/ and download the library.

After we are done with all of that let’s create our file structure

In our root directory we have server.js file - from here we will serve our static files inside the public folder and we will control the arduino. In the public folder we have index.html this will be our landing page when we visit the website, we also have index.js here we will connect to the WebSocket server and transfer the value chosen from the color picker. We also have a lib directory where we will store the jscolor library.

Let’s start from the index.html page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Color</title>
</head>
<body>
<script src='index.js'></script>
<script src='lib/jscolor.js'></script>
<h1>Please select a color</h1>
Color: <input id='myColor' class='jscolor' value='ab2567'>
</body>
</html>

Nothing fancy we have a link to the index.js script and a link to the jscolor library, an h1 tag and an input with class for our jscolor picker library as well as a default value for the same.

Let’s move on to the index.js file

1
2
3
4
5
6
7
window.onload =function(){
var socket = new WebSocket('ws://192.168.1.104:8080');
var el = document.getElementById('myColor');
el.addEventListener('change',function(data){
socket.send(data.target.value);
})
}

Here we grab the onload event and we create a socket connection

1
var socket = new WebSocket('ws://192.168.1.104:8080');

If you want to access the server from any device in your network make sure to put your own ip in my case the ip was 192.168.1.104 or leave it at localhost if you only want to access from the same machine where the server is.
Next we grab a hold of the input element and we add an eventListener to listen for the change event and we are passing in the event as data.

1
2
3
var el = document.getElementById('myColor');
el.addEventListener('change',function(data){
})

From here once we have chosen a color we send that color to the server

1
socket.send(data.target.value);

And last we take a look at server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const express = require('express');
const app = express();
const port = 3000;

var five = require("johnny-five");
const WebSocket = require('ws');
const wss = new WebSocket.Server({port:8080});

app.listen(port, () => { console.log("we are live") })
app.use('/color',express.static('public'));

five.Board().on('ready',function(){
var led = new five.Led.RGB({
pins:{
red:6,
green:5,
blue:3
}
});
led.on();
led.color('#FF0000');
wss.on('connection',function(ws,req){
console.log('connected');
ws.on('message',function(data){
led.color('#' + data);
})
})
})

Here we require our libraries express, johnny-five, and ws. We set the port of our express server to const port = 3000; and we create a WebSocket to listen on port 8080 const wss = new WebSocket.Server({port:8080}); Next we setup express to listen for the port 3000

1
app.listen(port, () => { console.log("we are live") })

and we setup a route /color

1
app.use('/color',express.static('public'));

That way when we navigate to localhost:3000/color public folder will be served and we will have the front-end part of our app rendered in the browser.
Next, after the board is ready we create an LED instance and set it to the correct pins:

1
2
3
4
5
6
7
8
9
five.Board().on('ready',function(){
var led = new five.Led.RGB({
pins:{
red:6,
green:5,
blue:3
}
});
})

Next we turn the Led on and we set a default color to it

1
2
led.on();
led.color('#FF0000');

After which we create the websocket connection

1
2
3
4
5
6
wss.on('connection',function(ws,req){
console.log('connected');
ws.on('message',function(data){
led.color('#' + data);
})
})

Here on connection we log connected and on message event we pass in the data transmitted from our frontend app in our case is the value of the color picker. So after we get that data we add it as a color for the RGB light

1
led.color('#' + data);

And that’s pretty much how you use websockets to wirelessly control an arduino board.
Check out the video below to see it in action.
Cya in the next one.



Share