【发布时间】:2021-01-12 14:23:06
【问题描述】:
以下 node.js 脚本扫描自定义 FTDI 设备的所有端口,一旦找到该设备,它会检查其序列号和温度。 console.log 显示:
Serial number: 1003
Temperature: 28
如果我拔下设备,我会收到以下错误:Port closed: bad file descriptor。当我重新插入设备时,我得到了一些未定义的行为。有时我得到正确的序列号但温度不正确:
Serial number: 1003
Temperature: 0
有时我会收到来自设备的回复unknown command(代码未显示在下面的 sn-p 中)。但是,如果我在 Visual Studio Code 中调试脚本,在 ftdiPort = new serialPort(path, {baudRate: 115200}); 处设置断点并在重新连接设备后等待 4 秒以上继续,我会得到正确的数据。
代码:
'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: '\n'}));
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\n';
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\n';
ftdiPort.write(serialCmd, function(error) {
if(error) {
console.log('Writing on port failed: ', error.message);
return;
}
console.log('Write', serialCmd, 'on', path);
});
}
Linux 上的调试信息(例如,我在这里得到的是 unknown command 而不是 temperature=0):
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
因此,在连接丢失后重新初始化端口似乎无法正常工作。我不知道这是否是 node.js 串行端口的一般问题,或者我是否错误地使用了该包。也许这与我的 Linux 发行版有关(顺便说一下,它是 openSuse 15.1)。 如果有人可以在这里帮助我,我会很高兴。谢谢。
【问题讨论】:
标签: node.js linux serial-port ftdi