为什么节点 SerialPort Readline 解析器不工作?
Why isn't node SerialPort Readline parser working?
我有一个 Arduino 发送非常基本的消息:
Serial.print('R');
Serial.println(1);
或
Serial.print('R');
Serial.println(2);
我正在尝试使用 node.js 和 SerialPort 模块读取每一行,但我得到的结果不一致:
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52> R
Data: <Buffer 31 0d 0a> 1
Data: <Buffer 52 32 0d 0a> R2
下面是我尝试解析的方式:
this.port = new SerialPort(portName, {
baudRate: baudRate,
autoOpen:false,
flowControl: false,
parser: new Readline("\r\n")
});
this.port.open(function (err) {
if (err) {
return console.log('Error opening port: ', err.message);
}
console.log("port open!");
});
this.port.on('error', function(err) {
console.log('Error: ', err.message);
})
this.port.on('open', function() {
console.log("open event called");
});
this.port.on('data', function (data) {
console.log('Data:', data,data.toString('utf8'));
});
简而言之:我希望 R1
、R2
消息始终如一地传入,而不是像这样分开:
Data: <Buffer 52> R
Data: <Buffer 31 0d 0a> 1
我将 ("\r\n"
/ 0x0d 0x0a
) 传递给 Readline
。我错过了什么?
如何在节点中使用 SerialPort 获得一致的新行解析?
我认为您的问题的解决方案需要在 parser
对象上绑定一个事件,而您当前正在 port
对象上侦听它。通过端口到达的数据并不总是以 0x0d 0x0a
(*) 结尾。这两个字节是仅用于 ReadLine
解析器的字符串终止符信号。
因此,也许您应该改为在代码中编写此侦听器:
// I'm not actually sure where parser lives, I'm not
// in the condition of trying by myself...
this.port.parser.on('data', function (data) {
console.log('Data:', data,data.toString('utf8'));
});
不幸的是,我没有任何使语法更优雅的建议,并且对于我的标准,此解决方案比创建一个为您重定向绑定的函数更优雅。不过,这取决于您的应用程序,目前我没有足够的信息来建议可能更好的解决方案。
(*) 在我立即删除的第一个(错误的)评论中,我问你为什么把两个字节作为终止行 0x0d 0x0a (\r\n)
,而不是简单的 0x0a (\n)
而是 Serial.println
方法实际上默认写入两个字节。
我有一个 Arduino 发送非常基本的消息:
Serial.print('R');
Serial.println(1);
或
Serial.print('R');
Serial.println(2);
我正在尝试使用 node.js 和 SerialPort 模块读取每一行,但我得到的结果不一致:
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52 31 0d 0a> R1
Data: <Buffer 52 32 0d 0a> R2
Data: <Buffer 52> R
Data: <Buffer 31 0d 0a> 1
Data: <Buffer 52 32 0d 0a> R2
下面是我尝试解析的方式:
this.port = new SerialPort(portName, {
baudRate: baudRate,
autoOpen:false,
flowControl: false,
parser: new Readline("\r\n")
});
this.port.open(function (err) {
if (err) {
return console.log('Error opening port: ', err.message);
}
console.log("port open!");
});
this.port.on('error', function(err) {
console.log('Error: ', err.message);
})
this.port.on('open', function() {
console.log("open event called");
});
this.port.on('data', function (data) {
console.log('Data:', data,data.toString('utf8'));
});
简而言之:我希望 R1
、R2
消息始终如一地传入,而不是像这样分开:
Data: <Buffer 52> R
Data: <Buffer 31 0d 0a> 1
我将 ("\r\n"
/ 0x0d 0x0a
) 传递给 Readline
。我错过了什么?
如何在节点中使用 SerialPort 获得一致的新行解析?
我认为您的问题的解决方案需要在 parser
对象上绑定一个事件,而您当前正在 port
对象上侦听它。通过端口到达的数据并不总是以 0x0d 0x0a
(*) 结尾。这两个字节是仅用于 ReadLine
解析器的字符串终止符信号。
因此,也许您应该改为在代码中编写此侦听器:
// I'm not actually sure where parser lives, I'm not
// in the condition of trying by myself...
this.port.parser.on('data', function (data) {
console.log('Data:', data,data.toString('utf8'));
});
不幸的是,我没有任何使语法更优雅的建议,并且对于我的标准,此解决方案比创建一个为您重定向绑定的函数更优雅。不过,这取决于您的应用程序,目前我没有足够的信息来建议可能更好的解决方案。
(*) 在我立即删除的第一个(错误的)评论中,我问你为什么把两个字节作为终止行 0x0d 0x0a (\r\n)
,而不是简单的 0x0a (\n)
而是 Serial.println
方法实际上默认写入两个字节。