我正在尝试让我的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。任何帮助将不胜感激。
谢谢! 波比
答案 0 :(得分:2)
问题与Arduino&#34; AutoReset&#34;查看更多here。
我实际上并没有禁用自动复位...我继续执行上面发布的代码。我需要用户交互来触发SerialPort.write()。只要打开串行连接和第一次写入之间有几秒钟,这就可以工作。
答案 1 :(得分:1)
我的猜测是new Buffer('4','ascii')
正在执行ASCII字符串,而不是ASCII字符。不同之处在于,您没有使用循环发送4
或44444444…
,而是使用循环4\0
或4\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);
}
}
}