MODBUS single register writing via RS485

Dear members,

I have a solar inverter, where I want to read and write few registers. I am using an MKR RS485 shield for that. The registers to read the data from work as intended, however, when I want to write the register, it doesn't work. Reading the registers gives me the voltage, currrent, temperature, and SOC of the battery. Writing the register is actually to set the value to charge or discharge the battery. A snap is attached from the inverter manual. My sketch is also given below. Currently, I am writing a value of 0xB4 to charge the battery with 180 watts. But it doesn't work. Can someone please tell me what I am doing wrong?

Furthermore, to discharge the battery with 180 watts, do I need to write the value 0xFF4C?

Thank you for the assistance.

#include <ArduinoModbus.h>
#include <RS485.h>

void setup() {
  
  Serial.begin(9600);
  while(!Serial);

  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to connect");
    while (1);
  }
}

void loop() {

  if (!ModbusRTUClient.requestFrom(0x01, HOLDING_REGISTERS, 0x3000, 4)) {           
    Serial.print("failed to read data! ");
    Serial.println(ModbusRTUClient.lastError());           
  } else {
    uint16_t word1 = ModbusRTUClient.read();                 
    Serial.print(word1/10);
    Serial.println(" V");
    int16_t word2 = ModbusRTUClient.read();
    Serial.print(word2/10);
    Serial.println(" A");
    int16_t word3 = ModbusRTUClient.read();
    Serial.print(word3/10);
    Serial.println(" C");
    uint16_t word4 = ModbusRTUClient.read();   
    Serial.print(word4);
    Serial.println(" %");
  }

  delay(1000);

  ModbusRTUClient.holdingRegisterWrite(0x01, 0x405A, 0xB4);
  
  delay(1000);
}

How do you know?

Because I have the app from the inverter and it shows 0 watts. It means battery is not charging. Furthermore, I tested to discharge the battery with 180 watts. I have a load that is 180 watts powered by grid and measured by energy meter. Now, if I discharge the battery with 180 watts, the meter should show 0. For discharging, I used the command:

ModbusRTUClient.holdingRegisterWrite(0x01, 0x405A, 0xFFC4); // 0xFFC4 = -180

but the same result.

Without programming (i.e. with default values) does the battery charge? How do you know that the charging circuit is working?

I haven't tested charging but discharging does work. Because I disconnected the grid and connected the load to the backup port of the inverter to power up my load and that worked. Regarding the discharging command, is it correct? I mean the 0xFFC4 (for -180 watts).

To answer questions like that, I would have to see the entire device manual.

RS485 Communication Protocol-Inverter.pdf (818.4 KB)

Here is the inverter manual.

That is not a manual. That is just a software protocol document.

I have it in hard form, but I have a presentation from the inverter manufacturer. Basic Introduction to Hybrid Inverter SMT-10K-TL-TH(1).pdf (3.5 MB)

The two statements seem to contradict...

I haven't tested charging without coding. You asked me how do I know if the charging circuit works.

I asked that, because you say that the charging doesn't work...

Then I misunderstood you. I haven't tested charging the battery without microncontroller, but I did test the battery discharging without mc and it works. I am now trying to charge and discharge the battery via the sketch I showed but it won't work.

what is "mc"

  1. What are your test conditions?
  2. How do you determine whether it works, or doesn't work?

Please understand that you haven't told us much.

microcontroller, i think the short form is written as uc.

No, to properly communicate that, you would say something like "the MCU" or "the CPU" depending on the system.

Ok, thanks for the correction :slight_smile:

You have to explain how you reached the conclusion that it doesn't work. Not in a vague sentence or paragraph with no context. You have to step up and guide us through the process.

Actually in my sketch, I am reading the battery voltage, current, state of charge and temperature. I can see these values on the Serial Monitor. Voltage = 205 v, Current = 0 A, Temperature = 30 C, SOC = 100%. These values match to the values that I can see on the app of the inverter on my mobile phone.

Now, how do I know if the discharge command does not work?

When I send a charge or discharge command then there must be current flowing into or out of the battery. And I should read that current value on my Serial Monitor, however, the current value remains 0 A on both Serial Monitor and the inverter app. So, this is how I am concluding that the charge and the discharge commands doesn't work.

Aren't the charge and discharge currents also dependent on the source and load? For example, you can't "set" the discharge and expect current to flow if, for test, you disconnected the load...