Arduino 2的补码读错误

时间:2013-04-23 23:46:44

标签: serial-port arduino

我有来自从设备的代码

byte buf[] = {125, 126, 127, 2000, 5000};

void setup() {
  // initialize serial:
  Serial.begin(9600);

}

void loop() {
  int i = Serial.write(buf, sizeof(buf));
  Serial.println(i);
  delay(5000);

}

我从听音设备获取此代码。

char protocol[5];
void setup() {
  Serial.begin(9600);
  memset(protocol, '\0', sizeof(protocol)); 
}


void loop() {
  if(Serial.available()) {
  Serial.readBytes(protocol, 5);
  Serial.println(protocol);
  for(int i = 0; i < sizeof(protocol); i ++ ) {
    Serial.println((int)protocol[i], BIN); 
  }
  }
  else{
   Serial.println("None available");
   delay(500); 
  }

}

据我所知,Arduino使用了2的赞美,但我得到的问题是打印出来的是

1111101
1111110
1111111
11111111111111111111111111010000
11111111111111111111111110001000

并且由于2的补码,所有零都被添加以完成char,因为最左边的位读入为1.无论如何,第4和第5个数字不是2000和5000但是数字与此大不相同。如何让附加的1离开,所以我读2000和5000?感谢

1 个答案:

答案 0 :(得分:1)

这里的问题是您将每个数字存储和传输为8位值,这个值不足以存储数字2000或5000.

要解决此问题,您需要将缓冲区数组的类型更改为int[]。方法如下:

在奴隶中,您需要更改声明缓冲区的行:

int buf[] = {125, 126, 127, 2000, 5000};

现在类型不同,您必须添加类型转换,因为Serial.write需要charbyte数组。

int i = Serial.write((char *) buf, sizeof(buf));

然后,您必须在侦听器设备中进行类似的更改。像这样声明你的protocol数组:

int protocol[5];

然后,Serial.readBytes也需要一个字节数组,所以你需要另一个强制转换(和sizeof来获取正确的字节数):

Serial.readBytes((byte *) protocol, sizeof(protocol));

编辑:要解释奴隶中的(char *)投射是如何工作的以及为什么必要,请记住这是C ++,所以(就像在C中一样)数组几乎就是一个指针内部。所以,当你创建五个int的数组时,真正发生的是你保留了10个字节的内存(足够5个16位int)并收到一个指向开始的指针它的。现在,除非另有说明,否则C ++会将该内存视为五个int。但是,如果你告诉它,它很高兴将其视为10 char s。这非常方便,因为Serial.write只会采用char个数组(正如您所记得的那样,它就像一个char指针,因此char *)。这样可以正常工作,因为它会将{10}字节作为char发送到整个行,其中侦听器将相同的10个字节放入protocol数组中。然后,使用10字节内存块的精确副本,protocol数组将与int数组中的buf数组具有相同的sizeof(protocol)

最后一条评论:在尝试阅读之前,您可能希望让您的侦听器等到实际有Serial.readBytes个字节可用。否则,如果只有部分数据准备就绪,它将继续尝试读取,但是>= sizeof(protocol)通常只在等待很短的时间才能放弃剩余数据,然后放弃缓冲区。您可以通过将if(Serial.available() >= sizeof(protocol)) { 添加到相应的行来解决此问题:

{{1}}