我在尝试通过USB在teensy和Raspberry Pi3之间进行通信时遇到了一些麻烦。
当我发送unsigned int时,我收到包含值13的字节的所有数字的错误数字,这些数字被更改为值10
例如:
13 becomes 10;
269 becomes 266;
525 becomes 522;
781 becomes 778;
1037 1034;
1293 1290;
1549 1546;
1805 1802;
etc...
但不是其他人......
无论我在pi上使用我的程序,还是在/dev/ttyACMO
上发送cat命令。但是,当我在另一台计算机上执行相同操作时,一切正常。
我在另一台计算机上遇到了同样的问题,所以我认为问题来自我安装的坏库。
你有什么想法吗?
PS:青少年时代的代码很简单:
unsigned int i = 0;
while(true){
Serial.write((char*) &i, 4);
++i;
delay(500);
}
答案 0 :(得分:1)
ASCII十进制10是换行符(<LF>
)。 ASCII十进制13是回车(<LF>
)。
您很可能是隐式<CR><LF>
⇄<LF>
转换的胜利者; Wikipedia explains it in detail,但总而言之,它源于技术历史:
首次为计算机提供文本输入/输出功能时,这不是通过显示器完成的,而是通过电传打字完成的。电传打字机本质上是一台机械打字机,其中的每个“键”也可以被电信号击中。
打字机,因此可以区分电传打字,包括使纸张前进(换行)和使支架退回(从头开始)一行。
ASCII编码本质上是将打字机功能映射为二进制模式的1:1映射。
最终结果是,要在电传打字机上开始新行,您必须发送换行符(<LF>
)和回车符(<CR>
),两者的顺序并不重要,物理效果实际上是相同的。
但是,不同的操作系统采用了不同的 default 约定来存储和传输换行符:
MS-DOS并通过继承选择Windows以此顺序显式存储<CR>
和<LF>
。
Unix选择仅存储<LF>
并将其发送给电传打字机时转换为<CR><LF>
序列,反之亦然。 Linux采用了这种Unix约定。
在通过串行链路进行传输时,默认始终是默认值,对于换行符,应该传输(<CR>,<LF>)
对,以期望另一端是电传打字机。 这就是这里可能发生的事情!通过电线传输的实际数据是<CR><LF>
,但是继承了Unix方式的接收操作系统将其静默地将其转换为普通的<LF>
。对于大于255的任何数字,此转换将碰到它的低8个字节,并丢弃整个字节。
当然可以重新配置此默认行为,即通过打开的串行端口上的termios/ioctl_tty,特别是输出和输入选项标志(即标志OPOST
,ONLCR
,{{ 1}},ONLCR
,OCRNL
,ONLRET
,INLCR
,IGNCR
)。
但是,我强烈建议您不要摆弄这些标志,而要谨记以下两点:
纯文本是通用的交换格式! (例如,如果可以避免的话,请勿通过电线提交原始二进制文件,而应以易于阅读的方式发送) –文字)
在阅读所收到的内容时要放心; (即以某种方式编写程序,即读取数据不依赖于严格的数据顺序和格式,即可以容忍任何种类的换行序列或空格定界字段;而且还以严格的常规方式发送数据,以使不那么宽松的接收者不会感到窒息)