Unable to extract a float from the node.getResponceBuffer() function

Who can help me!!

I am working on a project where a read some MODBUS addesses from a device.
The serial read out of those addresses is not the problem, but the Serial monitor shows wrong values.
I know the recieve buffer contains the right Hex values but the translation to float32 is a problem.
I tried seveal methodes but nothing seems to work, does someone have the right solution for me.
As you see in the picture, value 1 to 6 must be 100,00 in float32 notation.
value 2 is the HEX notation whitch is ok 42C8 >> If you put that number in the IEEE-754 Floating Point Converter it retruns with 100 ! (see picture 2)
Why I can’t do that in ARDUINO code?? >:(

Thks in advnace!

value 2 is the HEX notation which is ok 42C8 >> If you put that number in the IEEE-754 Floating Point Converter it retruns with 100 ! (see picture 2)

Where does the second 16 bits 0b0000000000000000 of the 4 byte float come from?
Hexadecimal Representation 0x42C80000
Are they always 0, and you values are completely defined by the first 16 bits?

Please post your complete code, or a simplified example which demonstrates the problem, not an image of a portion of the code.

EDIT:
What data type does node.getResponceBuffer() return?

If you know the 4 bytes your need to use as the IEEE754 float, there are ways using a union or a cast to get them combined and represented as a float. For example

void setup() {
 Serial.begin(115200);
 int Waarde2 = 0x42c8;
 int WaardeX = 0x00;
 uint32_t combinedValues = (uint32_t)Waarde2 << 16 | WaardeX;
 float f  = *(float*)&combinedValues;
 Serial.println(f);
 uint32_t combinedValues1 = (uint32_t)Waarde2 << 16;//without second int
 float f1 = *(float*)&combinedValues1;
 Serial.println(f1); 
}
void loop() {}

Prints
100.00
100.00

Thks! it’s working now. I only changed the following :

void loop()
{
uint32_t result;

// result = node.readHoldingRegisters(0x3501, 1); 1B93 = 7059
// result = node.readInputRegisters(7085, 24); //For read Performance per path
// result = node.readInputRegisters(7057, 12); //For read Velocity per path

result = node.readInputRegisters(7061, 24); //For read Sos per path
if (result == node.ku8MBSuccess)
{
Serial.println();

size_t Waarde1 = (node.getResponseBuffer(0));
size_t Waarde1a = (node.getResponseBuffer(1));
uint32_t combinedValues1 = (uint32_t)Waarde1 << 16| Waarde1a;
float f1 = (float)&combinedValues1;
Serial.print("Waarde1: ");
Serial.println (f1,5);
}
else
{
Serial.println(“No Comm”);
}
delay(1000);
}

I would really appreciate if you explain a little bit more of what you/I am doing here, i not quite understand the essence of those commands :
uint32_t combinedValues1 = (uint32_t)Waarde1 << 16| Waarde1a;
float f1 = (float)&combinedValues1;

Thks again !

I would really appreciate if you explain a little bit more of what you/I am doing here, i not quite understand the essence of those commands :
uint32_t combinedValues1 = (uint32_t)Waarde1 << 16| Waarde1a;
float f1 = (float)&combinedValues1;

uint32_t combinedValues1 = (uint32_t)Waarde1  << 16| Waarde1a;

This line creates a new 32 bit variable from the two 16bit Waarde variables using bitShifting and the binary “or” to add them. The ordering of the high and low 16 bits of the combined variable are dependent upon the little endian nature of the Arduino.

Lets say the compiler puts this new combinedValues1 variable at memory address 1234 and it will take up 4 adjacent bytes of memory.

float f1  = *(float*)&combinedValues1;

The (float*)&combinedValues1 is a pointer to address 1234 and tells the compiler to consider what starts at that address as as the 4 bytes of a float.
You then create a new float variable f1 linked with a pointer to the previous one. So when the compiler goes to get a value for f1 it follows one pointer to another and treats the variable as a float.

The use of the linked pointers is somewhat confusing, so you may want to consider this alternative which uses memcpy to copy the 4 bytes of the uint32_t combinedValues1 into the memory location of float f1.

uint32_t combinedValues1 = (uint32_t)Waarde1  << 16| Waarde1a;
float f1;
memcpy(&f1, &combinedValues1, 4);

You can also use a union to combine the 4 bytes with the float.

Think I get you!
Thanks, you for your clear explanation. :wink: