In this example additional potentiometer will be added. The schematics is shown on the next figure:
The breadboard view (components should have similar positions):
We add additional variable:
var actualValue = 0; // variable for actual value (output value)
Reading additional analog pin:
console.log("Enabling analog Pin 1");
board.pinMode(1, board.MODES.ANALOG); // analog pin 1
Adding additional board.read for pin1:
board.analogRead(1, function(value) {
actualValue = value; // continuous read of pin A1
});
Function sendValue now sends to bits of data (desired and actual):
function sendValues () {
wss.broadcast(JSON.stringify({"type": "clientReadValues", "desiredValue": desiredValue, "actualValue": actualValue}));
};
Code diff between example10b.js and example11.js:
Code for the example11.js is printed in the following section.
var http = require("http").createServer(handler); // on req - hand
var fs = require("fs"); // variable for file system for providing html
var firmata = require("firmata");
const WebSocket = require('ws'); // for permanent connection between server and client
const wss = new WebSocket.Server({port: 8888}); // websocket port is 8888
wss.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
board.pinMode(1, board.MODES.ANALOG); // analog pin 1
});
function handler(req, res) {
fs.readFile(__dirname + "/example11.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 var
var actualValue = 0; // variable for actual value (output value)
http.listen(8080); // server will listen on port 8080
board.on("ready", function() {
board.analogRead(0, function(value){
desiredValue = value; // continuous read of analog pin 0
});
board.analogRead(1, function(value) {
actualValue = value; // continuous read of pin A1
});
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, "actualValue": actualValue}));
};
Changes in html file:
We add additional variable:
var potValue2 = 0; // value of second potentiometer
var x2 = new Array(); // array for x2 variable
var y2 = new Array(); // array for y2 variable
And initialize second graph within load() function:
// initializaion of second graph
for (var i=0; i<200; i++) {
x2[i] = i; // x2 values are 0, 1, 2, ...
y2[i] = 0; // for y2 values are 0
};
We have now two values within socket:
socket.on("clientReadValues", function(value){
s.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;
potValue2 = msg.actualValue;
...
We draw the second graph (only one clearRect is used!):
// Draw first graph *****************************************
ctx1.clearRect(0, 0, canvas1.width, canvas1.height); // clear the canvas
ctx1.lineWidth = "1";
ctx1.strokeStyle = "#ff0000";
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***********************************
// Draw second graph **********************************************
ctx1.lineWidth = "1";
ctx1.strokeStyle = "#00ff00";
ctx1.beginPath(); // to start drawing new line
y2.splice(0, 1); // on the position 0 in the field y2 we erase one value
y2[199] = potValue2; // new value is added at the end
for (i=0; i<200; i++) {
ctx1.lineTo(x2[i], (100 - (y2[i] / 1023) * 100)); // 0,0 x,y coordinate is in upper left corner
};
ctx1.stroke(); // to draw the line
// Draw second graph graph END ************************************
log(potValue1 + "|" + potValue2); // msg to log
Code diff between example10b.html and example11.html:
<!DOCTYPE html>
<meta charset = utf8>
<html>
<head>
<title>Example with potentiometers</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 potentiometer
var x1 = new Array(); // array for x1
var y1 = new Array(); // array for y1
var potValue2 = 0; // value of second potentiometer
var x2 = new Array(); // array for x2 variable
var y2 = new Array(); // array for y2 variable
var 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 it
var 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";
// initializaction of first time series
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
};
// initializaion of second graph
for (var i=0; i<200; i++) {
x2[i] = i; // x2 values are 0, 1, 2, ...
y2[i] = 0; // for y2 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;
potValue2 = msg.actualValue;
// Draw first graph *****************************************
ctx1.clearRect(0, 0, canvas1.width, canvas1.height); // clear the canvas
ctx1.lineWidth = "1";
ctx1.strokeStyle = "#ff0000";
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***********************************
// Draw second graph **********************************************
ctx1.lineWidth = "1";
ctx1.strokeStyle = "#00ff00";
ctx1.beginPath(); // to start drawing new line
y2.splice(0, 1); // on the position 0 in the field y2 we erase one value
y2[199] = potValue2; // new value is added at the end
for (i=0; i<200; i++) {
ctx1.lineTo(x2[i], (100 - (y2[i] / 1023) * 100)); // 0,0 x,y coordinate is in upper left corner
};
ctx1.stroke(); // to draw the line
// Draw second graph graph END ************************************
log(potValue1 + "|" + potValue2);
break;
}
};
</script>
</body>
</html>
The results are shown in the next figure: