簡體   English   中英

如何將 float 轉換為 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值,為什么我原來的給定轉換不能像我期望的那樣工作?

如果您知道發送者和接收者都使用相同的 fp 二進制表示並且都使用相同的字節序,那么您可以只使用 memcpy:

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

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

聽起來您正試圖為這些數字找出一個最小尺寸的表示,您可以以一些非常小的數據包格式傳輸。 如果范圍受到適當限制,通常最好通過使用適當的定點表示來完成。

例如,如果您的溫度始終在 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 個數量級范圍),但你可以 go 更小,特別是如果你不需要負值。 U4.4 浮點格式為您提供 1 位數的精度和 8 位的 5 個數量級范圍(僅正數)

在 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 值存儲在大小為sizeof(data) data數據中

uint8_t的變量只能攜帶 256 個值。 如果你真的想把溫度壓縮成單個字節,你必須使用定點方法或最低有效位值方法

  • 定義工作范圍,T0 和 T1
  • 將 T0-T1 除以 256(2^8,一些可能的值)。
  • 結果值將是一個float常量(可以使用靈活的 LSB 值),您可以將其除以原始float值 X: R = (X-T0)/LSB 您可以將結果四舍五入,它適合字節。
  • 在接收方,您必須將整數值乘以相同的常量X = R*LSB + T0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM