在节点串行端口中发送消息并等待响应

问题描述

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
// And your other imports...

@Controller
@RequestMapping("/main")
public class SignInPageController {

    private UserDao userDao;

    @Autowired
    public SignInPageController(UserDao userDao){this.userDao = userDao;}

    @GetMapping("/menu")
    public String mainMenuPage(){
        return "main/menu";
    }

    @GetMapping("/signup")
    public String signUpPage(Model model){
        model.addAttribute("newuser",new User());
        return "main/signup";
    }

    @PostMapping("/signup")
    public String signUp(@RequestParam("name") String name,@RequestParam("password") String password,@RequestParam("email") String email,@RequestParam("nativeLanguage") String nativeLanguage){
        User user = new User(name,password,email,nativeLanguage);
        userDao.signUpUser(user);
        return "redirect:/main/menu";
    }
}

我的目的是获得以下输出

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

之所以会这样,是因为接收是异步的/事件驱动的,因此在接收到第一个Rx消息之前就发送了第二个Tx消息。

我正在寻找的是这个

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

我在npm(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); } node-byline以及本地linebyline模块)上寻找了一些“ readliney”软件包,但它们似乎都依赖于{{1} }事件,那不是我想要的(serialport-readline解析器已经做到了)。

是否有与Stream api兼容的功能允许我执行此操作?

解决方法

您似乎可以轮询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