【问题标题】:Send message and wait for response in node serialport在节点串行端口中发送消息并等待响应
【发布时间】:2020-10-01 21:04:01
【问题描述】:

我有一个使用串行接口通过 USB 连接到计算机的设备。 我可以使用npm-serialport 与它正确“交谈”,代码如下:

const SerialPort = require('serialport');
const ReadLine = require('@serialport/parser-readline');

function handleResponse(data) {
  console.log('Rx', data);
  console.log();
}

SerialPort.list()
  .then(async portInfos => {
    portInfos.filter(pinfo => pinfo.manufacturer === 'FTDI')
      .forEach(async portInfo => {
        const port = new SerialPort(portInfo.path).setEncoding('ascii');

        const parser = port.pipe(new ReadLine({
          delimiter: '\r\n',
          encoding: 'ascii',
        }));
        parser.on('data', handleResponse);

        port.open();

        const serialMessage = api.createReadMessage(SERIAL);
        const batteryMessage = api.createReadMessage(BATTERY);

        for (const m of [serialMessage, batteryMessage]) {
          console.log('Tx', m.trim());
          port.write(m);
        }
      });
  });

我的意图是得到这个输出:

  Tx :0A0300070004E8
  Rx :0A030800000467000000017F
  
  Tx :0A03000B0002E6
  Rx :0A03040064006427

但是我得到了这个:

  Tx :0A0300070004E8
  Tx :0A03000B0002E6
  Rx :0A030800000467000000017F
  
  Rx :0A03040064006427

发生这种情况是因为第二个 Tx 消息是在接收到第一个 Rx 消息之前发送的,因为接收是异步/事件驱动的。

我要找的是这个:

function sendAndReceive(messageToSend, port) {
  port.write(messageToSend);
  const response = port.readLine(); // BLOCKING, PERHAPS WITH TIMEOUT EXCEPTION;
  return response;
}

for (const m of [serialMessage, batteryMessage]) {
  console.log('Tx', m.trim());
  const response = sendAndReceive(m);
  console.log(response);
}

我在 npm 上寻找了一些“readliney”包(node-bylinelinebyline,以及原生的readline 模块),但它们似乎都依赖于stream.on 事件,这不是我想要(serialport-readline 解析器已经做到了)。

是否有任何与 Stream api 兼容的函数允许我这样做?

【问题讨论】:

    标签: node.js readline node-streams node-serialport


    【解决方案1】:

    看起来你可以轮询SerialPort.read() 来实现blocking reads。这是一些未经测试的伪代码:

    function sendAndReceive(messageToSend, port) {
      port.write(messageToSend);
      let response = '';
      while(true) {
        response = port.read(); // BLOCKING, PERHAPS WITH TIMEOUT EXCEPTION;
        if(response != null) {
          break;
        }
        sleep(1000);
      }
      return response;
    }
    
    function sleep(ms) {
      return new Promise(resolve => {
        setTimeout(resolve, ms)
      })
    }
    

    受此问题启发:https://github.com/serialport/node-serialport/issues/1996

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 2023-03-07
      • 2017-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      相关资源
      最近更新 更多