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

时间:2013-08-31 18:07:50

标签: javascript node.js events serial-port arduino

我正在使用node {j}的serialport2库来接收来自arduino的串行数据。这就像一个魅力,但不时的pc运行节点,决定停用由EMI引起的USB端口。尽管端口会立即再次激活,但Serialport会断开连接。 Node.js仍在运行,但从未恢复到arduino的串行连接。

使用Serialport的'closed'事件我希望节点在短暂延迟后重新连接到串行端口。到目前为止,这种方法很好:

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很新,所以这很可能是一个新手的错误。我究竟做错了什么?有人可以指出我正确的方向吗?

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

感谢

5 个答案:

答案 0 :(得分:1)

感谢您的回答。我能搞清楚。

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')事件中。

答案 1 :(得分:1)

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

接受的答案的问题是您可能会超过Node设置的最大事件侦听器,因为您每次都需要重新定义它们。使用Node SerialPort 7.x.x的最新版本,可以简单地执行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(); }
  }

答案 2 :(得分:0)

  • 在打开连接之前,您不应该注册.on功能吗?

  • babysitter

  • 似乎有一个模块

答案 3 :(得分:0)

您不应该使用serialport2,因为它已被弃用了一年多。您应该使用node serial port,它的工作方式相同,可以解决您的问题。

答案 4 :(得分:0)

  

在串行端口关闭事件中,您应该调用 arduinoSerial.resume()   serialport.io的方法。

  arduinoSerial.on('close', function(){
    console.log('ARDUINO PORT CLOSED');
    arduinoSerial.resume();
    reconnectArd();
  });