Integer to double conversion

Hi everyone!

I am working on a project where I need to format raw bytes received via serial into float or double value. I am using Arduino mega for this project. I am able to convert into signed and unsigned integer but somehow conversion to float does not work. I am explaining my requirement below with an example :

Example :: 0x41CC28F6 should give 25.52

Below is the function I use for data conversion in my code.

void Format_Data(struct MB_RESP *input, unsigned char fmt, char *data)
{
  char arr[30];
  float real;
  unsigned long int temp;

  strcat(data, ",");
  switch (fmt)
  {
    case INT16:
      *((char*)(&temp) + 0) = input->data[1];
      *((char*)(&temp) + 1) = input->data[0];
      *((char*)(&temp) + 2) = 0;
      *((char*)(&temp) + 3) = 0;

      sprintf(arr, "%d", temp);
      arr[5] = '\0';
      strcat(data, arr);
      break;

    case UINT16:
      *((char*)(&temp) + 0) = input->data[1];
      *((char*)(&temp) + 1) = input->data[0];
      *((char*)(&temp) + 2) = 0;
      *((char*)(&temp) + 3) = 0;

      sprintf(arr, "%u", temp);
      arr[5] = '\0';
      strcat(data, arr);
      break;

    case INT32:
      *((char*)(&temp) + 0) = input->data[3];
      *((char*)(&temp) + 1) = input->data[2];
      *((char*)(&temp) + 2) = input->data[1];
      *((char*)(&temp) + 3) = input->data[0];

      sprintf(arr, "%ld", temp);
      arr[10] = '\0';
      strcat(data, arr);
      break;

    case UINT32:
      *((char*)(&temp) + 0) = input->data[3];
      *((char*)(&temp) + 1) = input->data[2];
      *((char*)(&temp) + 2) = input->data[1];
      *((char*)(&temp) + 3) = input->data[0];

      sprintf(arr, "%lu", temp);
      arr[10] = '\0';
      strcat(data, arr);
      break;

    case IEEE754FP:
      *((char*)(&temp) + 0) = input->data[1];
      *((char*)(&temp) + 1) = input->data[0];
      *((char*)(&temp) + 2) = input->data[3];
      *((char*)(&temp) + 3) = input->data[2];

      sprintf(arr, "%lu", temp);        //temporarily converting into unsigned long long int
    //   sprintf(arr, "%lf", (double)temp);     //gives '?' on serial
      arr[10] = '\0';
      strcat(data, arr);
      break;
  }
}

I have included all header files and there is no compilation error.

Hello

You can use memcpy, it's the safest way to do that

uint32_t d = 0x41CC28F6;
float f;
memcpy( &f, &d, sizeof(float) );

I see a problem with endian-ness. Or else you have typos in your array indices...

(double)temp does not work as you think it works. I'm not sure how to explain.

It does not take an integer and say that the bytes in it now represent a float; it takes the integer and says to treat it as a float.

I beg to differ

uint32_t value = 0x41CC28F6; // should give 25.52
char buff[20];
float tFloat = 999.666;

void setup() {
  Serial.begin(115200);
  Serial.print(F("casting 0x"));
  Serial.print(value, HEX);
  Serial.print(F(" to float gives "));
  dtostrf((float)value, 0, 6, buff);
  Serial.println(buff);
  Serial.print(F("interpreting 0x"));
  Serial.print(value, HEX);
  Serial.print(F(" as float "));
  memcpy(&tFloat, &value, sizeof(value));
  dtostrf(tFloat, 0, 6, buff);
  Serial.println(buff);
}

void loop() {}
casting 0x41CC28F6 to float gives 1103898900.000000
interpreting 0x41CC28F6 as float 25.520000

As I said, I'm not sure how to explain. But your code demonstrates what I wanted to convey.

I probably just misunderstood you. :grinning:

1 Like