Modbus RTU Communication Failed

So, I have two different environments running OpenEMS Edge on Raspberry Pi 5. Here are the two setups:

First Pi setup:

  • Running OpenEMS Edge jar
  • This Pi is local to my network
  • Running ModbusServer Pro simulator on my MacBook Pro (Modbus Server - AppHugs)
  • One USB to RS485 converter connected to my Mac (Amazon.com)
  • The other USB to RS485 converter connected to a USB port on the Pi
  • Bridge Modbus/RTU Serial is enabled on OpenEMS Edge
  • My custom Deye ESS device code is able to read and write to the ModbusServer Pro simulator on my Mac
  • The ModbusServer Pro simulator is able to send and receive values to and from the OpenEMS Edge on the Pi
  • In addition, I have a small snippet of Python code running on the Pi that is also able to read and write to the ModbusServer Pro simulator running on my Mac

All good!!!

Second Pi setup (remote):

  • Running same OpenEMS Edge jar
  • This remote Pi is connected to an actual inverter using this USB to RS485 cable (https://www.amazon.de/dp/B0BZLT35J7?smid=A193ZWXZZR1JVT&ref_=chk_typ_imgToDp&th=1)
  • Bridge Modbus/RTU Serial is enabled on OpenEMS Edge with similar settings as other Pi
  • Custom Deye ESS code is also enabled on this Pi
  • An error shows in the logs stating “Modbus Communication failed”
  • The same Python test snippet is able to communicate with the inverter over the same USB port
  • We’ve also tried other cables with not success

To recap, two different Pi’s running the same OpenEMS Edge code but only one of them can communicate properly via Modbus RTU.

I have tried using Wireshark but I am having issues getting it to work on Linux for some reason. I would be willing to try other tools to see if I can get more detailed information on the error.

So, my question is, are there other logs, code, tools, or methods I can look at to try and figure out why the second Pi is unsuccessful in communicating over Modbus serial?

In case anyone is interested, here is a snippet of Python code for reading Modbus over serial for testing. Code originally from this source: GitHub - The-Intrigued-Engineer/RPi-Minimal-Modbus-Sensor

import minimalmodbus # Don't forget to import the library!!
import time

mb_address = 1 # Modbus address of device

inverter = minimalmodbus.Instrument('/dev/ttyUSB0',mb_address)  # Make an "instrument" object called sensy_boi (port n>

inverter.serial.baudrate = 9600                         # BaudRate
inverter.serial.bytesize = 8                                    # Number of data bits to be requested
inverter.serial.parity = minimalmodbus.serial.PARITY_NONE       # Parity Setting here is NONE but can be ODD or EVEN
inverter.serial.stopbits = 1                                    # Number of stop bits
inverter.serial.timeout  = 0.5                                  # Timeout time in seconds
inverter.mode = minimalmodbus.MODE_RTU                          # Mode to be used (RTU or ascii mode)

# Good practice to clean up before and after each execution
inverter.clear_buffers_before_each_transaction = True
inverter.close_port_after_each_call = True

print(inverter) # Print out all the properties of the inverter

for i in range(700, 721):
    multiData = inverter.read_registers(i, 1, 3)
    myHex = hex(multiData[0])
    print (f"{i}, '{myHex}', {multiData[0]}")
    time.sleep(0.15)

# Piece of mind close out
inverter.serial.close()

Could you maybe try openEMS Version 2024.1.0 and check if it works?

See Changelog in 2024.2.0 here:

Also i saw, that your cable is for the BMS not for an EMS, which COULD be the error… Please check:

  1. Your Cable (maybe try to read the registers manually with Python first using your cable)
  2. Your Code (are the right registers added?)
  3. openEMS Version Downgrade

For Deye you need to use 1+2 or 7+8 see here:

I guess your cable is for BMS (Pin 4+5) and that is the Issue here

Interesting catches, Sn0w3y. I will focus on both of your comments and report back. Thanks again.

Just to follow up on your bulleted list…

  1. Your Cable (maybe try to read the registers manually with Python first using your cable)
  • Confirmed: i can read the registers manually using Python using the existing cable
  1. Your Code (are the right registers added?)
  • Confirmed: I have limited the Deye implementation code to only read/write registers that are confirmed to be correct for the Deye inverter
  1. openEMS Version Downgrade
  • Not yet attempted
1 Like

The issue was in my code based on my incorrect assumptions from using a Chinese to English translated Modbus table document. Going to continue to test to be 100% sure, especially with writing to the registers. I’ll follow up with the outcome over the next few days.

1 Like

Reading and writing to the Modbus registers working great now. I will continue with the process of implementing this inverter. Not sure where to allow a user to configure items such as Time of Use Selling settings (could be in the OpenEMS Edge Configuration area or maybe something to do with Apps).

Thanks for all of the help.

1 Like