-8

我需要向物联网发送数据,数据需要以字节为单位

要通过物联网来回发送数据,您需要使用字节

一些函数返回带有 2 个小数的浮点数

23.56 或 4.32

我很难转换我的浮点数并将其保存到我的数据的可变 uint8_t 中。我必须找到如何转换我的浮点变量

我有一个这样的循环:

/*
NOTE:
uinit8_t mydata[64];
byte nbMaxCapteurs = 10;
mesMesures[i][mesCapteur[i].idDuCapteur].valeur => this is a float
*/

memset(mydata, 0xFF, 64);
uint8_t * ptr = mydata;
for (byte i = 0; i < nbMaxCapteurs; i++) {
  if (mesCapteur[i].actif) {
    *ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur;
    ptr += 15; // How to know the number of step to move the pointer
    if (i < nbCapteurActif + 1) {
      *ptr = 0x2C; // virgule
      ptr += sizeof(char);
    }
  } else {
    *ptr = 0x2C; // virgule pour les capteurs inactifs
    ptr += sizeof(char);
  }
}
*ptr = '00'; // Close \0
ptr += sizeof(char);
printData();

我对这种转换很陌生。真正的问题在这里:

*ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur;

printData 打印:

04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C 18 FF FF FF FF FF FF FF FF FF FF FF FF FF 2C CB FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C

但它至少应该打印这个:

34 2E 33 32 FF FF FF FF FF FF FF FF FF FF FF 2C 18 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C CB FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C

因为34 2e 33 32等于 4.32。

我不明白也不知道如何“合并”和转换浮点值。然后你能帮我按照浮动的大小移动指针吗?

我真的坚持这个话题,我非常感谢你的帮助。

4

2 回答 2

3
  • 如果要在小数点后两位四舍五入为零,可以使用以下命令:

    double lum = ((int)(luminosity * 100))/100.0;
    
  • 如果要在小数点后两位四舍五入到最接近(从零四舍五入),可以使用以下命令:

    #include <math.h>
    double lum = round(luminosity * 100)/100.0;
    

  • 另一方面,如果您想尽可能高效地将亮度存储到 8 位,则可以使用以下算法。

    uint8_t packed_luminosity;
    if (luminosity >= MAX_LUMINOSITY)       // Just in case
       packed_luminosity = 255;
    else if (luminosity <= MIN_LUMINOSITY)  // Just in case
       packed_luminosity = 0;
    else
       packed_luminosity = (uint8_t)(
           ( luminosity - MIN_LUMINOSITY ) / ( MAX_LUMINOSITY - MIN_LUMINOSITY + 1 ) * 256 );
    

    您可以以这种格式对亮度进行比较和某些操作。

  • 将十进制数打包成整数的另一种方法是定点数。这可以通过在编写程序时为所有亮度选择比例来实现。以下是一些缩放支持的范围:

    uint8_t
    =======
    Scaling  Supported range (binary)         Supported range (decimal)
    -------  -------------------------------  -----------------------------------------
    ...
    B8       [00000000.    .. 111111110.   ]  [0 .. 512)  No odd numbers
    B7       [ 0000000.    ..  11111111.   ]  [0 .. 256)  No decimals
    B6       [  000000.0   ..   1111111.1  ]  [0 .. 128)  .0, .5
    B5       [   00000.00  ..    111111.11 ]  [0 ..  64)  .0, .25, .5, .75
    B4       [    0000.000 ..     11111.111]  [0 ..  32)  Almost one full decimal place
    ...
    
    int8_t
    ======
    Scaling  Supported range (binary)        Supported range (decimal)
    -------  ------------------------------  --------------------------------------------
    ...
    B8       [10000000.   .. 011111110.   ]  [-256 .. 256)  No odd numbers
    B7       [ 1000000.   ..  01111111.   ]  [-128 .. 128)  No decimals
    B6       [  100000.0  ..   0111111.1  ]  [ -64 ..  64)  .0, .5
    B5       [   10000.00 ..    011111.11 ]  [ -32 ..  32)  .0, .25, .5, .75
    B4       [    1000.000 ..    01111.111]  [ -16 ..  16)  Almost one full decimal place
    ...
    

    如您所见,仅使用 8 位是非常有限的,并且您无法获得与早期方法相同的选择范围的灵活性。定点数的优点是您可以对它们执行算术函数(加法、减法、乘法和除法)。

于 2017-09-19T19:33:00.800 回答
0

(我对 Arduino 一无所知)

使您接近目标的最小变化是:

double luminosity;
uint32_t lum;
lum = (uint32_t)(luminosity * 100);

现在, lum 将包含您的值乘以 100,四舍五入。

您将获得 2345 而不是 23.45。使用 uint8_t 会限制您太多,因为范围太小 (0-255)。我不知道你是否有 uint16_t 和 uint32_t 可用。

这种技术称为定点算法。

于 2017-09-19T19:33:21.760 回答