2

我正在使用 node.js 的serialport2库从 arduino 接收串行数据。这就像一个魅力,但时不时地运行 pc 节点,由于EMI决定停用 USB 端口。尽管端口会立即再次激活,但串行端口会断开连接。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相当陌生,所以这很可能是一个菜鸟错误。我究竟做错了什么?有人可以指出我正确的方向吗?

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

谢谢

4

4 回答 4

4

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

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

  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(); }
  }
于 2019-08-09T15:57:21.287 回答
2

感谢您的回答。我能弄明白。

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')我想这(重新)吸引了听众,所以他们不会在事件中迷路。

于 2013-09-14T15:09:16.800 回答
0
  • 您不应该.on在打开连接之前注册该功能吗?

  • 似乎有一个模块babysitter

于 2013-08-31T18:14:48.380 回答
0

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

于 2013-09-01T13:57:28.730 回答