Problems with REAL4 value conversions from TUF-2000 flow meter (MODBUS)

Hello,

I'm facing confusing issue. I originally developed this software with SODAQ Explorer which is SAMD21 device and now I would like to get same code working for original Arduino Uno. I'm reading REAL4 value from industrial device (TUF-2000 flow meter) with modbus protocol.

Here is link to the manual https://images-na.ssl-images-amazon.com/images/I/91CvZHsNYBL.pdf

I'm reading registers 0221-0222 (should be "Inner pipe diameter" in millimeters, page 43) and I get two unsigned long values. I'm using "pipe inner diameter" because it's easy to change from the device. I have two boards: SODAQ Explorer (SAMD21) and Arduino Uno. Tried the same thing with both boards.

These are the results. TUF-2000 means value read from the device screen. value1/value2 are the values read from registers. Arduino Uno and SODAQ values mean converted values with same code but different board.

TUF-2000 value1 value2 Arduino Uno SODAQ Explorer
74 mm 17040 17038 72.18 72.18
75 mm 17042 17038 NaN 73.26
75.1199 mm 17042 51479 NaN 73.39
71.3999 mm 17038 3303 71.03 71.03

Here is the conversion code:

float toFloat(int value1, int value2)
{
  unsigned long temp = (unsigned long)value1 << 16 | value2;
  return *(float*)&temp;
}

From arduino I get NaN values. Also the number from the TUF-2000 screen are not exactly the same as values from arduino/SODAQ. :o

Does anyone have any idea, why Arduino produces NaN while SODAQ produces real value and what could be the problem with around 2 mm difference between the values from TUF-2000 compared to the read values?

Are my conversions completely wrong?

this gives me valid results

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  Serial.println(toFloat(17040,17038));
  Serial.println(toFloat(17042,17038));
  Serial.println(toFloat(17042,51479));
  Serial.println(toFloat(17038,3303));
}

void loop() {
  // put your main code here, to run repeatedly:

}

float toFloat(int value1, int value2)
{
  unsigned long temp = (unsigned long)value1 << 16 | (uint16_t)value2;
  return *(float*)&temp;
}

72.13
73.13
73.39
71.03

Ohh, that's working for me too, so it must be something with other parts of my software. Thanks!
EDIT: This was pretty newbie error, my toFloat -function had type "int" as parameter, not "unsigned int".

The other question is still unsolved, what's reason for the difference between values displayed TUF-2000 screen and the values read from it via modbus? Any ideas?

you should care about the definitions in your parameters. I still don't like

float toFloat(int value1, int value2)