tobiasfaust / SolaxModbusGateway

Modbus RTU to MQTT Gateway
GNU General Public License v3.0
55 stars 17 forks source link

suggestions for improvement #1

Closed uham999 closed 1 year ago

uham999 commented 1 year ago

I recently discovered your SolaxModbusGateway work. I congratulate you on your very interesting high quality work. Based on my experience trying to use this tool, I have a number of suggestions for you that if implemented would make it easier to use. In the modbus::init() function it would be useful to be able to set the serial2 RX and TX pins using private class variables in modbus.h to set the pins. On the ESP32 board I use, the default pins for Serial2 are in use for other purposes so the default pins can't be used. For example in modbus.cpp :- Serial2.begin(this->Baudrate,SERIAL_8N1,this->RXpin,this->TXpin);

Another problem I noticed was the documentation as written for setting up the RS485 Invertor suggests the following connections RS485 Inverter

A -> Pin 4 B -> Pin 5

In reality, the Inverter and the ESP32 have to have a common ground so the ESP32 Gnd needs to connect to the Solax inverter Gnd otherwise it will not work at all or not reliably. I could be wrong but I didn't see anything saying that this is the case. GND on the Solax X1-Hybrid is pin 6 according to page 61 in the user manual for it. RS485 Inverter

A -> Pin 4 B -> Pin 5 GND -> Pin 6 Solax X1 Hybrid

Another thing I noticed is that you do not use an RS485 direction control pin. I'm not sure why it works in your situation without it. It doesn't work with the RS485 breakout board that I used because there is no direction control. Although I have been using microcontrollers for a long time, RS485 is new to me so there could be something that I don't understand. On the TTL to RS485 breakout board I have, it is necessary to set the direction control pin correctly. In simple test programs it works well using the direction pin. If I don't use the direction pin, it doesn't work. For your configuration I can only assume that you use a special board that automatically handles the direction for you? It would be useful if it could be programmed to work with a more basic RS485 board. The RS485 board I have is shown on this page :- https://microcontrollerslab.com/rs485-serial-communication-esp32-esp8266-tutorial/ In my case, I connect the RE and DE pins together and connect them to a direction pin on the ESP32. Whenever you want to transmit the program takes to direction pin HIGH and when receiving data, put the direction pin LOW. One I use the direction pin in test programs, then transferring data between two ESP32 devices is straight forward.

In your test application test_RS485_Solax_ESP32.INO, you have comments that looks like you have tried something like this. //#define RX 17 // D1 =5 // 10 //Serial Receive pin //#define TX 16 // D2 = 4 //Serial Transmit pin //#define RTS_pin 9 //RS485 Direction control //#define RS485Transmit HIGH //#define RS485Receive LOW

The final suggestion I have is that an implementation writing to the Solax X1 Hybrid write registers from MQTT would be very useful for my application and maybe for other people. I have to keep a number of inverters synchronized with the same configuration so having each ESP32 subscribe to an MQTT topic so it can receive a configuration from the MQTT broker would be a useful function. The ESP32 could then write changes to the inverter registers.

I can potentially help with work like this because I have reasonable programming skills although I have never used GitHub before. regards Steve

tobiasfaust commented 1 year ago

Hi Steve,

thanks for your very useful hints. I will try to answer: 1) RX/TX Pins: I will add this in the next version, start of next year. In normal cases you are using an ESP32 with no other tasks so all pins are free ;) 2) common ground: i most cases the ground connection is not needed. The same for my case. It was not needed 3) direction pin: I have this RS-485 module: HW-0519 -> https://tasmota.github.io/docs/SolaX-X1/#breakout-boards This boards controls the direction by itself. But you are right, i will add the possibility of declaring a direction pin in next version 4) the possibility to send write requests sound really good. In my case the most wanted functionality was to read the values simply. I will add this functionality too in next release. I think its not difficult. But you can help my by find out the most wanted setting-functions with their registers and hex request. best regards

uham999 commented 1 year ago

Hi Tobias Thank you for clarification on HW-0519. It looks like that works the way I predicted.

In normal cases you are using an ESP32 with no other tasks so all pins are free ;) If only it was a perfect world ;)

I'm sure that there are many useful registers to write to that I haven't thought of but a starting point for registers I think would be most useful are:-

  1. Write single register function code 0x06 • 0x0020 - Manual mode. In some places, you can get paid a high rate to supply energy to the grid. I think register 0x0020 allows for this. I think that it allows a full power discharge regardless of demand. • Registers 0x0061 to 0x0070 control under what conditions manual charge and discharge can happen and when it can happen. This function seems to be partially duplicated in register function code 0x010 registers 0x001B to 0x001E - see below. Cheap electricity tariffs are available in some places at particular times of day. The time the cheap rates occur can even change on a daily basis. Being able to make use of cheap power to charge a depleted battery is useful. • Register 0x001F Solar charger use mode might be important for the above-described functions to work.

  2. Write multiple register function code 0x10 • Setting the clock 0x0000 to 0x0005 - I think that this might be necessary for the charge and discharge schedule to work. • Charge and discharge time 0x001B to 0x001E • Target state of charge 0x0083 - Charging Lithium batteries to 100% regularly is not a good idea so being able to set this is useful. regards Steve

tobiasfaust commented 1 year ago

Hi, We Need the complete Modbus Protocol Definition for Write Registers. Write Register are Not the Same as read Register. Can you take care of this?

uham999 commented 1 year ago

I can but not until the new year. I don't have access to the inverter until them.

tobiasfaust commented 1 year ago

Point 1 ( configurable tx and tx Pin) and 3 (Direction pin) solved. https://github.com/tobiasfaust/SolaxModbusGateway/commit/5e461dc3542e69d2bb068ccf357f743a9bae36c0

tobiasfaust commented 1 year ago

I´m currently implementing "set" commands. To test this, i need at least the complete command for TargetBatterySOC to set

{ "name": "TargetBatSOC", "request" : ["#ClientID", "0x06", "0x00", "0x83"] }

so maybe the final hexstring to set the value to 70% is:

0x01 0x06 0x00 0x83 0x00 0x46 <crc>

Can you confirm? What is a successful and a failure answer?

The most perfect situation if you can share the official Solax modbus write register documentation to me

uham999 commented 1 year ago

I will shortly be able to test this for you. Today, I am having two new inverters with batteries installed in my test environment. Once that installation work is complete, I will be able to test with the Solax-X1 hybrid. The other new inverter is a Growatt SPH3000 so should be able to test that too when the time comes.

uham999 commented 1 year ago

I have a version 3.07 of the Solax manual. My version seems to be more complete than the later version 3.14 version you have uploaded to the docs directory. Although your uploaded manual is a later version than mine, I can't see reference to function code 0x06 register 0x0083 in the v3.14 manual. Is the version 3.14 uploaded truncated? The v3.14 version of the manual as uploaded doesn't include the write registers accessed using function code 0x06 or 0x10. In my manual v3.07 it says TargetBatterySOC is of type Uint16 and written to using function code 0x10 rather than the function code 0x06 that you used. I would say that the final hexstring to set the TargetBatterySOC value to 70% is: 0x01 0x10 0x00 0x83 0x00 0x46 I will be able to test soon.

tobiasfaust commented 1 year ago

i found a new one. I updated the doc to version 3.21 by a00a7a8. Now all single write registers (0x06) are included.

Ability to send SET Comands implemented by eda3923, but notice, not full tested yet. Feel free to support me by your tests