2

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 Serial.begin(9600);

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

void loop() { float result;

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

Serial.print(&quot;V1N: &quot;);
Serial.println(node.getResponseBuffer(0x01));

Serial.print(&quot;V2N: &quot;);
Serial.println(node.getResponseBuffer(0x02));

Serial.print(&quot;V3N: &quot;);
Serial.println(node.getResponseBuffer(0x03));

Serial.print(&quot;Vavg: &quot;);
Serial.println(node.getResponseBuffer(0x04));

Serial.print(&quot;V12: &quot;);
Serial.println(node.getResponseBuffer(0x05));

Serial.print(&quot;V23: &quot;);
Serial.println(node.getResponseBuffer(0x06));

Serial.print(&quot;V31: &quot;);
Serial.println(node.getResponseBuffer(0x07));

Serial.print(&quot;L-L avg: &quot;);
Serial.println(node.getResponseBuffer(0x08));

} delay(1000); }

Ragaven N
  • 21
  • 1
  • 3

1 Answers1

3

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.

timemage
  • 5,639
  • 1
  • 14
  • 25