如何通过串口发送浮动

在Arduino上串行发送floatdoubleint16的最佳方法是什么?

Serial.print()仅以ASCII编码方式发送值。 但我想将值作为字节发送。 Serial.write()接受字节和字节Serial.write() ,但是将值转换为字节的最佳方法是什么?

我试图将int16转换为byte* ,没有运气。 我也使用了memcpy,但它使用了很多CPU周期。 Arduino使用普通的C / C ++。 这是一个ATmega328微控制器。

是的,要发送这些数字,您必须先将它们转换为ASCII字符串。 如果您正在使用C, sprintf()是IMO,这是进行此转换的最便捷方式:

[后来添加: AAAGHH! 我忘了对于ints / longs ,函数的输入参数想要无符号。 同样,传递给sprintf()的格式字符串。 所以我在下面改了。 对我可怕的疏忽感到抱歉,这本来是一个难以发现的错误。 此外, ulong使它更通用。]

 char * int2str( unsigned long num ) { static char retnum[21]; // Enough for 20 digits plus NUL from a 64-bit uint. sprintf( retnum, "%ul", num ); return retnum; } 

和花车和双打类似。 进行转换的代码事先已知。 必须告诉它 – 它正在转换什么类型的实体,所以你可能最终得到函数char *float2str( float float_num)char *dbl2str( double dblnum)

您将从转换中获得NUL终止的左侧调整(无前导空格或零)字符串。

您可以随时随地进行转换; 这些function只是插图。

HM。 这个怎么样:

 void send_float (float arg) { // get access to the float as a byte-array: byte * data = (byte *) &arg; // write the data to the serial Serial.write (data, sizeof (arg)); } 

使用Firmata协议。 引用:

Firmata是一种通用协议,用于与主机上的软件通信微控制器。 它适用于任何主机软件包。 现在有许多语言的匹配对象。 为其他软件添加对象很容易使用此协议。 基本上,该固件建立了一个协议,用于从主机软件与Arduino通信。 目的是让人们从主机上的软件中完全控制Arduino。

你需要查找的行话词是“序列化”。

这对串行连接来说是一个有趣的问题,它可能会限制哪些字符可以端到端,并且可能无法为每个字符传递8位。

对某些字符代码的限制相当普遍。 这里有几个袖口:

  • 如果正在使用软件流控制,那么传统上控制字符DC1和DC3(Ctrl-Q和Ctrl-S,有时也称为XON和XOFF)不能作为数据传输,因为它们被发送以启动和停止发送方在另一方电缆的末端。

  • 在某些设备上,NUL和/或DEL字符(0x00和0x7F)可能会从接收器的FIFO中消失。

  • 如果接收器是Unix tty,并且termio模式设置不正确,则字符Ctrl-D(EOT或0x04)可以使tty驱动程序向具有tty open的进程发送文件结束信号。

串行连接通常可配置为字节宽度,并且可能包含奇偶校验位。 某些连接将要求使用带有奇偶校验的7位字节,而不是8位字节。 甚至可以连接(严重旧的)传统硬件来为5位和6位字节配置许多串行端口。 如果每个字节可用的小于8位,则需要更复杂的协议来处理二进制数据。

ASCII85是一种流行的技术,用于解决7位数据和控制字符限制。 这是一种仅使用85个精心选择的ASCII字符代码重写二进制数据的约定。

此外,您当然要担心发送方和接收方之间的字节顺序。 您可能还需要担心浮点格式,因为并非每个系统都使用IEEE-754浮点。

最重要的是,选择纯ASCII协议通常是更好的答案。 它具有可以被人理解的优点,并且对串行连接的问题更具抵抗力。 除非您发送大量浮点数据,否则表示的低效率可能会因易于实现而被抵消。

只要对自己所接受的东西保持自由,对你所发出的东西保守。

尺寸重要吗? 如果是,您可以使用ASCII85将每个32位组编码为5个ASCII字符,请参阅http://en.wikipedia.org/wiki/Ascii85 。

也许这是将Float转换为Byte和Byte为Float的最佳方式,-Hamid Reza。

 int breakDown(int index, unsigned char outbox[], float member) { unsigned long d = *(unsigned long *)&member; outbox[index] = d & 0x00FF; index++; outbox[index] = (d & 0xFF00) >> 8; index++; outbox[index] = (d & 0xFF0000) >> 16; index++; outbox[index] = (d & 0xFF000000) >> 24; index++; return index; } float buildUp(int index, unsigned char outbox[]) { unsigned long d; d = (outbox[index+3] << 24) | (outbox[index+2] << 16) | (outbox[index+1] << 8) | (outbox[index]); float member = *(float *)&d; return member; } 

问候。 `

结构和工会解决了这个问题。 使用具有与结构匹配的字节大小的联合的压缩结构。 重叠指向结构和联合的指针(或在结构中添加联合)。 使用Serial.write发送流。 在接收端有一个匹配的结构/联合。 只要字节顺序不匹配,否则您可以使用“C”hto(s..l)函数解压缩。 添加“标题”信息以解码不同的结构/联合。