node.js串行端口事件在重新连接到端口后停止工作

node.js serialport events stop working after reconnecting to port

本文关键字:停止工作 重新连接 js 串行端口 事件 node      更新时间:2023-09-26

我正在使用node.js的serialport2库从arduino接收串行数据。这很有魅力,但由于EMI,电脑运行节点不时决定停用usb端口。尽管端口立即再次激活,但Serialport会断开连接。Node.js仍在运行,但从未恢复到arduino的串行连接。

使用串行端口的"关闭"事件,我希望节点在短时间延迟后重新连接到串行端口。到目前为止,这很好:

var SerialPort  = require('serialport2').SerialPort;
var arduinoPort = '/dev/arduino';
// setting up the serial connection
var arduinoSerial = new SerialPort();
var connectArd = function() {
  arduinoSerial.open(arduinoPort, {
    baudRate: 9600,
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false
  });
}
connectArd();
// do something with incoming data
arduinoSerial.on('data', function (data) {
  .
  .
  .
});
// check for connection errors or drops and reconnect
var reconnectArd = function () {
  console.log('INITIATING RECONNECT');
  setTimeout(function(){
    console.log('RECONNECTING TO ARDUINO');
    connectArd();
  }, 2000);
};
arduinoSerial.on('close', function(){
  console.log('ARDUINO PORT CLOSED');
  reconnectArd();
});
arduinoSerial.on('error', function (err) {
  console.error("error", err);
  reconnectArd();
});

一旦出现EMI或USB电缆断开,"arduinoSerial"的"关闭"侦听器就会启动,等待约2秒,然后重新连接到arduino。连接被恢复,节点再次从arduino接收数据。

但是。。。这只管用一次当出现第二次断开连接时,节点会停止接收数据,但由于某种原因,这次不会触发"关闭"事件。我必须重新启动节点应用程序才能再次连接到arduino。

我是javascript的新手,所以这很可能是一个新手错误。我做错了什么?有人能告诉我正确的方向吗?

(我知道我应该开始寻找干扰源,但由于设备的可用性/处理原因,这种自动重新连接功能也会派上用场。)

感谢

这些旧帖子出现在我的谷歌搜索中对我来说仍然很疯狂,但我想我最好在这里为其他时间旅行者发布一个答案。

接受的答案的问题是,您可能会超过Node设置的最大事件侦听器,因为您每次都要重新定义它们。您可以简单地使用最新版本的Node SerialPort 7.x.x调用open()方法。下面是我测试并确认的一些示例代码。我怀疑这个.connected是必要的,因为SerialPort上可能有一个访问方法,但我只是用它来进行故障排除。我也将这个类用作super,所以其中有一些其他逻辑用于处理不同类型的解析器,所以您也可以忽略它。

  connect() {
    return new Promise((resolve) => {
      this.serialPort = new SerialPort(this.port, { baudRate: this.baudRate, autoOpen: false });
      this.parser = this.serialPort.pipe(this.parser);
      this.serialPort.on('open', () => {
        this.connected = true;
      });
      this.serialPort.on('close', () => {
        this.connected = false;
        setTimeout(this.reconnect.bind(this), 5000);
      });
      this.serialPort.on('error', () => {
        setTimeout(this.reconnect.bind(this), 5000);
      });
      this.serialPort.open();
      resolve(this.parser);
    });
  }
  reconnect() {
    if (!this.connected) { this.serialPort.open(); }
  }

感谢您的回答。我可以弄清楚的。

var SerialPort  = require('serialport2').SerialPort;
var arduinoPort = '/dev/arduino';
// setting up the serial connection
var connectArd = function() {
  var arduinoSerial = new SerialPort();
  arduinoSerial.open(arduinoPort, {
    baudRate: 9600,
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false
  });
  // do something with incoming data
  arduinoSerial.on('data', function (data) {
  .
  .
  .
  });
  arduinoSerial.on('close', function(){
    console.log('ARDUINO PORT CLOSED');
    reconnectArd();
  });
  arduinoSerial.on('error', function (err) {
    console.error("error", err);
    reconnectArd();
  });
}
connectArd();
// check for connection errors or drops and reconnect
var reconnectArd = function () {
  console.log('INITIATING RECONNECT');
  setTimeout(function(){
    console.log('RECONNECTING TO ARDUINO');
    connectArd();
  }, 2000);
};

我认为突破是在每次重新连接时都调用var arduinoSerial = new SerialPort();。我想这(再次)打动了听众,这样他们就不会在arduinoSerial.on('close')事件中迷路。

  • 您不应该在打开连接之前注册.on函数吗?

  • 这个babysitter 似乎有一个模块

您不应该使用serialport2,因为它已经被弃用一年多了。您应该使用节点串行端口,它的工作方式相同,可能会解决您的问题。