Отображение данных нескольких датчиков с последовательного порта с помощью javascript и socket.io - PullRequest
0 голосов
/ 25 сентября 2018

Я новичок в Node.JS и Arduino.У меня есть установка Arduino с датчиками температуры на нем.Я читаю значения температуры с Arduino.Вывод моего последовательного монитора выглядит следующим образом:

serial Monitor:

0.05
0.10
0.15
0.20
0.25
0.30
0.34

Я отправляю данные из Arduino на мой терминал с помощью serialport, затем отображаю данные на веб-браузере в диаграммеформа.Я использую экспресс и socket.io.здесь связь с arduino и браузером с index.js.И 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", () => { //Start the server, listening on port 4000.
        console.log("Listening to requests on port 4000...");
    })

    var io = require('socket.io')(server); //Bind socket.io to our express server.

    app.use(express.static('public')); //Send index.html page on GET /

    const SerialPort = require('serialport');
    const Readline = SerialPort.parsers.Readline;
    const port = new SerialPort('/dev/ttyUSB0'); //Connect serial port to port COM3. Because my Arduino Board is connected on port COM3. See yours on Arduino IDE -> Tools -> Port
    const parser = port.pipe(new Readline({delimiter: '\r\n'})); //Read the line only when new line comes.
    parser.on('data', (temp) => { //Read data
        console.log(temp);
        var today = new Date();
        io.sockets.emit('temp', {date: today.getDate()+"-"+today.getMonth()+1+"-"+today.getFullYear(), time: (today.getHours())+":"+(today.getMinutes()), temp:temp}); //emit the datd i.e. {date, time, temp} to all the connected clients.
    });

    io.on('connection', (socket) => {
        console.log("Someone connected."); //show a log as a new client connects.
    })

Данные о температуре, полученные из серийного порта Arduino, отображаются в index.html (веб-браузер).

index.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, а в браузере консоли также отображаются только те же данные, что и на последовательном мониторе.

последовательный монитор с двумя датчиками температуры (результаты считывания между датчиками температуры между собой разделены пробелами)

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;
      }  
    }

1 Ответ

0 голосов
/ 25 сентября 2018

В основном есть 2 вопроса.

  1. Как отформатировать данные и использовать сервер express и отправить их на внешний интерфейс
  2. Как отобразить большечем один набор данных в графике, используя 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]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...