Node.js SerialPort Arduino时序问题

时间:2014-04-01 21:22:53

标签: node.js serial-port arduino

我正在尝试让我的Raspberry Pi / Node.js使用node-serialport与Arduino Uno进行通信。我遇到以下代码块时出现问题:

Raspberry Pi

var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort("/dev/ttyACM0", {
  baudrate: 9600
});

serialPort.on("open", function () {
  console.log('open');

  serialPort.on('data', function(data) {
    console.log('data received: ' + data);
  });

  serialPort.write(new Buffer('4','ascii'), function(err, results) {
    console.log('err ' + err);
    console.log('results ' + results);
  });
});

Arduino的

// LED on pin 12
int led = 12;

// Incoming serial data
int data=0;

void setup() {                
  // Pin 12 set to OUTPUT
  pinMode(led, OUTPUT);

  // Start listening on the serialport
  Serial.begin(9600);
}

void loop() {

  if(Serial.available()>0){

      // Read from serialport
      data = Serial.read();      

      // Check and see if data received == 4
      if(data=='4') {   
        // Blink the LED 3 times
        for(int i=0;i<3;i++){
            digitalWrite(led, HIGH);
            delay(1000);
            digitalWrite(led,LOW);
            delay(1000);
        }

       // Reset data to 0
       data=0;
     }
  }
}

如果我在serialPort.write()函数周围换一个for循环,我只能让Arduino闪烁LED。在第40次循环迭代时,LED最终开始闪烁并继续闪烁,直到serialPort.write()循环结束。这让我相信我遇到了某种时间问题。我正在寻找一种更加优雅(和非阻塞)的解决方案,通过Pi闪烁Arduino上的LED。任何帮助将不胜感激。

谢谢! 波比

2 个答案:

答案 0 :(得分:2)

问题与Arduino&#34; AutoReset&#34;查看更多here

我实际上并没有禁用自动复位...我继续执行上面发布的代码。我需要用户交互来触发SerialPort.write()。只要打开串行连接和第一次写入之间有几秒钟,这就可以工作。

答案 1 :(得分:1)

我的猜测是new Buffer('4','ascii')正在执行ASCII字符串,而不是ASCII字符。不同之处在于,您没有使用循环发送444444444…,而是使用循环4\04\04\04\04\04\04\04\0…

所以当你执行Serial.available()时,它返回2,因为它有两个字节缓冲,但你只读了一个字节。由于Arduino的缓冲区是一个循环缓冲区,随着时间的推移被新数据覆盖,可能发生的是你只读\0 s,直到时间推移,你只能读取4秒。

我的建议是读取缓冲区中的字符数,或者简单地丢弃无效读取,因为当缓冲区为空时Serial.read()返回-1

const int led=12;

void setup() {                
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Read from serialport
  int data = Serial.read();

  // Check and see if data received == 4
  // and thus discard data==-1 or data==`\0`
  if(data=='4') {   
    // Blink the LED 3 times
    for(int i=0;i<3;i++){
        digitalWrite(led, HIGH);
        delay(1000);
        digitalWrite(led,LOW);
        delay(1000);
    }
  }
}