node.js - 使用 javascript 和 socket.io 从串口显示多个传感器数据
问题描述
我是 Node.JS 和 Arduino 的新手。我有一个带有温度传感器的 Arduino 设置。我正在用 Arduino 读取温度值。我的串行监视器输出如下:
串行监视器:
0.05 0.10 0.15 0.20 0.25 0.30 0.34
我使用串行端口将数据从 Arduino 发送到我的终端,然后以图表形式在我的网络浏览器上显示数据。我正在使用 express 和 socket.io。这是使用 index.js 与 arduino 和浏览器的连接。还有一个 index.html
index.js:
var express = require('express'); var app = express(); var http = require('http').Server(app); var server = http.listen(4000, "0.0.0.0", () => { //启动服务器,监听4000端口。 console.log("监听 4000 端口的请求..."); }) var io = require('socket.io')(server); //将socket.io绑定到我们的快递服务器。 app.use(express.static('public')); //在GET上发送index.html页面/ const SerialPort = 要求('serialport'); const Readline = SerialPort.parsers.Readline; const port = new SerialPort('/dev/ttyUSB0'); //将串口连接到端口COM3。因为我的 Arduino Board 连接在端口 COM3 上。在 Arduino IDE -> 工具 -> 端口上查看您的 const parser = port.pipe(new Readline({delimiter: '\r\n'})); //仅在新行到来时读取该行。 parser.on('data', (temp) => { //读取数据 控制台.log(临时); var 今天 = 新日期(); io.sockets.emit('temp', {日期: today.getDate()+"-"+today.getMonth()+1+"-"+today.getFullYear(), 时间: (today.getHours()) +":"+(today.getMinutes()), temp:temp}); //向所有连接的客户端发送 datd 即 {date, time, temp}。 }); io.on('连接', (socket) => { console.log("有人连接。"); //在新客户端连接时显示日志。 })
从串口接收温度数据 Arduino 显示在 index.html(网络浏览器)中。
索引.html:
<!DOCTYPE html>
<html>
<head>
<title>Temperature Plot</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Temperature Graph</h1>
<h4>Date: <span id="date"></span></h4>
<div class="chart-container" style="position: relative; width:75vw; margin: auto;">
<canvas id="myChart"></canvas>
</div>
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.3:4000'); //connect to server
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: [],
datasets: [{
label: "Temperature",
borderColor: "#FF5733",
data: [],
fill: false,
pointStyle: 'circle',
backgroundColor: '#3498DB',
pointRadius: 5,
pointHoverRadius: 7,
lineTension: 0,
}]
},
// Configuration options go here
options: {}
});
socket.on('temp', function(data) { //As a temp data is received
console.log(data.temp);
document.getElementById('date').innerHTML = data.date; //update the date
if(chart.data.labels.length != 15) { //If we have less than 15 data points in the graph
chart.data.labels.push(data.time); //Add time in x-asix
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data.temp); //Add temp in y-axis
});
}
else { //If there are already 15 data points in the graph.
chart.data.labels.shift(); //Remove first time data
chart.data.labels.push(data.time); //Insert latest time data
chart.data.datasets.forEach((dataset) => {
dataset.data.shift(); //Remove first temp data
dataset.data.push(data.temp); //Insert latest temp data
});
}
chart.update(); //Update the graph.
});
</script>
</body>
<style>
h1 {
text-align: center;
font-family: 'Lato', sans-serif;
}
h4 {
text-align: center;
font-family: 'Lato', sans-serif;
}
p {
text-align: center;
font-family: 'Lato', sans-serif;
}
</style>
</html>
如果 Arduino 上只有 1 个传感器温度,一切正常,但是当我添加另一个温度传感器时,串行监视器结果如下,使传感器数据无法以图表的形式出现在 index.html 中,并且控制台浏览器也只有显示与串行监视器相同的数据。
带有2个温度传感器的串行监视器(温度传感器之间的读数结果以空格分隔)
0.05 1.00
0.10 1.00
0.15 0.99
0.20 0.98
0.25 0.97
0.30 0.96
0.34 0.94
我已经尝试解决这个问题将近一个星期,我尝试了很多方法来解决这个问题,但没有奏效,我确实需要你的帮助
Arduino代码:
double x; //I simulate 2 temperature sensor values
void setup() {
Serial.begin(115200);
x = 0;
}
void loop() {
Serial.print(sin(x));
Serial.print(" ");
Serial.println(cos(x));
delay(50);
// seting batasan input fungsi sinus
x += 0.05;
if(x>= 2*3.14){
x = 0;
}
}
解决方案
里面基本上有2个问题。
- 如何格式化数据并使用
express
服务器发送到前端 - 如何使用 chart.js 在图表中显示多个数据集
第 1 名
代码中的行
...
const parser = port.pipe(new Readline({delimiter: '\r\n'}));
...
实际上捕获每一行数据。但是由于您从 arduino 的输出包含同一行中的数据,因此我们必须split()
在space
字符处使用它。因此,要获得array
多个温度值,您可以使用tempArray = temp.split(" ");
. 然后可以将该数组发送到前端。
第 2 名
获得温度值数组后,您可以使用将该数组本身发送到前端
// Notice I have replaced `temp` with `tempArray`
io.sockets.emit('temp', {date:today.getDate()+"-"+today.getMonth()+1+"-"+today.getFullYear(), time: (today.getHours())+":"+(today.getMinutes()), temp:tempArray}); });
在前端,dataset
对象中的Chart
是一个数组。如果您想在图表中添加多个数据集,只需添加一个数据集对象即可:
....
datasets: [{
label: "Sensor1",
borderColor: "#FF5733",
data: [],
fill: false,
pointStyle: 'circle',
backgroundColor: '#3498DB',
pointRadius: 5,
pointHoverRadius: 7,
lineTension: 0,
},
....
....
{
label: "Sensor2",
borderColor: "#FFFF33",
data: [],
fill: false,
pointStyle: 'circle',
backgroundColor: '#34FFDB',
pointRadius: 5,
pointHoverRadius: 7,
lineTension: 0,
},
]
....
现在,在里面socket.on('temp', function(data){...})
你可以像这样推送数据:
chart.dataset[i].data.push(data.temp[i]) // looping over i
编辑
要将数据放入数据集中,您可以使用“for”循环,如下所示:
for (var i = 0; i < datasets.length; i++) {
chart.datasets[i].data.push(data.temp[i]);
}
推荐阅读
- qt - 在 Qt 快速程序中从 gpsd 获取位置
- javascript - Node.js - 没有检测到相同的数据
- swift - SwiftUI - 我如何知道何时单击了导航视图的后退按钮?
- python - 我可以在 CircuitPython 中将 i2c LCD 的地址设置为 20 以外的地址吗?
- linux - 如何删除具有相同前缀的最旧的 n 组文件?
- ios - 如何在 Swift 中更改 UIDatePicker 的颜色?
- c# - 如何将包含特定变量的元素分成单独的列表?
- amazon-web-services - 如何在 Arduino、Web 应用程序和 AWS 之间进行通信?
- php - php foreach 外循环
- c# - 无法追踪“索引超出范围”异常的原因