arduinomodbusrs485

Read Data from energy meter using Modbus RTU in Arduino Mega


Trying to read data from the energy meter. The code suppose to read voltage data and return but it's some random numbers are showing. Where am I making mistake in the code? Meter is conzerv EM6436 Energy Meter. Tried:- 1) converting data in uint16_t fail 2) Reading different other registers fail 3) The energy meter showing correct data on modscan. Energy Meter register Link

 #include<ModbusMaster.h>
  #define MAX485_DE      3
  #define MAX485_RE_NEG  2
 
  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);  
  
      Serial.begin(19200,SERIAL_8E1);  
//slave ID 1  
      node.begin(1, Serial);  

      Serial.println("Starting Modbus Transaction:");  
      node.preTransmission(preTransmission);  
      node.postTransmission(postTransmission);  
  }
  
  uint16_t newData = 0;
  float floatData;
  double dataOne;
  
void loop() {                           // loop starts from here.
static uint32_t i;
uint8_t j, result;
uint16_t data[10];

i++;
result = node.readHoldingRegisters(3036,1);

Serial.println(" ");
  
if (result == node.ku8MBSuccess) {
  
  Serial.print("\nSuccess, Received data 0: ");
  
  for (j = 0; j < 1; j++) {
    data[j] = node.getResponseBuffer(j);
    floatData, dataOne= node.getResponseBuffer(j);
    Serial.print("\nHex data:");
    Serial.print(data[j], HEX);
    Serial.print(" ");
    Serial.print("\nDec data:");
    Serial.print(data[j], DEC);
    Serial.print("\nfloat data:");
    Serial.print(floatData);
    
    
  }
} else {
  Serial.print("Failed, Response Code: ");
  Serial.print(result, HEX);
  Serial.println(" ");
  delay(5000); 
}
delay(1000);
}

Result:-

Success, Received data 0: 
-> Hex data:648F 

-> Dec data:25743

-> float data:25743.00⸮

Solution

  • As Bosz suggested in the comments above, the first thing you need to do is read two Modbus registers instead of 1. So change:

    result = node.readHoldingRegisters(3036,1);
    

    to:

    result = node.readHoldingRegisters(3036,2);
    

    Then you need to work with both registers and combine them to get the float you are looking for:

    if (result == node.ku8MBSuccess) {
    
    Serial.print("\nSuccess, Received data 0: ");
    
    for (j = 0; j < 2; j++) {
      data[j] = node.getResponseBuffer(j);
    }
    
    unsigned long temp = (unsigned long)data[0] + (unsigned long)data[1]*65536;
    floatData = *((float*)&temp);
      
    Serial.print(floatData);
    
    }
    

    This conversion should work for any FLOAT32 values on your device's register list.

    This particular problem has been discussed in several places, you can see for instance here.