Help Needed: Reading GoodWe Smartmeter GW3000 via RS485 with Arduino Uno and MAX485

Hello everyone,

I need assistance with reading data from a GoodWe Smartmeter GW3000 via the RS485 interface using an Arduino Uno and a MAX485 module. My goal is to read the watt data from the smart meter. Here is my current setup and the code I have so far:

Schematic:

**1.Arduino Uno:**
    RX (Pin 0) -> DI (MAX485)
    TX (Pin 1) -> RO (MAX485)
    GND -> GND (MAX485)
    5V -> VCC (MAX485)
    DE and RE (MAX485) -> Pin 2 (Arduino, for control)

**MAX485 Module:**
    A -> RS485 A (Smartmeter)
    B -> RS485 B (Smartmeter)
    GND -> GND (Smartmeter)

Code:

#include <ModbusMaster.h>

ModbusMaster node;

void preTransmission() {
  digitalWrite(2, HIGH);
}

void postTransmission() {
  digitalWrite(2, LOW);
}

void setup() {
  pinMode(2, OUTPUT);
  Serial.begin(9600);
  node.begin(1, Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;
  uint16_t data[6];

  result = node.readInputRegisters(0x0000, 6);
  if (result == node.ku8MBSuccess) {
    for (int i = 0; i < 6; i++) {
      data[i] = node.getResponseBuffer(i);
    }
    Serial.print("Watt: ");
    Serial.println(data[0]);
  } else {
    Serial.print("Error: ");
    Serial.println(result);
  }

  delay(1000);
}

Thank you in advance for any suggestions or guidance!

You can't use same serial for serial monitor and rs485. If you are limited to use arduino uno, you need to use softwareserial for rs485.

Like this?

#include <SoftwareSerial.h>

// Definiere die Pins für SoftwareSerial (MAX485)
SoftwareSerial max485Serial(10, 11); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // Warte auf die serielle Verbindung
  }

  max485Serial.begin(9600);
  Serial.println("Smart Meter Goodwe GM3000 Initialisierung...");
}

void loop() {
  if (max485Serial.available()) {
    String data = max485Serial.readStringUntil('\n');
    Serial.println("Empfangene Daten: " + data);
  }

  if (Serial.available()) {
    String debugData = Serial.readStringUntil('\n');
    max485Serial.println("Debug: " + debugData);
  }
}

Try with that, for sure you don't get any modbus communication.
Show your wiring.
Code would be like this.

#include <ModbusMaster.h>
#include <SoftwareSerial.h>

// Define software serial RX and TX pins
#define RX_PIN 2
#define TX_PIN 3

#define MAX485_DE_RE 4


// Create a SoftwareSerial instance
SoftwareSerial mySerial(RX_PIN, TX_PIN);

ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_DE_RE, 1); 
 
}

void postTransmission()
{
  digitalWrite(MAX485_DE_RE, 0); 
  }

void setup()
{
  pinMode(MAX485_DE_RE, OUTPUT);
    
  digitalWrite(MAX485_DE_RE, 0);
  Serial.begin(9600);
  mySerial.begin(9600); // Initialize software serial port

  node.begin(1, mySerial); // Use software serial for Modbus communication
  
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop()
{
  uint8_t result;
  
 
  result = node.readInputRegisters(0x0000, 2);
  
  if (result == node.ku8MBSuccess)
  {
    Serial.print("1st reg: ");
    Serial.println(node.getResponseBuffer(0));  
    Serial.print("2nd reg: ");
    Serial.println(node.getResponseBuffer(1)); 
  } 
  else 
  {
    Serial.print("Modbus Error: ");
    Serial.println(result);
  }

  Serial.println("\n ------------  \n ");

  delay(1000);
}

and post your modbus protocol sheet.

Like your code so:

Arduino Uno MAX485 Modul

5V ----------------> VCC

GND ----------------> GND

2 (RX_PIN) --------> RO

3 (TX_PIN) --------> DI

4 (MAX485_DE_RE) --> DE

4 (MAX485_DE_RE) --> RE

A ------------------> A (RS485 Bus)
B ------------------> B (RS485 Bus)

now i have a modus 226 error

It means, you have no response.
Post a photo of your wiring and gw3000 modbus protocol.


My Setup looks like this.

Thats the problem i know only it has rs485 and no protocol i hope that is the same like outher smart meters.

Then post a protocol "of your hope". And a photo that we can see clearly wiring between arduino and rs485 module.

I post it tomorow i am Not in the Workshop anymore



I have it like this and i know it uses modbus and i need to read the regsiter 35172.

#include <ModbusMaster.h>
#include <SoftwareSerial.h>

// Define software serial RX and TX pins
#define RX_PIN 2
#define TX_PIN 3

#define MAX485_DE_RE 4

// Create a SoftwareSerial instance
SoftwareSerial mySerial(RX_PIN, TX_PIN);

ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_DE_RE, 1); 
}

void postTransmission()
{
  digitalWrite(MAX485_DE_RE, 0); 
}

void setup()
{
  pinMode(MAX485_DE_RE, OUTPUT);
  digitalWrite(MAX485_DE_RE, 0);
  Serial.begin(9600);
  mySerial.begin(9600); // Initialize software serial port

  node.begin(1, mySerial); // Use software serial for Modbus communication
  
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop()
{
  uint8_t result;
  
  // Read register at address 35172 (0x8974)
  result = node.readInputRegisters(0x8974, 2);
  
  if (result == node.ku8MBSuccess)
  {
    Serial.print("1st reg: ");
    Serial.println(node.getResponseBuffer(0));  
    Serial.print("2nd reg: ");
    Serial.println(node.getResponseBuffer(1)); 
  } 
  else 
  {
    Serial.print("Modbus Error: ");
    Serial.println(result);
  }

  Serial.println("\n ------------  \n ");

  delay(1000);
}

From where you got that register address?

in five digit modbus numbering system 35172 means input register nro 5172 (first reg is 30001). That would be 0x1433 in hex.

Your wiring looks correct, but jumper wires and breadboard is bringing reliability next to nothing. So we don't know if that part is ok.

If expect that your problem is not right register address. If that device respect modbus standard, it should give response even if that register is empty or not allowed.
So I think that you have wrong slave address or hardware problem.

Edit:
I did quick research and found tiny evidence that slave address could be 3.

I have the register from this german page.

grafik
It gives me this.

The registers in your link were from inverter, not from meter.
Did I understand correctly that you try to read the meter?
Like this:
image

As long as error is 226, you have no communication.

Yes i want to read a smart meter like this.

Let's try to follow that tiny evidence I found.
Slave 3 and read holding regs instead of input.

#include <ModbusMaster.h>
#include <SoftwareSerial.h>

// Define software serial RX and TX pins
#define RX_PIN 2
#define TX_PIN 3

#define MAX485_DE_RE 4


// Create a SoftwareSerial instance
SoftwareSerial mySerial(RX_PIN, TX_PIN);

ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_DE_RE, 1); 
 
}

void postTransmission()
{
  digitalWrite(MAX485_DE_RE, 0); 
  }

void setup()
{
  pinMode(MAX485_DE_RE, OUTPUT);
    
  digitalWrite(MAX485_DE_RE, 0);
  Serial.begin(9600);
  mySerial.begin(9600); // Initialize software serial port

  node.begin(3, mySerial); // Use software serial for Modbus communication
  
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop()
{
  uint8_t result;
  uint8_t j;
  
 
  result = node.readHoldingRegisters(0x005E, 10);
  
  if (result == node.ku8MBSuccess)
  {
    
for (j = 0; j < 10; j++)
    {
      Serial.println(node.getResponseBuffer(j));
    }

  } 
  else 
  {
    Serial.print("Modbus Error: ");
    Serial.println(result);
  }

  Serial.println("\n ------------  \n ");

  delay(1000);
}

I tryied this code and i have also error 226 ):