How to Degug: ModBus + USR-TCP232-304 + PZEM-016

I am trying to use the ModBus binding to connect to a USR-TCP232-304 Ethernet to RS485 server, and on to a PZEM-016 ModBus electric meter.

Problem is that it doesn’t work.

With Wireshark I can see (and debug) the communication on the Ethernet level, so I assume the problem is on the RS485 level. Can anyone please give tips about how to debug that? It may be a problem with the transceivers on either side; but how can I tell which side is bad? Or it may be a data content error of some sort; so how could I debug that?

U could get a usb to rs485 adapter and send known signals through the device and see if they are ariving correctly.
Also you could use something like this to check what the electric meter is sending as data.
There are many different adapters available.

I have used Modbus Poll and Modbus Slave in the past. (But they have to be purchased after a trial period.)

On work i hav an opensource python tool for sending modbus test data to devices.
I can look up it’s name.

Many thanks @Confectrician for the tips. Unfortunately I think I wasted your time (sorry for that), because my problem was that the USR-TCP232 unit supports the ModBus RTU/IP protocol whereas the OH binding supports the ModBus TCP protocol(*); the messages were in fact getting through Ok, but the devices just couldn’t understand each other.

(*) the former is identical to ModBus RTU Serial whereas the latter adds a preamble code and deletes the CRC

Not much time wasted. Just stuff i had in mind immediately. So no problem. :slight_smile:

I have some experience with these USR gizmos (and find them reliable and effective, if fiddly for initial setup)

I’d rephrase your problem as - “this device is a generic serial gateway, and knows nothing about Modbus (or any other protocol really)”.

You can use this gizmo to pass Modbus traffic … if you can set up a means for a driver at your host end to “look like” a real serial port to the Modbus binding.
I have done this on a Windows, using USR supplied “VCOM” driver software that creates a virtual COM port. Binding then chats RTU serial to COM22 or whatever, driver does the TCP stuff to transparently deliver RTU to and from the physical serial port. The gizmo is just passing bytes and has no idea of any protocol involved.

I have no idea what you might do outside of Windows in lieu of that driver, sorry. You’d think it were possible with ser2net or suchlike, but no-one has admitted to trying it yet.

The best solution is a different model gizmo - the more upmarket versions are capable of acting as a true Modbus gateway, where you talk TCP to the gizmo and it takes care of TCP<->RTU conversions itself.
Current USR model for that is USR-232-410S

There are other makes, but again be aware of distinction between generic serial and real Modbus gateway capabilities.

Thanks @rossko57. I did also have a look at extending the ‘tcp’ Thing in the OH Modbus binding to have a Config Param to switch between talking the current ‘Modbus TCP’ protocol and the ‘Modbus RTU’ protocol. The ‘serial’ Thing already supports ‘Modbus RTU’ so in theory, all the pieces are already there, so it ought to be a trivial extension. But in practice, even after half a day’s work, I found the code to be so dense and abstracted that I couldn’t even figure out where to start. Perhaps someone else (e.g. @ssalonen :)) has a suggestion?

(off-topic discussing binding development)

@AndrewFG Unfortunately the modbus java library (jamod)used by the binding does not support RTU-over-TCP. I have investigated this at some point and I find it quite non-trivial change due to the way classes paired and organised in the jamod library…

One option could be to upgrade from jamod fork used by openHAB to a more recent and upgraded library like steveohara/j2mod, offering RTU-over-TCP. What makes things complicated is the varying incompatible libraries used to interact with serial devices in java. For example, j2mod uses serial abstractions/libraries which are not compatible with the openHAB world.

I can imagine the whole thing being quite overwhelming when looking at the code base. However, the transport and binding should be quite easy to adjust once the library part is sorted out.

If you interested to work on this, I’m happy give some further pointers and my comments on the topic, just send me a PM.

Comment: I doubt this simple serial gateway actually supports Modbus RTU-over-TCP anyway. So far as I know, it just passes any old bundle of bytes you like, so long as it is encapsulated in … what, I don’t know. RFC2217 perhaps? I have seen that one mentioned in USR docs.

@rossko57 the unit passes “any old bundle” as you say; and obviously that includes Modbus RTU bundles. It does also support RFC2217 which would potentially allow an OH binding to determine by software the comms parameters that it uses to forward that bundle onto its serial port. However it also supports manual configuration via a webui of the comms params.

So to reiterate, what you need is a piece of software on your host system that presents a virtual serial port to the Modbus binding and sends/receives RFC2217 to the remote serial gateway.

Or, a Modbus gateway.

Hi,
I use socat on linux to create a virtual serial port, then run modpoll to test serial devices.
Using a USR–TCP232-302 device.

socat notes for serial line sniffer

Create a PTY with socat - note, cd to /tmp as the log files will be wriien in the current directory.

$ socat /dev/ttyUSB1,raw,echo=0 SYSTEM:‘tee input.txt | socat - “PTY,link=/tmp/ttyV0,raw,echo=0,waitslave” | tee output.txt’

Run the serial command, using the PTY

$ modpoll -m rtu -b 9600 -p none -a 2 -r 1 -c 1 -t4:float -1 -f /tmp/ttyV0

modpoll 3.4 - FieldTalk™ Modbus® Master Simulator
Copyright © 2002-2013 proconX Pty Ltd
Visit http://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: Modbus RTU
Slave configuration…: address = 2, start reference = 1, count = 1
Communication…: /tmp/ttyV0, 9600, 8, 1, none, t/o 1.00 s, poll rate 1000 ms
Data type…: 32-bit float, output (holding) register table
Word swapping…: Slave configured as big-endian float machine

– Polling slave…
[1]: 0.000000

$ od -h input.txt
0000000 0302 0004 0000 c900 0033
0000011

$ od -h output.txt
0000000 0302 0000 0200 38c4
0000010

$ modpoll -m rtu -b 9600 -p none -a 2 -r 513 -c 2 -t4:hex -1 -f /tmp/ttyV0
modpoll 3.4 - FieldTalk™ Modbus® Master Simulator
Copyright © 2002-2013 proconX Pty Ltd
Visit http://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: Modbus RTU
Slave configuration…: address = 2, start reference = 513, count = 2
Communication…: /tmp/ttyV0, 9600, 8, 1, none, t/o 1.00 s, poll rate 1000 ms
Data type…: 16-bit register (hex), output (holding) register table
Word swapping…: Slave configured as big-endian float machine

– Polling slave…
[513]: 0x0000
[514]: 0x0000

=======================================

@rossko57 thanks for your support. Yup those are two of the options. A third one is to extend the OH binding to use RTU transfer encoding over IP. I am actually working with @ssalonen on this right now.

Hi @Robert_Brady many thanks for this tip. As you can see from the above, I now have four options for solutions. I had in fact tried to use socat already, but failed, probably due to wrong configuration.

Since this is really about sending any old jumble of bytes over IP, and is not Modbus specific, but rather about packaging a serial packet to RFC2217 or whatever it is you need … it seems to me this would be more appropriate and generally useful as an extension to the underlying serial libraries, or as an alternative virtual serial port feature.

There might be something to be gleaned from previous efforts to remotely drive USB zwave sticks and such over IP.

In general, I’ll still maintain you’ve just got the wrong gateway product for the job here. :wink:

Hmm. That is an interesting thought. But it is probably not as simple as you suggest. As background you need to know the following…

  • The OH binding org.openhab.binding.modbus is in the openhab/addons repo.
  • It depends on the OH transport layer interface library org.openhab.core.io.transport.modbus in the openhab/core repo.
  • Which in turn depends on the OH adopted fork of the ModBus transport library net.wimpi.modbus (aka jamod) in the openhab/jamod repo.
  • Which does NOT depend on the “the (OH) underlying serial libraries”

Furthermore I personally feel no great motivation to implement RFC2217 on top of this all, since the serial port can be set up in a one time configuration step.

So my approach is to work on extending the binding; if you are interested to see what I have done so far, please look at the git:compare links below; as you can see, it entails three changes as follows…

  1. Minimal extension of the binding to add a boolean choice between ‘Modbus TCP’ encoding (existing) and ‘ModBus RTU’ encoding (new).

  2. Minimal extension of the OH core to forward this boolean down from the binding to the underlying jamod transport library.

  3. Add an RTU over TCP transport class to the ModBus jamod library. Essentially this class is a copy/paste/merge of parts of the existing “Modbus RTU over Serial” and “Modbus TCP over TCP” transport classes.

https://github.com/openhab/openhab-addons/compare/main...andrewfg:modbus-rtu-ip

https://github.com/openhab/openhab-core/compare/master...andrewfg:modbus-rtu-ip

https://github.com/openhab/jamod/compare/master...andrewfg:modbus-rtu-ip

1 Like

I have an USR-DR302 which I could setup after many trials as TCP server on port 502. After doing that I could communicate with my modbus meter using the standard modbus binding. Here are screenshots of my configuration:
image
image

1 Like

For the record as well to this old thread. The binding nowadays also supports modbus rtu over tcp.

Hi everybody,

I am planning to replace the modbus USB adapter with a TCP one so that I move OH in a docker swarm.
I am planning to use this this : USR-DR302 . Or, you you have better recommendation (it need to be DIN rail).
Does it mean that all slave devices that I already have should work in the same way ?

Thank you.

I use the USR TCP 232-304 which works fine. Your proposed DIN rail version looks like it could be based on the same hardware, so I suppose it would work fine too.

Great! Thanks a lot.