I have been having an issue with converting a floating point value I read over Modbus that is sent in 4 bytes. I have confirmed via logging that the correct 4 bytes are being read, but I can’t seem to get the conversion right. I have tried various permutations and combinations but of course since floats are a special encoding and not just raw bits, things like fiddling with shifts or reading the single bytes have not been very helpful.
I have previously implemented a working version of this on a different device in Python. This is the very simple code that does the conversion as intended on my ARM7(ARMV7A) 32 Bit Linux System:
res = self.get_input_register(address, 2)
if res is not None and len(res) > 1:
floatp1 = res[0]
floatp2 = res[1]
float_val = unpack('f', pack('<HH', floatp2, floatp1))[0]
if self.debug_mode:
print "FLOAT:" + str(float_val)
This code flips the first 2 bytes with the last 2, so the 2 bytes received 2nd are the MSBs. Then the format string tells the system that this is a Float encoded as 2 variables of type ‘Little Endian unsigned short’ (this system is Big Endian so a conversion is needed).
It is my understanding that the NRF52840 (ARMCortexM4) is Little Endian as well. Therefore, I was hoping something this simple would work:
if (result == modbus.ku8MBSuccess)
{
data[0] = modbus.getResponseBuffer(0);
data[1] = modbus.getResponseBuffer(1);
int32_t tmpVal = ((uint32_t)(data[1]));
tmpVal = tmpVal << 16;// shift left 2 bytes
tmpVal = tmpVal | ((uint32_t)data[0]); // OR in LSB
float outVal = static_cast<float>(tmpVal);
Serial.printf("FLOAT: %f", outVal);
}
However, this prints seemingly random/nonsensical garbage data. I have played around with various permutations and combinations of fixes I could think of, but nothing seemed to help. Does anything jump out as an obvious oversight or mistake I’m making?