HEX to 32 bit Float

I need to convert this HEX word " 3F84ED94 " to a 32 bits float.
On internet I found 1.0385 when using a converter an typing the character in this position (thus the bytes order look ok). The value I obtained also make sense. It is pressure in ambiant air in Bar.

I get this HEX word from a modbus rtu sensor using the code below.

I need to represent the variable uint32_t combined variable into IEEE-754 float. I expect a value of 1.0385.

/*
  Modbus Library for Arduino Example - Modbus RTU Client
  Read Holding Registers from Modbus RTU Server in blocking way
  ESP8266 Example
  
  (c)2020 Alexander Emelianov (a.m.emelianov@gmail.com)
  https://github.com/emelianov/modbus-esp8266
*/

#include <ModbusRTU.h>
//#include <SoftwareSerial.h>

#define SLAVE_ID 1
#define FIRST_REG 22
#define REG_COUNT 2
int i = 0;

//SoftwareSerial S(D2, D1);
ModbusRTU mb;

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors
  if (event != Modbus::EX_SUCCESS) {
    Serial.print("Request result: 0x");
    Serial.print(event, HEX);
  }
  return true;
}

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1,16,17);
  mb.begin(&Serial1);
  mb.master();
}

void loop() {
  uint16_t res[REG_COUNT];
  if (!mb.slave()) {    // Check if no transaction in progress
    mb.readHreg(SLAVE_ID, FIRST_REG, res, REG_COUNT, cb); // Send Read Hreg from Modbus Server
    while(mb.slave()) { // Check if transaction is active
      mb.task();
      delay(10);
    }

     Serial.println(res[0], HEX);    //  This print 3F84
    Serial.println(res[1], HEX);    //  This print ED94
    
    uint32_t combined = res[0];          // This allow to concatenate the two part into one.
    combined = (combined << 16) | res[1];    
    Serial.println (combined, HEX);  //  This show in the monitor:  3F84ED94

union 
{
    float z;
   long m;
}data;
data.m = combined;
Serial.println(data.z,4); 


     }
  delay(1000);
}

This is the converter I used.

thank you

1 Like

Use the forum search tool, that horse has been beaten to death here, so you will find complete and interesting answers.

Here is one way to do it:

  float fVal = 0;
  uint32_t combined = res[0];          // This allow to concatenate the two part into one.
  combined = (combined << 16) | res[1];    
  Serial.println (combined, HEX);  //  This show in the monitor:  3F84ED94
  memcpy(&fVal, &combined, sizeof(float));
  Serial.println(fVal, 4);

Thank you for the answer @ToddL1962 . I found a different solution but working solution on the forum. Although I don't understand how it work!

I edit the code in my first post with the verison that compile and work. With it I obtain the expected pressure value.

Oy. I don't have the energy to start up that discussion again.

The forum rules asks you not to do that. It is because it renders later answers wrong, disrupting the flow of the threads.
Please never do that again.

1 Like

That's the beauty of the standards compliant, portable method (bit shifting). It is self explanatory as long as you understand the basics.

Most compilers nowadays are optimizing, so bit shifting code will be implemented as byte moves, such as memcpy(), under the hood. But unlike memcpy and unions, it will be guaranteed portable because it sticks to the language definition and doesn't exceed it.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.