如何将double转换为十六进制/字节

时间:2017-09-19 19:26:14

标签: arduino hex byte uint8t arduino-c++

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

  

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

某些函数返回带有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 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 2C A8 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 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 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF 2C

因为34 2e 33 32等于4.32。

我不明白,也不知道我怎么能&#34;合并&#34;并转换浮点值。然后你可以帮我按照浮动的大小移动指针吗?

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

2 个答案:

答案 0 :(得分: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位是非常有限的,并且您没有像以前的方法那样灵活地选择范围。定点数的优点是你可以对它们进行算术运算(加法,减法,乘法和除法)。

答案 1 :(得分:0)

(我对Arduino一无所知)

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

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

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

而不是23.45,你将得到2345.使用uint8_t会限制你太多,因为范围太小(0-255)。无论你有uint16_t和uint32_t,我都不知道。

这种技术称为定点算法。