enter image description here

enter image description here

enter image description here

Hi,am trying to communicate with power-factor controller [Selec APFC 148-312] using modbus RTU,am following example sketch from modbusmaster library. am able to get the raw data from the instrument but data structure seems to be in decimal format, can someone help me to convert this into float.thank you

#include <ModbusMaster.h>

#define MAX485_DE      3
#define MAX485_RE_NEG  2

// instantiate ModbusMaster object
ModbusMaster node;

void preTransmission()
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);

void postTransmission()
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

void setup()
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode

  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Modbus communication runs at 9600 baud

  // Modbus slave ID 1
  node.begin(1, Serial);
  // Callbacks allow us to configure the RS485 transceiver correctly

void loop()
  float result;

  result = node.readInputRegisters(0x30000, 10);
  if (result == node.ku8MBSuccess)

    Serial.print("V1N: ");

    Serial.print("V2N: ");
    Serial.print("V3N: ");

    Serial.print("Vavg: ");

    Serial.print("V12: ");

    Serial.print("V23: ");
    Serial.print("V31: ");

    Serial.print("L-L avg: ");
  • C++ programming question ... not Arduino specific really
    – jsotola
    Jul 17, 2021 at 0:30
  • decimal format and floating point format are two different things ... what do you actually need?
    – jsotola
    Jul 17, 2021 at 0:47
  • @jsotola i just need the output displayed in the serial monitor to be in voltage and other parameter readings as given on the data sheet.
    – Ragaven N
    Jul 17, 2021 at 2:35
  • Re “data structure seems to be in decimal format”: It's not. It's binary. The reason you see decimal on the serial console is because Serial.println() converts its argument to decimal, for the purpose of printing it as text. The authors of this method assumed that most humans prefer reading decimal rather than binary. Note that Serial.println() can be told (by a second argument) to use a different base. Jul 17, 2021 at 9:41

1 Answer 1


I'm not sure this can really be considered topical, but someone wanting to read floating point numbers over MODBUS with an Arduino might get something out of it. Also I have no way to test this really. But here goes:

Your MODBUS map shows V2N at 30002, and you notice 30003 is not mentioned in the map. Your voltage from phase two to neutral appears to be encoded into two consecutive 16-bit registers, which is a somewhat normal scheme for conveying 32bit floats via MODBUS, from what I can tell. So, your values of 17280 and 9830 are two halves of a 32-bit floating point number. In hex, 0x4380 and 0x2666. These seem to be taken together as 0x43802666 as the bit pattern for 32-bit float.

A function like this would allow you to extract your 32-bit float data from your separate 16-bit MODBUS register reads:

float modbus_16bit_register_pair_to_float(uint16_t a, uint16_t b) {
    uint32_t combined = ((uint32_t)a << 16) | b;
    float f;
    memcpy(&f, &combined, sizeof f);
    return f;

There are lots of ways you could do this. This code assumes that the float type's endian matches the uint32_t type's endian, and that float is 32-bit, which is common but not strictly standard.

Running this on 17280 and 9830 gives 256.3 (rounded), which doesn't perfectly match other output, but I suspect that's just because the reading is varying.

  • 1
    Thank You Sir. it worked.
    – Ragaven N
    Aug 15, 2021 at 20:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.