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
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]);
};
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.