0

我从一个从设备得到这个代码

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 的补码,所有零都被添加以完成字符,因为最左边的位读入为 1。无论如何,第 4 和第 5 个数字不是 2000 和 5000,而是数字与此大不相同。如何让附加的 1 消失,以便阅读 2000 和 5000?谢谢

4

1 回答 1

1

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

要解决此问题,您需要将缓冲区数组的类型更改为int[]。就是这样:

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

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

现在类型不同了,你必须添加一个类型转换,因为Serial.write需要一个charorbyte数组。

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

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

int protocol[5];

然后,Serial.readBytes还需要一个字节数组,因此您需要另一个强制转换(并sizeof获得要读取的正确字节数):

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

编辑:为了解释(char *)从属中的强制转换是如何工作的以及为什么它是必要的,请记住这是 C++,所以(就像在 C 中一样)数组在内部几乎是一个指针。因此,当您创建五个ints 的数组时,真正发生的事情是您保留了 10 个字节的内存(足够五个 16 位ints)并收到指向它开头的指针。现在,除非另有说明,否则 C++ 会将该内存视为 5 个ints。char但是,如果您告诉它,它非常乐意将其视为 10秒。这非常方便,因为Serial.write它只需要一个chars 数组(你记得,它就像一个char指针,因此是char *)。这将正常工作,因为它将跨行发送 10 个字节作为chars,监听器会将相同的 10 个字节放入protocol数组中。然后,使用 10 字节内存块的精确副本,该protocol数组将具有与从站中int的数组相同的 s buf

最后一条评论:您可能希望让您的侦听器等到实际有sizeof(protocol)可用字节后再尝试读取。否则,如果只有部分数据准备好,它会继续尝试读取,但Serial.readBytes通常只等待剩余数据的一小段时间,然后放弃并让缓冲区未填充。您可以通过添加>= sizeof(protocol)到相应的行来解决此问题:

if(Serial.available() >= sizeof(protocol)) {
于 2013-04-24T00:49:54.210 回答