I am trying to read a SDM220 meter on my solar setup. I've been reading it using Modbus SCADA, so know it all works ok. But I want to read it with my Arduino Mega 256. My problem is that when I run the code below the final value MtrKWh , is not float value. it's actual value is printed. Here is a copy of the output.
17241 MtrKWh1 1129906176 MtrKWh1<<16 57737 MtrKWh2 1129963913 MtrKWh3 11299639.00 MtrKWh 2
the value '1129963913' MtrKWh3,
if I turn it into Binary is 01000011010110011110000110001001,
if I convert this to binary using https://www.h-schmidt.net/FloatConverter/ it gives me the value
217.881,
the very value I expect. Am I missing some brackets somewhere? So how do I get MtrKWh to print its float value? I have left a lot of commented out bits to show the several things I have tried. Sorry if it appears messy, I will tidy it up once I solve this problem. I'm sure it is something simple, but, I haven't been able to see it so far. Any sugestions would be appreciated.
// MtrV, MtrC, MtrW, MtrKWh
//void AddressRegistry_0()
result = sdm220_modbus.readInputRegisters(0x48, 2);
//while (!result == 0) {
// delay(10);
// result = sdm220_modbus.readInputRegisters(0x156,4);
//}
if (result == sdm220_modbus.ku8MBSuccess)
{
// 1 Serial.println((node.getResponseBuffer(0x0D) + node.getResponseBuffer(0x0E) << 16)/100.0f);
// 2 pvpower = ((long)node.getResponseBuffer(0x03) << 16 | node.getResponseBuffer(0x02)) / 100.0f;
// 3 long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
// 1 working ?? MtrKWh1 = (((long)sdm220_modbus.getResponseBuffer(0x0) + sdm220_modbus.getResponseBuffer(0x1) << 16)/6.f);
// 2 working ?? MtrKWh1 = ((long)sdm220_modbus.getResponseBuffer(0x0) << 16 | sdm220_modbus.getResponseBuffer(0x1)) / 100.3f;
// 3 working MtrKWh1 = (( sdm220_modbus.getResponseBuffer(0x0) << 16) | sdm220_modbus.getResponseBuffer(0x1)) / 16.3f;
//
// float MtrKWh0 =((float)(sdm220_modbus.getResponseBuffer( 0) << 16 | sdm220_modbus.getResponseBuffer( 1)));
// Serial.print(MtrKWh0);
// Serial.print(" MtrKWh0 ");
signed long MtrKWh1 = sdm220_modbus.getResponseBuffer(0x0);
Serial.print(" ");
Serial.print(MtrKWh1);
Serial.print(" MtrKWh1");
MtrKWh1 = MtrKWh1 << 16;
Serial.print(" ");
Serial.print(MtrKWh1);
Serial.print(" MtrKWh1<<16");
word MtrKWh2 = sdm220_modbus.getResponseBuffer(0x1);
Serial.print(" ");
Serial.print(MtrKWh2);
Serial.print(" MtrKWh2");
signed long MtrKWh3 = MtrKWh1 | MtrKWh2;
Serial.print(" ");
Serial.print(MtrKWh3);
Serial.print(" MtrKWh3");
float (MtrKWh) = float (MtrKWh3) / 10000.0;
Serial.print(" ");
Serial.print(MtrKWh);
Serial.print(" MtrKWh ");
//uint32_t x = 0x3f322e3f;
//float y = *(float*)&x;
//Serial.print (y, 6);
// Serial.print(" MtrKWhxxx ");
}
else
{
rs485DataReceived = false;
Serial.println("Fail sdm220_modbus.readInputRegisters(0x0, 1) ");
}
reinterpret_cast
does exactly that. I think it's a C++11 thing though, and I don't know whether the Arduino compiler supports it.