3

I am using a Pi4B to try to read data from a SDM630 energy meter. Because the meter is far from the Pi I us a HF2211 ethernet to RS485 converter to bridge the distance. the HF2211 is in transparent mode so the payload of the ethernet messages is forwarded to the RS485 bus. This setup is already working good for my PV inverter with Modbus interface. I hooked up the energy meter to the other side of the RS485 bus.

to start I generate a virtual serial device on the Pi (virtual communication) with socat.

sudo socat  pty,link=/dev/sdm, raw tcp:172.17.x.y:8899 &

so now I have a virtual serial device that talks to my ethernet <=> RS485 converter.

next I call minimalmodbus

device = minimalmodbus.Instrument('/dev/sdm', 1, debug = True)
device.serial.baudrate = 9600
print (device)
print ( device.read_register(2))

the result is

MinimalModbus debug mode. Create serial port /dev/sdm
minimalmodbus.Instrument<id=0xb61a5cf0, address=1, mode=rtu, close_port_after_each_call=False, precalculate_read_size=True, clear_buffers_before_each_transaction=True, handle_local_echo=False, debug=True, serial=Serial<id=0xb61a5d10, open=True>(port='/dev/sdm', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=0.05, xonxoff=False, rtscts=False, dsrdtr=False)>

and

MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 00 00 01 84 0A (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/sdm
MinimalModbus debug mode. No sleep required before write. Time since previous read: 18336983.37 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument:  (0 bytes), roundtrip time: 0.1 ms. Timeout for reading: 50.0 ms.

and

Traceback (most recent call last):
  File "/home/domotica/scripts/python/sdm-test.py", line 24, in <module>
    print ( device.read_register(0, 0))
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 486, in read_register
    payloadformat=_Payloadformat.REGISTER,
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1245, in _generic_command
    payload_from_slave = self._perform_command(functioncode, payload_to_slave)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1322, in _perform_command
    response_bytes = self._communicate(request_bytes, number_of_bytes_to_read)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1490, in _communicate
    raise NoResponseError("No communication with the instrument (no answer)")
minimalmodbus.NoResponseError: No communication with the instrument (no answer)

what did I check

  • there are no overlapping Modbus addresses used
  • I tried various numbers of the registers and numbers for number of decimals
  • Socat creates a device called /dev/pts/number. this device is owned by root, I change the owner to pi, which is running the program.
  • config parameters of the RS485 devices are all 9600,8,1,N
  • proper connection and termination of the bus
  • traffic on the bus with scope, yes there is traffic with expected voltages, but is looks like only the Master is talking, no response from the Slave.
RobD
  • 91
  • 1
  • 7
  • 1
    Try requesting two registers (e.g. `device.read_registers(2,2)`). I have no experience with the SDM630 but have seen similar units that will only return pairs (as [the manual](https://www.eastroneurope.com/images/uploads/products/protocol/SDM630_MODBUS_Protocol.pdf) says " Data must be requested in register pairs"). You might also consider using [RTU over TCP](https://pymodbus.readthedocs.io/en/latest/source/example/changing_framers.html ) (avoiding the need to create `/dev/sdm`) or using the ModbusTCP server in the HF2211 (meaning you use Modbus TCP and the HF2211 converts to RTU). – Brits Aug 26 '22 at 02:18
  • 1
    I already did that ```device,read_register(2, 2)```. no result. I have been thinking about using Modbus TCP. the thing is that I then have to rebuild my PV program, because the PV inverter and the SDM630 are on the same Modbus line – RobD Aug 26 '22 at 07:31
  • 1
    In that case you probably need to start with first principals (connect directly to the device and see if you get a response and go from there). The cause could be anything from RS485 termination upwards. – Brits Aug 27 '22 at 01:38
  • 1
    I suppose it's pretty obvious but since you did not mention it in your question I will ask it: have you verified the meter works by hooking it to a Modbus master and trying to read? A proper cable can get you very far with RS485. Another thing that I found to be at fault with this kind of Ethernet-to-Modbus conversion is the ID number of the slave, you might want to try to use Modbus broadcast address. Is there some mention of that in the manual? – Marcos G. Aug 27 '22 at 08:12
  • 1
    @MarcosG. from the comments above it appears that there are two units on the bus (the SDM630 and a PV inverter) so an issue with the device or cabling is my first guess too. I believe the HF2211 is running in "TCP Server" mode so it should not be touching the data (just passing whatever it receives directly out via 485 - It's not acting as a ModbusTCP server). The [manual](https://www.eastroneurope.com/images/uploads/products/protocol/SDM630_MODBUS_Protocol.pdf) states "The Eastron Digital meters do not support the broadcast address". – Brits Aug 27 '22 at 09:56
  • 1
    Thanks Brits, in my (limited) experience it's not easy to find Modbus gateways that handle correctly the slave ID field. Actually, some devices set the ID on all messages to 0, if this is the case here the setup will never work. – Marcos G. Aug 27 '22 at 11:43
  • 1
    thank you for all comments. yes the HF2211 is in TCP servermode so not touching the payload. to cabling: the total cablelength is limited to under 10 meters. it is CAT6 cable. it should do the trick, with or without termination. During my experiments the communication whith the PV inverter kept running. and I connected a scope to the cable and saw nice block lines as for the communication with the PV inverter as well as the command I send from my Pi to the SDM630. – RobD Aug 27 '22 at 15:00
  • 1
    One extra thing to add: I have 2 Pi's - one production unit that runs the Python program to handle the PV - one test pi on which I run the tests to the SDM630. Either – RobD Aug 27 '22 at 15:01
  • 1
    I stopped the communication from the ProdPi to the PV and changed the HF2211 protocol to MODbus. In this case I can talk ModbusTCP from the Test Pi to the HF2211 avoiding the virtual device with socat. ```device = sdm_modbus.SDM630(host="172.17.116.65",port="8899") print (device) print ("connected?: ", device.connected()) ``` also no result. Either I am sending nonsens to the SDM so it won't answer or something else is bugging me. I ordered a new HF2211A so that I can seperate Production and test invironments completely and I start over again when the new device is received. – RobD Aug 27 '22 at 15:09
  • 1
    @marcosG The HF2211 is handling in transparent mode my units number without problem. the PV units is set to 247 and is running fine. the SDM is set to 1 so should be no prob. – RobD Aug 27 '22 at 15:12
  • 1
    Minimalmodbus is not supporting Modbus TCP so I use the sdm-modbus library. – RobD Aug 27 '22 at 15:14
  • 1
    I see... I'm still a bit confused with regards to your setup, are you able to test the meter with any Modbus library or maybe QModMaster or something similar (on a laptop or a Pi) connecting it directly: `laptop (or Pi)<-->USB-to-RS485<-->wire<-->meter`? Based on what you way it seems reasonable for the problem to be on the meter's Modbus port. I would also try reading both input and holding registers. – Marcos G. Aug 27 '22 at 15:47
  • 2
    Another thing I frequently find with bridges is that they screw timing and some slaves are very sensitive, since you have a scope I would try to measure the time it takes for the bus to idle after a query. – Marcos G. Aug 27 '22 at 15:53
  • 1
    I don't know if I have a USB to RS485 converter lying around. I'm afraid not. Yes I can test with any library. Either from the (test)Pi or from my Windows Laptop. – RobD Aug 28 '22 at 10:56
  • 1
    wow this QmodMaster is a cool tool. now I can see what is going on on the bus. thanks! – RobD Aug 28 '22 at 11:07
  • Yes, it's a very useful tool indeed. Good luck with debugging. – Marcos G. Aug 28 '22 at 11:49
  • 1
    might be a stupid question but do these modbus libraries handle the CRC calculation? In my transparent mode (for the PV installation), I handle everything in the Python Program, so CRC calculation, endianness etc. I expect these libs to take care of all this overhead so that I only have to take care of the adressing of the registers. Am I right? – RobD Aug 28 '22 at 12:23
  • 1
    Yes, you are correct, all Modbus libraries I know handle everything for you. Apps like QModMaster too. Otherwise, they would not be of much use I guess... Endianness you might want to swap it in the library just in case your devices are different than the default (that happened to me more than once). – Marcos G. Aug 28 '22 at 13:16
  • 1
    problem solved. I don't know what happened the first time but when I rebuild the test configuration on my workbench, it worked right away. I use the modbus add-on in Home Assistant to read the relevant registers. Thanks for all your support. – RobD Oct 03 '22 at 10:12
  • Damn, how do I detect if any data is being sent on the modbus? `instr.serial.in_waiting` nothing, but when I `sudo screen /dev/serial0` there is indeed data. How can this screen program just automatically work with ZERO PARAMETERS. Yet for 3 days I can try EVERY PARAMETER of Serial and Instrument, and it can't ********* work ? – MathCrackExchange Jul 10 '23 at 03:53
  • 1
    @DanielDonnelly please ask this as a new question (referencing this one if it is relevant). Note that "sent on the modbus" does not make a lot of sense (I suspect you mean 'sent via the serial port') – Brits Jul 10 '23 at 03:57
  • @Brits I solved my issue, so if anyone is having this same issue. Minimalmodbus library is meant for master's only. So since PyModbus is too slow on the Pi Zero, you're left to implement your own Modbus protocol in your slave code. You do this with a pyserial serial.Serial instance, be wary of all the parameters - what you need them to be - and if you're using RX/TX pins for UART you have to enable that doing `sudo rasppi-confg` under Interfaces / Serial. In that case you would need rtscts=True as a Serial parameter, or get errors thrown sometimes. Hope this helps! – MathCrackExchange Jul 10 '23 at 14:58
  • [...] Also, if you install the "screen" console program using apt (used for reading device data and displaying on screen), you can do: `sudo screen /dev/serial0 9600` e.g. to see if your connected test master (polling (writing) a register with data) is indeed sending and your PiZero is seeing it. You can't have your program also connected when screen is running on that device, so reboot and now try your code. Also if your Master has a limited number of polling loops, then plug/unplug your master's power to restart polling or you'll see no data. – MathCrackExchange Jul 10 '23 at 15:01
  • Once you do the `raspi-confg` step with the hardware setting enabled, you can use either '/dev/ttyS0' or '/dev/serial0' on the PiZero, since I was able to - they both point to the same thing now. We happend to have some modbus implemented on the Pico for memory reasons, it was a simple translation to replace machine.UART (Pico / MicroPython) with serial.Serial (PiZero / Linux). – MathCrackExchange Jul 10 '23 at 15:02

0 Answers0