The following node.js script scans all ports for a custom FTDI device and once the device is found, it checks its serial number and temperature. console.log
shows:
Serial number: 1003
Temperature: 28
If I unplug the device I get the following error: Port closed: bad file descriptor
. When I re-plug the device I get some undefined behaviour. Sometimes I get the correct serial number but an incorrect temperature:
Serial number: 1003
Temperature: 0
Sometimes I get the reply unknown command
from the device (code is not shown in the snippet below). However if I debug the script in Visual Studio Code, set a breakpoint at ftdiPort = new serialPort(path, {baudRate: 115200});
and wait 4+ seconds to go on after reconnecting the device, I get the correct data.
Code:
'use strict';
const serialPort = require('serialport');
let ftdiPort;
searchFtdiPort();
//Check all ports every 1 second if device is connected
function searchFtdiPort() {
let checkPorts = setInterval(function() {
serialPort.list().then(ports => {
for(let i = 0; i < ports.length; i++) {
if(ports[i].manufacturer == 'FTDI') {
openFtdiPort(ports[i].path);
clearInterval(checkPorts);
break;
}
}
});
}, 1000);
}
//When device is connected, open port and ask for serial number and temperature
function openFtdiPort(path) {
ftdiPort = new serialPort(path, {baudRate: 115200});
let Readline = require('@serialport/parser-readline');
let parser = ftdiPort.pipe(new Readline({delimiter: '
'}));
ftdiPort.on('open', function() {
getSerial(path);
getTemperature(path);
});
ftdiPort.on('error', function(error) {
console.log('Port error: ', error.message);
});
ftdiPort.on('close', function(info) {
console.log('Port closed: ', info.message);
searchFtdiPort();
});
parser.on('data', function(data) {
parseFtdiData(data);
});
}
function parseFtdiData(data) {
let key = res[0];
let value = res[1];
switch(key) {
case 'serial':
console.log('Serial number:', value);
break;
case 'fmcw_temp':
console.log('Temperature:', value);
break;
default:
console.log('Key not specified.');
break;
}
}
function getSerial(path) {
let serialCmd = 'get_serial
';
ftdiPort.write(serialCmd, function(error) {
if(error) {
console.log('Writing on port failed: ', error.message);
return;
}
console.log('Write', serialCmd, 'on', path);
});
}
function getTemperature(path) {
let serialCmd = 'fmcw_temp
';
ftdiPort.write(serialCmd, function(error) {
if(error) {
console.log('Writing on port failed: ', error.message);
return;
}
console.log('Write', serialCmd, 'on', path);
});
}
DEBUG information on Linux (here I get unknown command
instead of temperature=0
for example):
user@linux-ayq9:~/Desktop/Service> DEBUG=* node test.js
serialport/bindings loading LinuxBinding +0ms
serialport/stream .list +0ms
serialport/stream opening path: /dev/ttyUSB0 +51ms
serialport/binding-abstract open +0ms
serialport/stream _read queueing _read for after open +1ms
serialport/bindings/poller Creating poller +0ms
serialport/stream opened path: /dev/ttyUSB0 +0ms
serialport/stream _write 11 bytes of data +1ms
serialport/binding-abstract write 11 bytes +2ms
serialport/stream _read reading { start: 0, toRead: 65536 } +0ms
serialport/binding-abstract read +1ms
serialport/bindings/unixWrite Starting write 11 bytes offset 0 bytesToWrite 11 +0ms
serialport/bindings/unixRead Starting read +0ms
serialport/bindings/unixWrite write returned: wrote 11 bytes +0ms
serialport/bindings/unixWrite Finished writing 11 bytes +1ms
serialport/stream binding.write write finished +2ms
serialport/stream _write 10 bytes of data +0ms
serialport/binding-abstract write 10 bytes +1ms
Write get_serial
on /dev/ttyUSB0
serialport/bindings/unixWrite Starting write 10 bytes offset 0 bytesToWrite 10 +0ms
serialport/bindings/unixRead read error { [Error: EAGAIN: resource temporarily unavailable, read] errno: -11, code: 'EAGAIN', syscall: 'read' } +1ms
serialport/bindings/unixRead waiting for readable because of code: EAGAIN +0ms
serialport/bindings/poller Polling for "readable" +3ms
serialport/bindings/unixWrite write returned: wrote 10 bytes +1ms
serialport/bindings/unixWrite Finished writing 10 bytes +0ms
serialport/stream binding.write write finished +1ms
Write fmcw_temp
on /dev/ttyUSB0
serialport/bindings/poller received "readable" +16ms
serialport/bindings/unixRead Starting read +16ms
serialport/bindings/unixRead Finished read 48 bytes +0ms
serialport/stream binding.read finished { bytesRead: 48 } +15ms
Serial number: 1003
Temperature: 28
serialport/stream _read reading { start: 48, toRead: 65488 } +0ms
serialport/binding-abstract read +16ms
serialport/bindings/unixRead Starting read +0ms
serialport/bindings/unixRead read error { [Error: EAGAIN: resource temporarily unavailable, read] errno: -11, code: 'EAGAIN', syscall: 'read' } +1ms
serialport/bindings/unixRead waiting for readable because of code: EAGAIN +0ms
serialport/bindings/poller Polling for "readable" +1ms
serialport/bindings/poller error [Error: bad file descriptor] +3s
serialport/stream binding.read error [Error: bad file descriptor] +3s
serialport/stream disconnected [Error: bad file descriptor] +0ms
serialport/stream #close +1ms
serialport/binding-abstract close +3s
serialport/stream _read queueing _read for after open +0ms
serialport/bindings/poller Stopping poller +2ms
serialport/bindings/poller Destroying poller +1ms
serialport/stream binding.close finished +1ms
Port closed: bad file descriptor
serialport/stream .list +1s
serialport/stream .list +1s
serialport/stream .list +1s
serialport/stream opening path: /dev/ttyUSB0 +44ms
serialport/binding-abstract open +3s
serialport/stream _read queueing _read for after open +0ms
serialport/bindings/poller Creating poller +3s
serialport/stream opened path: /dev/ttyUSB0 +2ms
serialport/stream _write 11 bytes of data +0ms
serialport/binding-abstract write 11 bytes +2ms
serialport/stream _read reading { start: 0, toRead: 65536 } +0ms
serialport/binding-abstract read +0ms
serialport/bindings/unixWrite Starting write 11 bytes offset 0 bytesToWrite 11 +6s
serialport/bindings/unixRead Starting read +6s
serialport/bindings/unixWrite write returned: wrote 11 bytes +0ms
serialport/bindings/unixWrite Finished writing 11 bytes +0ms
serialport/stream binding.write write finished +0ms
serialport/stream _write 10 bytes of data +0ms
serialport/binding-abstract write 10 bytes +0ms
Write get_serial
on /dev/ttyUSB0
serialport/bindings/unixWrite Starting write 10 bytes offset 0 bytesToWrite 10 +0ms
serialport/bindings/unixRead read error { [Error: EAGAIN: resource temporarily unavailable, read] errno: -11, code: 'EAGAIN', syscall: 'read' } +0ms
serialport/bindings/unixRead waiting for readable because of code: EAGAIN +1ms
serialport/bindings/poller Polling for "readable" +2ms
serialport/bindings/unixWrite write returned: wrote 10 bytes +1ms
serialport/bindings/unixWrite Finished writing 10 bytes +0ms
serialport/stream binding.write write finished +1ms
Write fmcw_temp
on /dev/ttyUSB0
serialport/bindings/poller received "readable" +21ms
serialport/bindings/unixRead Starting read +21ms
serialport/bindings/unixRead Finished read 71 bytes +0ms
serialport/stream binding.read finished { bytesRead: 71 } +22ms
Unknown command: get_serial
Unknown command: fmcw_temp
serialport/stream _read reading { start: 71, toRead: 65465 } +0ms
serialport/binding-abstract read +23ms
serialport/bindings/unixRead Starting read +1ms
serialport/bindings/unixRead read error { [Error: EAGAIN: resource temporarily unavailable, read] errno: -11, code: 'EAGAIN', syscall: 'read' } +0ms
serialport/bindings/unixRead waiting for readable because of code: EAGAIN +0ms
serialport/bindings/poller Polling for "readable" +1ms
So reinitialising the port after a connection loss seems to not working properly. I don't know if it's a general problem with node.js serialport, or if I am using the package incorrectly. Maybe it's something with my Linux distribution (it's openSuse 15.1 by the way).
I would be glad if someone could help me out here. Thank you.