4

Does anyone have any example code to use the node.js serialport module in a blocking/synchronous way?

What I am trying to do is send a command to a micro-controller and wait for the response before sending the next command.

I have the sending/receiving working but the data just comes in with the listener

serial.on( "data", function( data) {
        console.log(data);
    }); 

Is there a way to wait for the returned data after doing a

serial.write("Send Command");

Should I be setting a global flag or something?

I am still new to the async programming style of node.js

Thanks

2 Answers 2

3

There is no such option and it's actually not necessary. One way of doing this is to maintain a queue of commands. Something like this:

function Device (serial) {
    this._serial = serial;
    this._queue = queue;
    this._busy = false;
    this._current = null;
    var device = this;
    serial.on('data', function (data) {
        if (!device._current) return;
        device._current[1](null, data);
        device.processQueue();
    });
}

Device.prototype.send = function (data, callback) {
    this._queue.push([data, callback]);
    if (this._busy) return;
    this._busy = true;
    this.processQueue();
};

Device.prototype.processQueue = function () {
    var next = this._queue.shift();

    if (!next) {
        this._busy = false;
        return;
    }

    this._current = next;
    this._serial.write(next[0]);
};
Sign up to request clarification or add additional context in comments.

Comments

0

This can now be done using the serialport-synchronous library in npm.

Consider the following serial port flow:

1. << READY
2. >> getTemp
3. << Received: getTemp
4. << Temp: 23.11

We can get the temperature value with the following code:

import { SerialPortController } from 'serialport-synchronous'

const TEMP_REGEX = /^Temp: (\d+\.\d+)$/
const ERROR_REGEX = /^ERROR$/
const READY_REGEX = /^READY$/

const controller = new SerialPortController({
  path: '/dev/ttyUSB0',
  baudRate: 19200,
  handlers: [{
    pattern: READY_REGEX,
    callback: main // call the main() function when READY_REGEX has matched.
  }]
})

// push the log events from the library to the console
controller.on('log', (log) => console[log.level.toLowerCase()](`${log.datetime.toISOString()} [${log.level.toUpperCase()}] ${log.message}`))

// open the serial port connection
controller.open()

async function main () {
  try {
    // send the getTemp text to the serialport
    const result = await controller.execute({
      description: 'Querying current temperature', // optional, used for logging purposes
      text: 'getTemp',                             // mandatory, the text to send
      successRegex: TEMP_REGEX,                    // mandatory, the regex required to resolve the promise
      bufferRegex: TEMP_REGEX,                     // optional, the regex match required to buffer the response
      errorRegex: ERROR_REGEX,                     // optional, the regex match required to reject the promise
      timeoutMs: 1000                              // mandatory, the maximum time to wait before rejecting the promise
    })
    
    // parse the response to extract the temp value
    const temp = result.match(TEMP_REGEX)[1]
    console.log(`\nThe temperature reading was ${temp}c`)
  } catch (error) {
    console.error('Error occured querying temperature')
    console.error(error)
  }
}

Output looks something like this:

2022-07-20T01:33:56.855Z [INFO] Connection to serial port '/dev/ttyUSB0' has been opened
2022-07-20T01:33:58.391Z [INFO] << READY
2022-07-20T01:33:58.392Z [INFO] Inbound message matched unsolicited handler pattern: /^READY$/. Calling custom handler function
2022-07-20T01:33:58.396Z [INFO] Querying current temperature
2022-07-20T01:33:58.397Z [INFO] >> [TEXT] getTemp
2022-07-20T01:33:58.415Z [INFO] << Received: getTemp
2022-07-20T01:33:58.423Z [INFO] << Temp: 23.11
2022-07-20T01:33:58.423Z [DEBUG] Received expected response, calling resolve handler

The temperature reading was 23.11c

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.