In this example the analog value from the potentiometer will be read and shown on the graph on client side. In order to observe the results the interactive real time streaming graph will be developed.
First, we should connect the potentiometer to the board. Schematics is shown on the next figure:
The breadboard view is the following (here we should put pot, Arduino and breadboard as shown from left to right for further application). On the breadboard the minus (-) and (+) strips are established in the lower right part of the breadboard. This will be usefull later on.
We should declare new variable for desired value which pot represents on the server side (.js file):
var desiredValue = 0; // desired value varWe should enable analog pin:
console.log("Enabling analog Pin 0");board.pinMode(0, board.MODES.ANALOG); // analog pin 0Board analog value is read by the following command:
board.analogRead(0, function(value) { desiredValue = value; // continuous read of pin A0});Definition of the function which sends the data to the last connected client:
wss.sendToLastWs = function sendToLastWs(data) { if (wss.clients[wss.clients.length-1] !== undefined) { // if websocket exist if (wss.clients[wss.clients.length-1].readyState === WebSocket.OPEN) { // if it is connected wss.clients[wss.clients.length-1].send(data); // send to the last connected client - to only one client's websocket } }};Definition of the function that sends the data to all connected clients
wss.broadcast = function broadcast(data) { wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(data); } });};Within the socket, we set the interval on which the values from the server are sent to the client (setInterval):
wss.on('connection', function (ws, req) { // start of wss code messageJSON = {"type": "message", "content": "Srv connected, board OK"}; ws.send(JSON.stringify(messageJSON)); setInterval(sendValues, 40); // on 40ms we send message to client}); // end of sockets.on connectionFunction for sending desired value in the json form (we can test sendToLastWs and broadcast function):
function sendValues () { wss.sendToLastWs(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue})); //wss.broadcast(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue}));};Code for the first step:
var http = require("http").createServer(handler); // on req - handvar fs = require("fs"); // variable for file system for providing htmlvar firmata = require("firmata");const WebSocket = require('ws'); // for permanent connection between server and clientconst wss = new WebSocket.Server({port: 8888}); // websocket port is 8888wss.broadcast = function broadcast(data) { wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(data); } });};wss.sendToLastWs = function sendToLastWs(data) { if (wss.clients[wss.clients.length-1] !== undefined) { // if websocket exist if (wss.clients[wss.clients.length-1].readyState === WebSocket.OPEN) { // if it is connected wss.clients[wss.clients.length-1].send(data); // send to the last connected client - to only one client's websocket } }};var messageJSON;console.log("Starting the code");var board = new firmata.Board("/dev/ttyACM0", function(){ console.log("Connecting to Arduino"); console.log("Enabling analog Pin 0"); board.pinMode(0, board.MODES.ANALOG); // analog pin 0});function handler(req, res) { fs.readFile(__dirname + "/example10a.html", function (err, data) { if (err) { res.writeHead(500, {"Content-Type": "text/plain"}); return res.end("Error loading html page."); } res.writeHead(200); res.end(data); })}var desiredValue = 0; // desired value varhttp.listen(8080); // server will listen on port 8080board.on("ready", function() { board.analogRead(0, function(value){ desiredValue = value; // continuous read of analog pin 0 }); wss.on('connection', function (ws, req) { // start of wss code messageJSON = {"type": "message", "content": "Srv connected, board OK"}; ws.send(JSON.stringify(messageJSON)); //console.log(wss.clients[1]); setInterval(sendValues, 40); // on 40ms we send message to client }); // end of sockets.on connection}); // end of board.on(ready)function sendValues () { //wss.sendToLastWs(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue})); wss.broadcast(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue}));};In .html file we have only added the log of desired value:
ws.onmessage = function(event) { var msg = JSON.parse(event.data); // string from ws is put to JSON switch(msg.type) { case "message": log(msg.content); // add msg to div break; case "clientReadValues": log(msg.desiredValue); // add msg with value to div break; }};<!DOCTYPE html><meta charset = utf8><html><head><title>Example with pozi</title></head> <body> <div id="print1"></div> <br> <script type="text/javascript"> "use strict"; // in order to use clasess var divElement = document.getElementById("print1"); // var for div el. var numberOfLinesBeforeScroll = 10; var linesPrintCounter = 0; function log(msg) { var node=document.createElement("tr"); // we create the variable node as the a table row (tr) var textnode=document.createTextNode(linesPrintCounter + " | " + msg); // we create element with the text adding the counter node.appendChild(textnode); // adding text to "node", i.e. table row divElement.insertBefore(node, divElement.childNodes[0]); // inserting into variable node if (linesPrintCounter > numberOfLinesBeforeScroll-1) { // if the lines are more than limit -> start with scroll divElement.removeChild(divElement.childNodes[numberOfLinesBeforeScroll]); // we remove the oldest printout } linesPrintCounter++; // increasing the number of printouts } let ws = new WebSocket("ws://192.168.254.149:8888"); // create socket - connect to itvar messageJSON;ws.onmessage = function(event) { var msg = JSON.parse(event.data); // string from ws is put to JSON switch(msg.type) { case "message": log(msg.content); // add msg to div break; case "clientReadValues": log(msg.desiredValue); // add msg with value to div break; }}; </script></body></html>The values from the potentiometer should be seen as in the following figure:
On client side, we declare, that onLoad the function load should be run:
<body onload="load()";>In html part, we declare the canvas:
<canvas id="canvas1" width = "200" height = "100" style="border: 1px dashed #00c3c3;"></canvas>Declaration of new variables and function load():
var potValue1 = 0; // value of first potentiometer
var x1 = new Array(); // array for x1 variablevar y1 = new Array(); // array for y1 variablevar canvas1;var ctx1;function load() { // function that is started, when we open the page canvas1 = document.getElementById("canvas1"); ctx1 = canvas1.getContext("2d"); // initialization of graph with points ctx1.lineWidth = "1"; ctx1.strokeStyle = "#ff0000"; // draw first time series initialization for (var i=0; i<200; i++) { x1[i] = i; // for x values are 0, 1, 2, ... y1[i] = 0; // for y values are 0 };};Within WebSocket ws we make the graph:
potValue1 = msg.desiredValue; // Draw graph ***************************************** ctx1.lineWidth = "1"; ctx1.strokeStyle = "#ff0000"; ctx1.clearRect(0, 0, canvas1.width, canvas1.height); // clear the canvas ctx1.beginPath(); // to start drawing new line y1.splice(0, 1); // on the position 0 in the field y1 we erase one value y1[199] = potValue1; // new value is added at the end for (var i=0; i<200; i++) { ctx1.lineTo(x1[i], (100 - (y1[i] / 1023) * 100)); // 0,0 x,y coordinate is in upper left corner }; ctx1.stroke(); // to draw the line // End of draw graph***********************************var http = require("http").createServer(handler); // on req - handvar fs = require("fs"); // variable for file system for providing htmlvar firmata = require("firmata");const WebSocket = require('ws'); // for permanent connection between server and clientconst wss = new WebSocket.Server({port: 8888}); // websocket port is 8888wss.broadcast = function broadcast(data) { wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(data); } });};wss.sendToLastWs = function sendToLastWs(data) { if (wss.clients[wss.clients.length-1] !== undefined) { // if websocket exist if (wss.clients[wss.clients.length-1].readyState === WebSocket.OPEN) { // if it is connected wss.clients[wss.clients.length-1].send(data); // send to the last connected client - to only one client's websocket } }};var messageJSON;console.log("Starting the code");var board = new firmata.Board("/dev/ttyACM0", function(){ console.log("Connecting to Arduino"); console.log("Enabling analog Pin 0"); board.pinMode(0, board.MODES.ANALOG); // analog pin 0});function handler(req, res) { fs.readFile(__dirname + "/example10b.html", function (err, data) { if (err) { res.writeHead(500, {"Content-Type": "text/plain"}); return res.end("Error loading html page."); } res.writeHead(200); res.end(data); })}var desiredValue = 0; // desired value varhttp.listen(8080); // server will listen on port 8080board.on("ready", function() { board.analogRead(0, function(value){ desiredValue = value; // continuous read of analog pin 0 }); wss.on('connection', function (ws, req) { // start of wss code messageJSON = {"type": "message", "content": "Srv connected, board OK"}; ws.send(JSON.stringify(messageJSON)); //console.log(wss.clients[1]); setInterval(sendValues, 40); // on 40ms we send message to client }); // end of sockets.on connection}); // end of board.on(ready)function sendValues () { //wss.sendToLastWs(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue})); wss.broadcast(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue}));};<!DOCTYPE html><meta charset = utf8><html><head><title>Example with potentiometer</title></head> <body onload="load()";> <div><canvas id="canvas1" width ="200" height = "100" style="border: 1px dashed #00c3c3;"></canvas> </div> <div id="print1"></div> <br> <script type="text/javascript"> "use strict"; // in order to use clasess var divElement = document.getElementById("print1"); // var for div el.var numberOfLinesBeforeScroll = 10;var linesPrintCounter = 0; var potValue1 = 0; // value of the first potentiometervar x1 = new Array(); // array for x1var y1 = new Array(); // array for y1var canvas1;var ctx1; function log(msg) { var node=document.createElement("tr"); // we create the variable node as the a table row (tr) var textnode=document.createTextNode(linesPrintCounter + " | " + msg); // we create element with the text adding the counter node.appendChild(textnode); // adding text to "node", i.e. table row divElement.insertBefore(node, divElement.childNodes[0]); // inserting into variable node if (linesPrintCounter > numberOfLinesBeforeScroll-1) { // if the lines are more than limit -> start with scroll divElement.removeChild(divElement.childNodes[numberOfLinesBeforeScroll]); // we remove the oldest printout } linesPrintCounter++; // increasing the number of printouts} let ws = new WebSocket("ws://192.168.254.149:8888"); // create socket - connect to itvar messageJSON;function load() { // function that is started, when we open the page canvas1 = document.getElementById("canvas1"); ctx1 = canvas1.getContext("2d"); // initialization of graph with points ctx1.lineWidth = "1"; ctx1.strokeStyle = "#ff0000"; // draw first time series initialization for (var i=0; i<200; i++) { x1[i] = i; // for x values are 0, 1, 2, ... y1[i] = 0; // for y values are 0 };};ws.onmessage = function(event) { var msg = JSON.parse(event.data); // string from ws is put to JSON switch(msg.type) { case "message": log(msg.content); // add msg to div break; case "clientReadValues": potValue1 = msg.desiredValue; // Draw graph ***************************************** ctx1.lineWidth = "1"; ctx1.strokeStyle = "#ff0000"; ctx1.clearRect(0, 0, canvas1.width, canvas1.height); // clear the canvas ctx1.beginPath(); // to start drawing new line y1.splice(0, 1); // on the position 0 in the field y1 we erase one value y1[199] = potValue1; // new value is added at the end for (var i=0; i<200; i++) { ctx1.lineTo(x1[i], (100 - (y1[i] / 1023) * 100)); // 0,0 x,y coordinate is in upper left corner }; ctx1.stroke(); // to draw the line // End of draw graph*********************************** log(msg.desiredValue); // add msg with value to div break; }}; </script></body></html>As the result, we should get plotted graph as well as logged value: