c++ 如何将浮点数转换为uint8_t?

wbrvyc0a  于 2022-12-24  发布在  其他
关注(0)|答案(4)|浏览(657)

我尝试使用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值,为什么我最初给出的转换结果不像我期望的那样工作呢?

kognpnkq

kognpnkq1#

如果你知道发送方和接收方都使用相同的fp二进制表示,并且都使用相同的字节序,那么你只需要memcpy:

float a =  23.24;
uint8_t buffer[sizeof(float)];

::memcpy(buffer, &a, sizeof(float));
jei2mxaa

jei2mxaa2#

听起来像是您在尝试找出这些数字的最小表示法,以便能够以某种非常小的数据包格式传输。如果范围受到适当限制,通常最好使用适当的定点表示法。
例如,如果您的温度始终在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值将被四舍五入为24.25。
如果您只需要一点精度但需要更大的范围,则可以使用自定义浮点格式。IEEE 16位浮点(S5.10)非常好(给予你3位数的精度和大约10个数量级的范围),但你可以走得更小,特别是当你不需要负值的时候。U4.4浮点格式给予你1位的精度和5个数量级的8位范围(仅限正值)

xsuvu9jc

xsuvu9jc3#

在Arduino中,可以将浮点数转换为字符串

float ds_temp=sensors.getTempCByIndex(0); // DS18b20 Temp sensor

然后将String转换为char数组:

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)

kyxcudwk

kyxcudwk4#

一个变量uint8_t只能携带256个值,如果你真的想把温度压缩成一个字节,你必须使用定点方法或最低有效位值方法

  • 定义工作范围T0和T1
  • 将T0-T1除以256(2^8,许多可能的值)。
  • 结果值将是一个float常量(可以使用灵活的LSB值),您可以将原始float值X除以该常量:R = (X-T0)/LSB。您可以舍入结果,它将适合字节。
  • 在接收端,必须将整数值乘以相同的常数X = R*LSB + T0

相关问题