我尝试使用LMIC lora库从一个arduino发送多个float
值,LMIC函数只接受uint8_t
作为它的传输参数类型。temp
包含我的温度值作为一个浮点数,我可以打印这样的测量温度没有问题:
Serial.println((String)"Temp C: " + temp);
有一个示例显示了使用以下代码进行转换:
uint16_t payloadTemp = LMIC_f2sflt16(temp);
// int -> bytes
byte tempLow = lowByte(payloadTemp);
byte tempHigh = highByte(payloadTemp);
payload[0] = tempLow;
payload[1] = tempHigh;
我不确定这是否可行,看起来不可行。发送的结果数据是:FF 7F
我不相信这是我要找的.我也试过以下转换程序:
uint8_t *array;
array = (unit8_t*)(&f);
使用arduino,这甚至不会编译.
一个确实有效,但产生的结果太长的东西是:
String toSend = String(temp);
toSend.toCharArray(payload, toSend.length());
payloadActualLength = toSend.length();
Serial.print("the payload is: ");
Serial.println(payload);
但是得到的十六进制太长了,当我得到我想发送的其他值时。
那么我如何将一个float
转换成一个uint8_t
值,为什么我最初给出的转换结果不像我期望的那样工作呢?
4条答案
按热度按时间kognpnkq1#
如果你知道发送方和接收方都使用相同的fp二进制表示,并且都使用相同的字节序,那么你只需要memcpy:
jei2mxaa2#
听起来像是您在尝试找出这些数字的最小表示法,以便能够以某种非常小的数据包格式传输。如果范围受到适当限制,通常最好使用适当的定点表示法。
例如,如果您的温度始终在0..63范围内,您可以使用6.2单字节定点格式:
当你读回这个字节时,你只要把它乘以0.25就可以得到(近似的)浮点值。
当然,由于8位的精度相当有限(大约2位),因此它将被四舍五入一点以适应--您的23.24值将被四舍五入为24.25。
如果您只需要一点精度但需要更大的范围,则可以使用自定义浮点格式。IEEE 16位浮点(S5.10)非常好(给予你3位数的精度和大约10个数量级的范围),但你可以走得更小,特别是当你不需要负值的时候。U4.4浮点格式给予你1位的精度和5个数量级的8位范围(仅限正值)
xsuvu9jc3#
在Arduino中,可以将浮点数转换为字符串
然后将String转换为char数组:
uint_8值存储在
data
中,大小为sizeof(data)
kyxcudwk4#
一个变量
uint8_t
只能携带256个值,如果你真的想把温度压缩成一个字节,你必须使用定点方法或最低有效位值方法float
常量(可以使用灵活的LSB值),您可以将原始float
值X除以该常量:R = (X-T0)/LSB
。您可以舍入结果,它将适合字节。X = R*LSB + T0
。