如何将浮点数转换为uint8_t?
How to convert a float into uint8_t?
我正在尝试使用 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
值,为什么我的原始给定转换不能按照我期望的方式工作?
听起来你正在试图为这些数字找出一个最小尺寸的表示形式,你可以用一些非常小的数据包格式传输。 如果范围受到适当限制,通常最好使用适当的定点表示来完成。
例如,如果温度始终在 0..63 范围内,则可以在单个字节中使用 6.2 定点格式:
if (value < 0.0 || value > 63.75) {
// out of range for 6.2 fixed point, so do something else.
} else {
uint8_t bval = (uint8_t)(value * 4 + 0.5);
// output this byte value
}
当您读回字节时,只需将其乘以 0.25 即可获得(近似(浮点值。
当然,由于 8 位的精度非常有限(大约 2 位(,因此它会四舍五入一点以适应 - 您的 23.24 值将四舍五入为 23.25。 如果需要更高的精度,则需要使用更多位。
如果您只需要一点精度但范围更广,则可以使用自定义浮点格式。 IEEE 16 位浮点数 (S5.10( 非常好(为您提供 3 位精度和大约 10 个数量级范围(,但您可以更小,特别是如果您不需要负值。 U4.4 浮点格式在 8 位(仅正数(中为您提供 1 位精度和 5 个数量级范围
如果您知道发送方和接收方都使用相同的 fp 二进制表示形式,并且都使用相同的字节序,那么您可以只考虑:
float a = 23.24;
uint8_t buffer[sizeof(float)];
::memcpy(buffer, &a, sizeof(float));
uint8_t
变量只能携带 256 个值。 如果真的想把温度压缩成单字节,就必须使用定点法或最低有效位值法
- 定义工作范围,T0 和 T1 将
- T0-T1 除以 256(2^8,许多可能的值(。
- 结果值将是一个
float
常量(可以使用灵活的 LSB 值(,通过该常量将原始值float
值 X:R = (X-T0)/LSB
除以。您可以将结果四舍五入,它将适合字节。 - 在接收端,您必须将整数值乘以相同的常量
X = R*LSB + T0
。
在Arduino中,可以将浮点数转换为字符串
float ds_temp=sensors.getTempCByIndex(0); // DS18b20 Temp sensor
然后将字符串转换为字符数组:
String ds_str = String(ds_temp);
char* ds_char[ds_str.length()];
ds_str.toCharArray(ds_char ,ds_str.length()-1);
uint8_t* data =(uint8_t*)ds_char;
uint_8值存储在data
中,大小sizeof(data)
- 从值小于256的uint16到uint8的Endian安全转换
- 将 Uint8(浮点AUDIO_F32)转换为int16_t(16 位 PCM)
- 错误:无法将'uint8* {aka unsigned int*}'转换为"常量emxArray_uint8_T*"?
- 将具有不同字段的结构转换为 uint8 的数组
- 如何将 uint8 列表转换为其相应的有符号值
- 如何将元素从 Swift 中的 [UnsafeMutablePointer<UInt8>] 转换为 C++ 中的 UInt8 *
- 从字符串转换为 uint8,反之亦然
- 将 UInt8 C++值转换为 C# 字节数组
- 警告缩小转换范围(uint32 到 uint8)
- 将 uint8 转换为范围为 0-1 的浮点数的最有效方法
- 将 Uint8 转换为无符号字符 RGB 值
- 将uint8的矢量转换为ascii十六进制字符串的更好方法
- 从std::string转换为uint8
- Jagged Uint8数组转换为C#字节
- 将"wstring"转换为"const UInt8 *"
- 我如何将bitset转换为字节/uint8数组
- 如何在c++中将UINT8转换为UINT32 ?
- 我如何将uint8_t (SDL中的Uint8)转换为字符串
- 将uint8 vector类型的元素转换为stringstream类型
- Node.js 6增加了将Buffer.from()转换为const UInt8*的功能