【问题标题】:Why isn't node SerialPort Readline parser working?为什么节点 SerialPort Readline 解析器不工作?
【发布时间】:2018-04-30 16:35:52
【问题描述】:

我有一个 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'));
        });

简而言之:我期待R1R2 消息始终如一地进来,而不是像这样分开:

Data: <Buffer 52> R
Data: <Buffer 31 0d 0a> 1

我将 ("\r\n" / 0x0d 0x0a) 传递给 Readline。我错过了什么? 如何在节点中使用 SerialPort 获得一致的新行解析?

【问题讨论】:

  • 我也是这么想的。我事先尝试了parser: new Readline("\n"),但似乎没有什么不同。我将其设置为\r\n,因为这是我在数据缓冲区节点看到的(0d 0a)出于某种原因
  • 嗯,可能是因为您在端口上附加了事件,而不是解析器?看例子:node-serialport.github.io/node-serialport/global.html#Parsers(这只是一个想法,我不确定这个,但是端口可能会接收块中的数据,而解析器尚未准备好或仍在等待数据)
  • @MatteoRagni 在解析器上添加“数据”侦听器有效。我想我可以通过在SerialPort 构造函数中指定解析器并直接在串行端口上侦听解析数据而摆脱困境。请在下面提供答案,以便标记。此外,如果您有任何建议来保持语法优雅,那就太棒了

标签: node.js arduino serial-port node-serialport


【解决方案1】:

我认为您的问题的解决方案需要在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 方法实际上写入了两个字节默认情况下。

【讨论】:

  • 我遇到了完全相同的问题。我一直在看在线文章和官方文档两个多小时,直到我找到你的答案。在我看到的所有地方,我都错过了他们在解析器上调用on("data") 函数的微小细节,而不是端口。我不确定我是该笑还是该哭。非常感谢!
猜你喜欢
  • 2016-09-18
  • 2015-10-11
  • 2017-02-27
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多