I think I got it figured out from the github (https://github.com/voodootikigod/node-serialport page... basically it looks like I was missing the "open" event as shown below:

serialPort.on("open", function () {
  console.log("open");
  serialPort.on("data", function(data) {
    console.log("data received: " + data);
  });  
  serialPort.write("SYST:ADDR?\n", function(err, results) {
    console.log("err: " + err);
    console.log("results: " + results);
  });  
});
Answer from io2work on Stack Overflow
🌐
npm
npmjs.com › package › serialport
serialport - npm
Better yet, program them!. Latest version: 13.0.0, last published: a year ago. Start using serialport in your project by running `npm i serialport`. There are 5260 other projects in the ...
      » npm install serialport
    
Published   Dec 24, 2024
Version   13.0.0
Top answer
1 of 2
1

I think I got it figured out from the github (https://github.com/voodootikigod/node-serialport page... basically it looks like I was missing the "open" event as shown below:

serialPort.on("open", function () {
  console.log("open");
  serialPort.on("data", function(data) {
    console.log("data received: " + data);
  });  
  serialPort.write("SYST:ADDR?\n", function(err, results) {
    console.log("err: " + err);
    console.log("results: " + results);
  });  
});
2 of 2
1

Here is another approach which works very well and allows for dynamic addressing of a specific serial device. In my case I am only interested in connecting to the Numato device connected to our integrated system which is why I have the conditional logic in the list callback.

 exports.testSerial = function(data) {
    serialPort.list(function(err, ports) {

      var port = {};

      for(var i = 0; i < ports.length; i++) {
        try {
          if(typeof ports[i].manufacturer != 'undefined' && ports[i].manufacturer.includes("Numato")) {
            port = ports[i];
          }
        } catch(err) {
          console.dir(err);
        }
      }

      // the port will be opened via the constructor of this call
      var numato = new serial(port.comName, {baudrate : 19200}, function(err) {
        if(err) {
          return console.dir(err);
        }

        // by having the write call within the callback you can access it directly w/o using .on()
        numato.write('relay ' + data.state + ' ' + data.channel + '\r', function(err) {
          if(err) {
            console.dir('error writing');
            console.dir(err);
          }
          console.dir('serial message written');
          numato.close();
        });
      });

      return true;

    });
 }

Hope this helps someone in the future! For reference this is with library version 4.0.7.

🌐
NYU ITP
itp.nyu.edu › physcomp › labs › labs-serial-communication › lab-serial-communication-with-node-js
Lab: Serial Communication with Node.js – ITP Physical Computing
There’s a library for node.js that allows you to communicate over your computer’s serial ports called serialport. If your computer’s connected to the internet, you can download install it automatically using npm.
🌐
Serialport
serialport.io › serialport usage
SerialPort Usage | Node SerialPort
November 8, 2024 - const { SerialPort } = require('serialport') const port = new SerialPort({ path: '/dev/tty-usbserial1', baudRate: 9600 }, function (err) { if (err) { return console.log('Error: ', err.message) } }) port.write('main screen turn on', function(err) { if (err) { return console.log('Error on write: ', err.message) } console.log('message written') })
🌐
Stack Overflow
stackoverflow.com › questions › 41026744 › read-serial-port-after-writing-using-node-js
Read Serial Port After Writing using Node.js - Stack Overflow
} }); port.write('#01VER\r', function(err) { if(err) console.log('Write error') else { // HOW TO READ RESPONSE FROM DEVICE? } }); }); ... I think this is a better way to do it. By function calling, first create your function of reading and writing: var serialport = require("serialport"); var SerialPort = serialport.SerialPort; var sp = new SerialPort("/dev/ttyACM0", { baudrate: 9600, parser: serialport.parsers.readline("\n") }); function write() //for writing { sp.on('data', function (data) { sp.write("Write your data here"); }); } function read () // for reading { sp.on('data', function(data) { console.log(data); }); } sp.on('open', function() { // execute your functions write(); read(); });
🌐
Serialport
serialport.io
Home | Node SerialPort
Talk to your Serial devices with JavaScript · Nodebots uses SerialPort as the bridge between your javascript and the firmware on thousands of devices from Arduinos to drones
Find elsewhere
🌐
GitHub
github.com › DeekyJay › serialport
GitHub - DeekyJay/serialport: Node.js package to access serial ports for reading and writing. Welcome your robotic JavaScript overlords. Better yet, program them! · GitHub
Node.js package to access serial ports for reading and writing. Welcome your robotic JavaScript overlords. Better yet, program them! - DeekyJay/serialport
Author   DeekyJay
Top answer
1 of 2
2

I wrap a promise in the serial data receive

function sendSync(port, src) {
    return new Promise((resolve, reject) => {
        port.write(src);
        port.once('data', (data) => {
            resolve(data.toString());
        });

        port.once('error', (err) => {
            reject(err);
        });
    });
}

Please take note, the event is using once instead of on to prevent event from stacking (please check the comments below for more information - thanks @DKebler for spotting it)

Then, I could write the code in sync as below

sendSync(port, 'AThello\n').then((data) => {
    //receive data
});

sendSync(port, 'ATecho\n').then((data) => {
    //receive data
});

or I could use a generator, using co package

 co(function* () {
        const echo = yield sendSync(port, 'echo\n');
        const hello = yield sendSync(port, 'hello 123\n');

        return [echo, hello]
    }).then((result) => {
        console.log(result)
    }).catch((err) => {
        console.error(err);
    })
2 of 2
1

We have a similar problem in a project I'm working on. Needed a synchronous send/receive loop for serial, and the serialport package makes that kinda weird.

Our solution is to make some sort of queue of functions/promises/generators/etc (depends on your architecture) that the serial port "data" event services. Every time you write something, put a function/promise/etc into the queue.

Let's assume you're just throwing functions into the queue. When the "data" event is fired, it sends the currently aggregated receive buffer as a parameter into the first element of the queue, which can see if it contains all of the data it needs, and if so, does something with it, and removes itself from the queue somehow.

This allows you to handle multiple different kinds of architecture (callback/promise/coroutine/etc) with the same basic mechanism.

As an added bonus: If you have full control of both sides of the protocol, you can add a "\n" to the end of those strings and then use serialport's "readline" parser, so you'll only get data events on whole strings. Might make things a bit easier than constantly checking input validity if it comes in pieces.

Update:

And now that code has been finished and tested (see the ET312 module in http://github.com/metafetish/buttshock-js), here's how I do it:

function writeAndExpect(data, length) {
  return new Promise((resolve, reject) => {
    const buffer = new Buffer(length);
    this._port.write(data, (error) => {
      if (error) {
        reject(error);
        return;
      }
    });
    let offset = 0;
    let handler = (d) => {
      try {
        Uint8Array.from(d).forEach(byte => buffer.writeUInt8(byte, offset));
        offset += d.length;
      } catch (err) {
        reject(err);
        return;
      }
      if (offset === length) {
        resolve(buffer);
        this._port.removeListener("data", handler);
      };
    };
    this._port.on("data", handler);
  });
}

The above function takes a list of uint8s, and an expected amount of data to get back, returns a promise. We write the data, and then set ourselves up as the "data" event handler. We use that to read until we get the amount of data we expect, then resolve the promise, remove ourselves as a "data" listener (this is important, otherwise you'll stack handlers!), and finish.

This code is very specific to my needs, and won't handle cases other than very strict send/receive pairs with known parameters, but it might give you an idea to start with.

Top answer
1 of 2
4

I figured it out. I put a serial port monitoring application on to see what was happening.

The final answer was

A. When using an array or buffer to pass to the .write() method, it needs to be either a decimal character code (ie. 30 for "0" or 13 for carriage return) or a hex code (ie. 0x30 for "0" or 0x0D for carriage return) for each item in the array. I didn't try unicode or anything else. But see below my thoughts on that.

B. It turns out that in my example code

sp.on("open", function () {
    console.log(comPort + ' is open');
    sp.write(0x80);
    sp.write('123456\r');
});

I needed to be sending the 0x80 as a buffer/array instead. so sp.write([0x80]);, without it sent lots of 00 00 00...s However the LED display vendor's documentation was incorrect as it needed a \r\n at the end and not just a \r.

C. (a bit of a "duh" moment) was simply that Javascript will attempt to convert anything concatenated with a string to a string. So concatenating 0x80 + '123456\r' turns into '128123456\r'.

D. Passing unicode, like sp.write('\u0080') ends up outputing double characters, I'm assuming since unicode is 2 bytes per character, and the string is being treated/expecting single byte encoding. Javascript strings are UTF-16, so I'm guessing the node serialport module doesn't handle it since RS-232 uses 8 bits or less per character which falls into the typical ASCII char set.

2 of 2
0

I tested this on a console, not over a serial port, but I think it should work for you.

There are two options: 1) you can escape into Unicode or 2) you can use the String.fromCharCode function (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode)

Escaping into Unicode is pretty simple, just use \uXXXX where XXXX is the hex representation of your number

sp.write('\u0080123456\r');

Or you can use String.fromCharCode:

sp.write(String.fromCharCode(128) + '123456\r');
🌐
GitHub
github.com › serialport › node-serialport
GitHub - serialport/node-serialport: Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them! · GitHub
Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them! - serialport/node-serialport
Starred by 6K users
Forked by 1K users
Languages   TypeScript 85.8% | JavaScript 13.2%
🌐
Serialport
serialport.io › 📦 serialport
📦 serialport | Node SerialPort
November 8, 2024 - import { SerialPort } from 'serialport' const serialport = new SerialPort({ path: '/dev/example', baudRate: 9600 }) serialport.write('ROBOT POWER ON')
🌐
GitHub
github.com › serialport › node-serialport › issues › 1826
SerialPort write not working · Issue #1826 · serialport/node-serialport
Data rate: ${port.baudRate}`)); port.write('0\n', (err) => { if (err) return console.log('Error on write: ', err.message); console.log('message written') });``` // Code ```void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); } void loop() { if(Serial.available()){ switch(Serial.read()){ case '0': digitalWrite(LED_BUILTIN, LOW); break; case '1': digitalWrite(LED_BUILTIN, HIGH); break; default: break; } } }``` - SerialPort@ 7.1.4 - Node.js 10.4.2 - Windows - Hardware and chipset Arduino Mega 2560
Author   serialport
🌐
Stack Overflow
stackoverflow.com › questions › 63253111 › sending-bytes-with-serialport-nodejs
node.js - Sending bytes with SerialPort Nodejs - Stack Overflow
August 4, 2020 - const SerialPort = require("serialport"); var port = new SerialPort( "COM4", { baudRate: 2400, databits: 8, parity: "none", }, false ); command = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13]; for (var i = 0; i < command.length; i++) { port.write(command[i], function (err) { if (err) { return console.log("Error on write: ", err.message); } console.log(`Sent ${command[i]}`); }); } port.on("data", (line) => console.log(line));
🌐
Bhuvaneswaran
bhuvaneswaran.com › articles › serial-port-communication-with-node
Serial communication with Node.js - Bhuvaneswaran Balasubramanian
December 1, 2021 - var SerialPort = require("serialport"); var port = "COM1"; var message = "Hakuna Matata"; var serialPort = new SerialPort(port, { baudRate: 9600 }); serialPort.write(message, function(err) { if (err) { return console.log("Error on write: ", err.message); } console.log("Message sent successfully"); });
🌐
Microcontrollerelectronics
microcontrollerelectronics.com › connecting-a-serial-port-to-the-web-via-node-js
Connecting a serial port to the WEB via Node.js – MicroController Electronics
February 7, 2021 - /* Node.js Serial Port Data to Web From: earl@microcontrollerelectronics.com */ var serport = ""; var rate = 115200; var serports = []; var fs = require('fs'); const SerialPort = require('serialport'); var express = require('express'), app = express(), server = require('http').Server(app), io = require('socket.io')(server), port = 8888; server.listen(port, () => console.log('Server Listening on port' + port)) //app.use(express.static(__dirname)); app.get('*', function(req, res){ fs.readFile(__dirname + '/index.html','utf8', function (err, data) { if (err) { res.writeHead(500); return res.end('
🌐
GitHub
github.com › serialport › node-serialport › issues › 267
serialPort.write("data\n") results in 4 and doesn't work · Issue #267 · serialport/node-serialport
November 27, 2013 - var SerialPort = require("serialport").SerialPort var serialPort = new SerialPort("/dev/ttyACM0", { baudrate: 9600 }); serialPort.on("open", function () { console.log('open'); serialPort.write("255\n") }); Below is my Arduino code: int value ...
Author   serialport
🌐
Medium
medium.com › @machadogj › arduino-and-node-js-via-serial-port-bcf9691fab6a
Arduino and Node.js via Serial port | by Gustavo Machado | Medium
September 19, 2018 - const SerialPort = require('serialport'); const Readline = require('@serialport/parser-readline');const port = new SerialPort('/dev/ttyACM0', { baudRate: 9600 }); const parser = port.pipe(new Readline({ delimiter: '\n' }));// Read the port data ...
🌐
Medium
medium.com › @pkl9231 › serial-communication-between-node-js-and-arduno-read-and-write-data-2a712e07d337
Serial Communication between node js and Arduino (read and write data) | by Purushotam Kumar | Medium
December 11, 2021 - const SerialPort = require('serialport'); const Readline = require('@serialport/parser-readline');const port = new SerialPort('/dev/ttyACM0', { baudRate: 9600 }); const parser = port.pipe(new Readline({ delimiter: '\n' }));// Read the port data ...