-
Notifications
You must be signed in to change notification settings - Fork 0
Modbus Reader. Reads modbus data and sends that to an mqtt server.
License
mats-bergstrom/mbrdr
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
mbrdr -- Modbus Reader Reads data from a Huawei SUN2000 Solar Inverter and publishes the data using MQTT. This program is intended to be running on a Raspberry Pi. Regarding the Huawei SSUN2000, the on-line fora are full of suggestions on how to read out data with confidence but no real good infomration seems to be available. The Huawei responces indicate they do not have any idea why reading data using modbus sometimes works, sometimes not. After experimening, I managed to cook up an algorithm that seems to work (so far). In pseudo code it looks like: 1 Establish a TCP connection. 2 Sleep 5 s. 3 For each parameter to read 4 read a parameter 5 send a modbus package 6 read the responce with a timeout of 5 s. 7 sleep 2 s before reading the the next parameter I.E. the modbus slave (renamed server some time ago) cannot cope with incoming requests too quickly. 1: It needs a delay of several seconds after a TCP connection is established bef ore the first request is received, too quick and it does not respond at all, 5 s seems to have a very log failure rate. 2: The slave also needs a very long time before it responds, using a 5 s time-out gives a very low failure rate. 3: Requests must be separated by a long duration. 2 s gives a very low failure rate. Note that ANY fault in the timing or using the wrong modbus id results in no responce at all (time-out). Also, if the device status is "Idle" (state code=0xa000) some parameters are not red out correctly, e.g. the internal temperature and on top of this, reading too many times will fail. To avoid that the program closes the TCP connection and reopens it. To provide an inverter in the 1500-2000 USD range with this kind timing issues and other quirks is really weird. I used libmodbus for the modbus communication. It works great but as I prefer static linking for this I added a few scripts to build and create a static library to link with. A description of the modbus registers for my inverter (SUN2000-10KTL-M0) can be found in: https://www.photovoltaikforum.com/core/attachment/180219-solar-inverter-modbus-interface-definitions-v3-0-pdf/ To build: git clone https://github.com/mats-bergstrom/mbrdr.git cd mbrdr make-cfgf make-libmodbus make To control: sudo systemctl start mbrdr sudo systemctl stop mbrdr sudo systemctl status mbrdr -n 100 Options: -v Verbose mode. -n No-active mode. Does not send mqtt topics. -m No-modbus mode. Does not read modbus. The config file: # Configuration for mbrdr # broker address port mqtt id mqtt 127.0.0.1 1883 mbrdr-test # # modbus data slave address port slave id modbus 127.0.0.1 502 1 # # Time outs (s) connect read write delays 5 5 2 # # Intervals between reads in a given state (s) # ACTIVE IDLE STANDBY intervals 120 900 120 The mqtt and modbus lines should be self explanatory. The delays line sets the delay after a connect, the read time out and delay between TCP writes to read a parameter. The intervals are the intervals between the modbus device is polled for data when it is in the ACTIVE, IDLE, and STANDBY states. The parameters to read out and publish are in a hard-coded table (see below) add/remove/change according to your needs. typedef struct { uint16_t addr; /* modbus address to read */ uint16_t len; /* no of words to read */ uint32_t gain; /* gain of data */ conv_t conv; /* data type and conversion */ const char* fmt; /* format conversion */ const char* topic; /* topic of data */ } param_t; param_t tab[] = { /* Always have status first */ { 32089, 1, 1, conv_U1, "%02x", "sun/status" }, /*must be 0*/ { 32087, 1, 10, conv_F, "%.1lf", "sun/internalTemp" }, /*must be 1*/ { 32080, 2, 1000, conv_F, "%.3lf", "sun/activePower" }, { 32064, 2, 1000, conv_F, "%.3lf", "sun/inputPower" }, { 32106, 2, 100, conv_F, "%.2lf", "sun/accEnergy" }, { 32114, 2, 100, conv_F, "%.2lf", "sun/dailyEnergy" }, { 0,0,0,0,0,0} /* Terminator */ };
About
Modbus Reader. Reads modbus data and sends that to an mqtt server.
Topics
Resources
License
Stars
Watchers
Forks
Releases
No releases published