简体   繁体   中英

RS485 Modbus Commmunication

I have been trying to acquire electrical parameters from my energy meter using Arduino through Modbus communication. But my code fails to get the data from the meter. In this code, I'm trying to get the phase voltage value from the energy meter whose register address is 12.

  #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(9600);  
    //slave ID 1  
    node.begin(1, Serial);  

    Serial.println("Starting Modbus Transaction:");  
    node.preTransmission(preTransmission);  
    node.postTransmission(postTransmission);  
  }

  void loop() {
    static uint32_t i;
    uint8_t j, result;
    uint16_t data[10];

    i++;

    result = node.readInputRegisters(0x30012,2);

    Serial.println("");
  
    if (result == node.ku8MBSuccess) {
      Serial.print("Success, Received data: ");
      for (j = 0; j < 2; j++) {
        data[j] = node.getResponseBuffer(j);
        Serial.print(data[j], HEX);
        Serial.print(" ");
      }
      Serial.println("");
    } else {
      Serial.print("Failed, Response Code: ");
      Serial.print(result, HEX);
      Serial.println("");
      delay(5000); 
    }
    delay(1000);
  }

You are using the wrong Modbus function. You should be using function 0x03 readHoldingRegisters (note the 0x03 at the beginning of the frame on the bottom side of the page).

Just change this line:

result = node.readInputRegisters(0x30012,2);

to:

result = node.readHoldingRegisters(12,2);

By the way, there must be something else wrong with your setup because the error code you are getting is 0xE2 and you should be getting 0x02 meaning Ilegal Data Address or maybe 0x01 ( Illegal Function ) depending on the meter's firmware. Maybe you should double-check the baud rate.

You might also need to set the ID of the node to 0xAA in your setup loop with:

node.begin(170, Serial);

as someone commented above. The documentation is not very good...

If you look at what looks like an example data command at the bottom:

aa 03 0001 003C 0DC0

It looks like aa is the slave address, 03 the function code as discussed above, and 003C is the number of registers to read (60 to read all data from the meter in one go). The last two bytes 0DC0 should be the CRC.

If that's correct then you should consider reading register 11 and 12 instead of 12-13 if you want to get the phase voltage:

result = node.readHoldingRegisters(11,2);

Again, that's just my best guess to fill the gaps on the documentation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM