Home > Net >  Read Serial port data using node js
Read Serial port data using node js

Time:03-22

I want to read data from serial port and get from data when reqested

Here is my code

const http = require('http');
const hostname = 'localhost';
const { SerialPort } = require('serialport')
const { ReadlineParser } = require('@serialport/parser-readline')
const { io } = require('socket.io');
let express = require('express')

const serialPort = new SerialPort({ 
    path: 'COM4',
    baudRate: 9600 ,
})
const parser = serialPort.pipe(new ReadlineParser({ delimiter: '\r\n' }))
let app = express();
var port = 8080;

const server = http.createServer(app);

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
app.get('/get_data', function(req, res) {
    parser.on('data', function(data) {
        res.json({'weight': data});
    });
});

When i am try to get data i got ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client I want serial port data when requested from localhost:8080/get_data anyone can help ?

CodePudding user response:

Your data event from parser is probably firing more than once, which means you would be calling res.json more than once. As you can see in the express api documentation, res.json sets the content-type header...thus you can only call it once per request. Hence the error.

What I think would normally be done in this kind of situation is to set up a queuing system. A simple version might be done using an array, although if you were using this in a production server it might be better to use a proper message queuing system (e.g. rabbitMQ, kafka, AWS SQS, etc).

Here's an example of how you might use an array:

const queue = [];
parser.on('data', function(data) {
  // push new data onto end of queue (array)
  queue.push(data);
});
app.get('/get_data', function(req, res) {
  if (req.params.getFullQueue === 1) {
    // empty complete contents of current queue,
    // sent to client as an array of { weight: x } objects
    const data = queue.splice(0, queue.length)
      .map(x => ({ weight: x }));
    res.json(data);
  } else {
    // get oldest enqueued item, send it only
    res.json({ weight: queue.shift() });
  }
});

The if/else in the app.get is meant to illustrate these two options, depending on which you wanted to use. In production you'd probably want to implement pagination, or maybe even a websocket or EventSource so that data could be pushed as it became available.

  • Related