我有来自从设备的代码
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?感谢
答案 0 :(得分:1)
这里的问题是您将每个数字存储和传输为8位值,这个值不足以存储数字2000或5000.
要解决此问题,您需要将缓冲区数组的类型更改为int[
]。方法如下:
在奴隶中,您需要更改声明缓冲区的行:
int buf[] = {125, 126, 127, 2000, 5000};
现在类型不同,您必须添加类型转换,因为Serial.write
需要char
或byte
数组。
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}}