epsilonrt / libmodbuspp

Much more than a C++ wrapper for libmodbus
https://epsilonrt.fr/modbuspp
GNU Lesser General Public License v3.0
73 stars 44 forks source link

Possibility of having RTU over TCP client connection to a Modbus slave #3

Closed chffelix closed 4 years ago

chffelix commented 4 years ago

Hello! First of all, thanks for your great work on libmodbuspp! The nice docs and examples made it very easy to get up and running to develop my first modbus application. Now I specifically need to implement a TCP client connection to a gateway with many RTU slave devices connected to it, so I need to establish a RTU over TCP client connection. From what I understood from the "virtual-rtu" branch and the "Server" and "Router" examples in the master branch it seems it only works for inbound connections. It seems though there is underlying support for RTU over TCP implemented. Is it possible to simply adapt it so we can have a "RTU-TCP" backend as well when instantiating the Modbus Master?

epsilonrt commented 4 years ago

Hi, the virtual-rtu branch is a development branch, you should not use it. A client is a MODBUS master. The Master class implements this functionality, this is a standard case, you just have to indicate how to connect your gateway to the master:

Master mb (Tcp, "127.0.0.1", "1502");

here we will connect to a gateway which runs at IP address 127.0.0.1 and on port 1502. then you add your slaves with addSlave() You can connect completely transparently to a server (a slave) through your gateway using the Unit Identifier field of the MODBUS TCP protocol. it is managed by the Slave class automatically. I invite you to read the reference document. See also the comments in the examples and doc.

chffelix commented 4 years ago

Hi! Yes.. I already use the master the way you say - like Master mb(Tcp, "192.168.0.10", "1502") - where 192.168.0.10 is a TCP to RTU gateway with many RTU slaves connected via serial -, and I already add the slaves specifying their slave ID with addSlave, but I understood that specifiying "Tcp" backend it will use a TCP APU, without the CRC part, right? What I actually need is to send a regular RTU datagram but over the TCP channel (commonly know as the "RTU over TCP" protocol). Is that possible as it currently stands or we would need a slightly modified backend? (I wonder something like 'RtuTcp' in place of 'Tcp' in the master instantiation). I had also raised a question in stackoverflow over this, maybe if you are interested and are active there as well it might raise awareness on your nice work: https://stackoverflow.com/questions/61791447/is-it-possible-to-implement-a-modbus-master-based-on-libmodbuspp-which-uses-rtu . Thanks!

epsilonrt commented 4 years ago

This does not comply with the MODBUS standard, it will never be developed in libmodbuspp, it is especially useless. It is up to the gateway to decapsulate the payload in the TCP frame and to encapsulate it in an RTU frame (with the CRC). The Modbus::Router class does this. What is a gateway?

chffelix commented 4 years ago

This gateway is just this device which receives the "RTU over TCP" (pure RTU datagrams just encapsulated onto TCP), strips off the TCP part and passes the RTU packet unchanged to the RTU device connected to its serial port. I think it might really be non-standard, but unfortunately it seems to be rather common in the market: https://control.com/forums/threads/confused-modbus-tcp-vs-modbus-rtu-over-tcp.37377/

At least it is nice to know it is really non-conforming and won't be implemented. Unfortunately the device exists and I'll have to adapt to it :/ Maybe using this fork of libmodbus as the underlying version for my to-be-adapted version of libmodbuspp: https://github.com/myssta/libmodbus/tree/unstable_rtutcp

There are several requests for the "original" libmodbus library in Github to implement this "RTU over TCP" scheme, but I found this one to appear the "cleaner" one, so I expect using his approach: https://github.com/stephane/libmodbus/pull/445

Thank you anyway for your attention!