GoodWe GM1000D smartmeter Modbus esp32-Wroom-32s

Hi!

I'm trying to communicate with my GoodWe inverter using the meter port, [this document ] (https://forum.iobroker.net/assets/uploads/files/1666333836822-goodwe_modbus_protocol_hybrid_et_eh_bh_bt__arm205-hv__v1.7-_-read-only_20200226-1.pdf), [this document] (https://downloads.vodnici.net/uploads/wpforo/attachments/483/4349-1GoodweModbusPROTOCOLHybrid-ENV1-3EMseries.pdf),


, an ESP32-WROOM-32S, the modbusmaster library and a XY-017 rs485 ttl converter. But, I can't get it to work. The only id not showing error "Invalid slave ID" is 3, so I assumed that is probably the id I'm looking for. But using id 3 gives me timeout issues.

the XY-017 RS485 side GND is connected to the GND of the inverter (tried it without gnd too, didn't make a difference)
RX -> RX
TX--> TX

The code looks like this;

#include <ModbusMaster.h>

ModbusMaster node;
int i;
int winningId = -1;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600, SERIAL_8N1, 16, 17);
  
  // Serial1.setTimeout(2000);
  
  node.begin(3, Serial1);
  //node.begin(85, Serial1); 
  //node.begin(193, Serial1); 
  
  int i = 0;
  

}

void loop() {
  // node.begin(i, Serial1);
  uint8_t result;
  uint16_t data[1];
  
  result = node.readHoldingRegisters(36044, 1); //Meter protocol version
  // result = node.readHoldingRegisters(0x050E, 1); // Battery SOC
  // result = node.readHoldingRegisters(306, 38); // Inverter request
  if (result == node.ku8MBSuccess) {
    data[0] = node.getResponseBuffer(0);
    Serial.println("Protocol version: ");
    Serial.println(data[0]);
    winningId = i;
  } else {
    Serial.println("Error code: ");
    Serial.println(result);

    switch(result) {
      case node.ku8MBIllegalFunction:
        Serial.println("Illegal function");
        break;
      case node.ku8MBIllegalDataAddress:
        Serial.println("Illegal data address");
        break;
      case node.ku8MBIllegalDataValue:
        Serial.println("Illegal data value");
        break;
      case node.ku8MBSlaveDeviceFailure:
        Serial.println("Slave device failure");
        break;
      case node.ku8MBInvalidSlaveID:
        Serial.println("Invalid slave ID");
        break;
      case node.ku8MBInvalidFunction:
        Serial.println("Invalid function");
        break;
      case node.ku8MBResponseTimedOut:
        Serial.println("Response timed out");
        break;
      case node.ku8MBInvalidCRC:
        Serial.println("Invalid CRC");
        break;
      default:
        Serial.println("Unknown error");
        break;
    }
    
    i += 1;
    Serial.print("new i: ");
    Serial.println(i);
    Serial.print("winning id: ");
    Serial.println(winningId);
    
  }
  // delay(2000);
  delay(1);
}

I logged the master request from the inverter via the meter port using the following code;

#include <SoftwareSerial.h>

SoftwareSerial  rs485(16,17);

void setup() {
   
   Serial.begin(9600);
  
   rs485.begin(9600);
}

void loop() {
   while ( rs485.available() > 0 )  {
     Serial.print(rs485.read());
     Serial.print(" ");
  }
  
}

I found that the inverter is sending the following request to the smart meter: 3 3 1 50 0 38 101 193 which would indicate that it is trying to reach the smart meter with slave id 3, using function code 03H at address 306 expecting 38 bytes right? I tried sending this exact request.

The goal is to simulate the GM1000D smart meter so I can be in control of the data being sent to the inverter. Any help is appreciated!

Hi @artons98 ,

Welcome to the forum..

You printed in decimal not hex..

converting to hex, looks like..
Field Name (Hex)
Slave Address 3
Function 03
Starting Address Hi 01
Starting Address Lo 32
No. of Points Hi 00
No. of Points Lo 26
Error Check (CRC) Hi 65
Error Check (CRC) Lo C1

Good luck.. ~q

Hi @qubits-us,

Thanks! So does that mean that I was right about the inverter trying to reach the smart meter with slave id 3 (0x03), using function code 03 (0x03) at address 306 (0x0132) expecting 38 (0x0026) bytes?

That means this should work right?;

#include <ModbusMaster.h>

ModbusMaster node;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600, SERIAL_8N1, 16, 17);

  node.begin(3, Serial1);  //Slave id 3 (0x03)
}

void loop() {
  uint8_t result;
  uint16_t data[38]; //Make room for 38 bytes
  
  result = node.readHoldingRegisters(306, 38); //Address 306 (0x0132), expecting 38 bytes (0x0026)
  if (result == node.ku8MBSuccess) {
    data[0] = node.getResponseBuffer(0);
    Serial.println("Protocol version: ");
    Serial.println(data[0]);
    winningId = i;
  } else {
    Serial.println("Error code: ");
    Serial.println(result);

    switch(result) {
      case node.ku8MBIllegalFunction:
        Serial.println("Illegal function");
        break;
      case node.ku8MBIllegalDataAddress:
        Serial.println("Illegal data address");
        break;
      case node.ku8MBIllegalDataValue:
        Serial.println("Illegal data value");
        break;
      case node.ku8MBSlaveDeviceFailure:
        Serial.println("Slave device failure");
        break;
      case node.ku8MBInvalidSlaveID:
        Serial.println("Invalid slave ID");
        break;
      case node.ku8MBInvalidFunction:
        Serial.println("Invalid function");
        break;
      case node.ku8MBResponseTimedOut:
        Serial.println("Response timed out");
        break;
      case node.ku8MBInvalidCRC:
        Serial.println("Invalid CRC");
        break;
      default:
        Serial.println("Unknown error");
        break;
    }   
  }
  delay(2000);
}

It turns out I was using a faulty XY-017 module. It was getting extremely hot by just powering it of of 3.3v. After switching to a new one everything worked fine.
Only thing to do now is find out what data I'm looking at. So if anyone happens to know where I can find the GoodWe Smart Meter Protocol...... haha, anyway... thanks so far!

no not really..
slave id 3, function 3..
starting address Hi is 01, Lo is 32, think that's like 288 dec..
number of points is 26 hex which is 38 decimal..
the 38 points refers to 38 registers, each modbus registers is a word 2 bytes..
so it would be 38 x 2 for how many bytes..

sorry about the faulty unit..
hope the new one is good..

got a copy of the Modbus protocol doc here..

good luck.. ~q