Modbus RTU over TCP

1,167 views
Skip to first unread message

Darryl

unread,
Jun 7, 2011, 2:22:04 AM6/7/11
to modbus-tk
G'Day

I have just purchased an Ethernet to Serial device and I am trying to
move one of my scripts from Modbus RTU to Modbus RTU over TCP.

What the serial device at the end of the TCP link is expecting is:
2011-06-07 16:22:52,558 DEBUG modbus.execute PoolThread-
twisted.internet.reactor-1 -> 1-3-192-32-0-24-120-10

What is being sent is :
2011-06-07 16:22:24,717 DEBUG modbus.execute PoolThread-
twisted.internet.reactor-1 -> 0-1-0-0-0-6-1-3-192-32-0-24

Obviously there is some difference here. I think what I want to do is
to encapsulate the Modbus RTU over the TCP link. If anyone has any
advice on how to do this that would be appreciated

Thanks

Darryl, VK2TDS
Sydney, Australia

Luc JEAN

unread,
Jun 7, 2011, 3:18:10 AM6/7/11
to modb...@googlegroups.com
Hello Daryl,
The difference is that Modbus TCP and Modbus RTU are different protocol. The difference is more than the link (network or serial). The exchanged bytes are not the same.
I don't know how your converter is working but I guess that it needs to receive RTU packets over a socket.
This feature is not currently supported by modbus-tk but it should be quite easy to implement. In my opinion, the easiest path would be to create a new Serial interface that mimick the serial.Serial class of pyserial http://pyserial.sourceforge.net/pyserial_api.html#classes
Thanks to Python duck typing, you only need to implement what is needed by the RtuMaster class of modbus-tk.
I hope it helps
Best
luc

2011/6/7 Darryl <radioacti...@gmail.com>

Darryl

unread,
Jun 7, 2011, 3:40:16 AM6/7/11
to modbus-tk
Thanks Luc

The unit just sends the packets over a socket. I will have a look at
the code and see how I go. Otherwise I might just stay with the USB to
Serial converter and keep the computer local.

Darryl

On Jun 7, 5:18 pm, Luc JEAN <luc.j...@gmail.com> wrote:
> Hello Daryl,
> The difference is that Modbus TCP and Modbus RTU are different protocol. The
> difference is more than the link (network or serial). The exchanged bytes
> are not the same.
> I don't know how your converter is working but I guess that it needs to
> receive RTU packets over a socket.
> This feature is not currently supported by modbus-tk but it should be quite
> easy to implement. In my opinion, the easiest path would be to create a new
> Serial interface that mimick the serial.Serial class of pyserialhttp://pyserial.sourceforge.net/pyserial_api.html#classes
> Thanks to Python duck typing, you only need to implement what is needed by
> the RtuMaster class of modbus-tk.
> I hope it helps
> Best
> luc
>
> 2011/6/7 Darryl <radioactivenetwo...@gmail.com>

jlafr...@nobatek.com

unread,
Apr 15, 2014, 1:20:31 PM4/15/14
to modb...@googlegroups.com


Le mardi 7 juin 2011 09:18:10 UTC+2, luc a écrit :
 
This feature is not currently supported by modbus-tk but it should be quite easy to implement. In my opinion, the easiest path would be to create a new Serial interface that mimick the serial.Serial class of pyserial http://pyserial.sourceforge.net/pyserial_api.html#classes
Thanks to Python duck typing, you only need to implement what is needed by the RtuMaster class of modbus-tk.

Hi Luc and all.

I needed RTU over TCP as well so I tried this approach.

Here is a first draft: https://github.com/Jerome-github/modbus-tk/tree/dev_rtu_over_tcp

It contains a class to emulate the serial port on a socket (this is in utils.py) and a new rtuovertcpmaster_example.py file.

It seems to work in my rather limited use case. However, I'm convinced a lot of corner cases are forgotten, particularly timeout issues.

I'll update if I can do better. In the meantime, please send me your comments or contributions.

Thanks for all the work on modbus-tk, by the way.

--
Jérôme

Luc JEAN

unread,
Apr 15, 2014, 3:20:30 PM4/15/14
to modb...@googlegroups.com
Hello Jerome,

I've just had a quick look on your fork but it looks very good. Thanks for your contribution. 

I'll be glad to know what everyone think about it and to merge it on trunk if no one find a problem with this approach.

Best
luc


--
You received this message because you are subscribed to the Google Groups "modbus-tk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modbus-tk+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jérôme Lafréchoux

unread,
Apr 16, 2014, 4:07:13 AM4/16/14
to modb...@googlegroups.com
De : modb...@googlegroups.com
Envoyé : mardi 15 avril 2014 21:21
À : modb...@googlegroups.com
Objet : Re: Modbus RTU over TCP

> Hello Jerome,
>
> I've just had a quick look on your fork but it looks very good. Thanks for your contribution. 
>
> I'll be glad to know what everyone think about it and to merge it on trunk if no one find
> a problem with this approach.

Hi.

Integrating this shouldn't bring any regression since I don't touch existing code.

However, please note that this code is not complete and probably not safe either. Again, this was rather a first draft that happened to work in my case. I didn't even test connection loss, wrong register number, etc.

- There is only a master example, no slave
- I only created the methods that are called in the rest of the code, I may have missed some
- I'm not sure whether the port should be opened in __init__() or in open(), and whether it should be closed in close() or at instance destruction
- isOpen is not that useful. Should it be done differently ?
- I don't know about flushInput. Is this really what we want to do ? And flushOutput is just void as I didn't know what to fit in.
- More importantly, I kind of stubbed the whole timeout management. My test code works, but it might not be so secure. I tried to fit in the interCharTimeout / baudrate / timeout the rest of the code expects. This is a bit of a trick. We can live with this kind of trick if we don't want to modify the rest of the code, but the values I entered are more or less random. And I didn't think about the possible latency we can expect from the network connection.

This timeout issue is what bothers me the most. This is where I needed your feedback. I entered into Modbus two days ago, all of this is new to me. And I understand that in RTU, since there is no end of frame character, timeouts are critical.

Anyway, I'll be glad is this can be improved and made available to the community.

(Regarding the copyright notices, you can keep or reject them, I don't mind. I didn't take the time to check how the contributors (if any) are credited so I just added that quickly.)

Have a nice day.

--
Jérôme

Jérôme Lafréchoux

unread,
Apr 16, 2014, 10:33:51 AM4/16/14
to modb...@googlegroups.com

-----Message d'origine-----
De : Jérôme Lafréchoux
Envoyé : mercredi 16 avril 2014 10:07
À : modb...@googlegroups.com
Objet : RE: Modbus RTU over TCP

> - I'm not sure whether the port should be opened in __init__() or in open(), and whether it should be closed in close() or at instance destruction

Answering to myself.

On second thought, it is better the way it is, with the socket being opened only when a request is executed.

--
Jérôme

Jérôme Lafréchoux

unread,
Apr 18, 2014, 1:35:48 PM4/18/14
to modb...@googlegroups.com
Hi.

I just commited a fix : the timeout was set after the connection was opened...

I've been testing again in my own use case, and it seems to behave as expected in case of wrong IP/port, or connection loss.

I still don't really like the baudrate stub, but this is because we need to feed something to the caller. Unless the caller is modified, this is always going to look a bit dodgy.

And I don't know how it reacts to incomplete frames, since the baudrate / interCharTimeout is disabled.

Perhaps someone with a little more insight on RTU/Ethernet issues would have an opinion.

Enjoy the WE.

--
Jérôme

Jérôme Lafréchoux

unread,
Apr 22, 2014, 5:53:42 AM4/22/14
to modb...@googlegroups.com
Hi.

I've added a few changes to my branch.

- set is_open to False when closing socket
- use .name instead of deprecated .portstring

Note that the latter affects current code although the output should be identical. serial.portstr is deprecated. serial.name exists from python2.5. I could submit this specific commit separately.

Remarks/concerns/questions about my RTU over TCP implementation :

1/ The socket is kept open. I have the feeling that it would be better to open and close it each time a request is sent. Keeping it open might not be such an issue. Except the way the code is currently done in the SerialSocketEmulator, the timeout is not changed once the socket is open. So any call to set_timeout() after the port is open for the first time is useless.

Should we close the socket between requests and may we close the serial port too ? Should we keep the socket open, like the serial port, and ensure the timeout change is applied to the open socket (should be possible with a decorator without a change to RtuMaster) ? Should we act differently upon both serial and socket types (kills the idea of emulating the serial port, means we need to modify RtuMaster) ?

2/ I'm still unsure about the timeout management. I don't know how long would be needed. It might not be as obvious as in the COM port case. Where does the 3.5 come from in time.sleep(3.5 * self._t0) ? In the case of a socket, a sleep might not be reliable. It may require waiting for reply complete (along with a timeout). This also kills the serial port emulation concept.

My first attempts were with pyserial and I found the same limitation. RTU over TCP would only succeed with a sleep() of arbitrary length added between sending request and reading reply, otherwise the reply was not complete. There is a dev branch for a design rework to wait until the answer is complete, but it seems stalled.

3/ I don't know about flushInput and flushOutput. Any opinion ?

Thank you for your feedback.

--
Jérôme

Tomas V.

unread,
Nov 11, 2018, 3:27:57 PM11/11/18
to modbus-tk


Dne úterý 7. června 2011 8:22:04 UTC+2 Darryl napsal(a):

Tomas V.

unread,
Nov 11, 2018, 3:27:57 PM11/11/18
to modbus-tk


Dne úterý 7. června 2011 8:22:04 UTC+2 Darryl napsal(a):
G'Day
Reply all
Reply to author
Forward
0 new messages