stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.3k stars 1.71k forks source link

Add support for Modbus RTU Over TCP #192

Open marinonjalsson opened 10 years ago

marinonjalsson commented 10 years ago

Hi

It would be a good idea to add support from Modbus RTU Over TCP. I, for one, got device supporting that protocol and not Modbus TCP!.

Below are some statements from http://www.control.com/thread/1305797461

Where Modbus over TCP means a MODBUS RTU packet wrapped in a TCP packet.

Standard Modbus RTU is meant for transmission over serial lines (RS232 or RS485 are the most common). The message starts with a one byte Slave ID and ends with a two byte CRC. Sometimes the RTU message is run through a gateway onto ethernet without actually changing any of the bytes in the message. This is commonly called "RTU over TCP".

There is a different specification for Modbus TCP where the message bytes are modified to add the 6 byte MBAP header and remove the two byte CRC.

Best regards, Marinó

sq5gvm commented 9 years ago

Hi Marinó,

If you're interested in patching libmodbus you can grab "ugly patch that breaks the design guidelines of the beautiful original code" written by Johan Englund at https://groups.google.com/forum/#!msg/libmodbus/xm8S6MMDhgM/Qd97y9_mhwgJ I'm using his patch (updated for version 3.0.6 of libmodbus) successfully since ~February 2014. To see how to use it - please check referenced above changes in my branch of check_modbus nagios/icinga plugin.

regards Mirek (sq5gvm)

karlp commented 9 years ago

I'd like to get this as an option too. PyModbus lets you use arbitrary framers with arbitrary transports, it works quite well: https://pymodbus.readthedocs.org/en/latest/examples/changing-framers.html

I had been trying to use socat to setup a virtual serial port<->tcp port mapping, but was getting "Invalid Argument" errors from some syscall inside libmodbus. Worked around it by using pymodbus, but that's not as portable to small devices as libmodbus :)

stephane commented 8 years ago

Related to #257

stephane commented 8 years ago

When I see all the forks which implement that feature I think you are legion to want it!

cevatbostancioglu commented 7 years ago

So , i look around and still can'not found any implementation. i implemented myself , first i am opening tcp socket and listening. and then parsing manually modbus tcp packet , find slaveid , function etc. after that polling with modbus_new_rtu , reading there and putting that values in ctx->mb_mapping then calling modbus_reply function , everything works fine.

for every tcp packet , first 5 bytes is zero. than starting the frame. i don't know why. 0x < 00 00 00 00 00 06 01 03 04 02 00 01 > this packet offset is 7.

BUT some modbus IDE's(SCH ELECTRIC ION SETUP) , just sending this packet 0x < 03 03 0B C2 00 01 26 30 > this packet offset is also 7. but when i write query[offset + 1] like that , gives me nothing.

so , i parsed like , " if first index is zero or not", if it's zero parse this index like that and so on.

BUT i can't send data to ION Setup program , modbus library send errors like unknown functions etc.

so do you guys any idea how i can handle this problem ?

ElenRey commented 7 years ago

Hello, here is an article about Modbus over ethernet that I've found

Have anybody tested this software?

henkhoo commented 6 years ago

+1 for Modbus-over-TCP option please.

i also found http://www.modbusdriver.com/modpoll.html can do it with the -m enc ( Encapsulated Modbus RTU over TCP ) option.

v-zhuravlev commented 6 years ago

Sample implementation: https://github.com/stephane/libmodbus/pull/385

DmitriyVinogradov commented 5 years ago

Hello! I suggest a patch for use modbus over tcp and modbus over udp. patch.zip

DmitriyVinogradov commented 5 years ago

Thank. I wanted to stay within the library implementation.

сб, 3 нояб. 2018 г. в 4:38, Mike Purvis notifications@github.com:

Here's another example implementation: https://github.com/rscada/libmodbus/blob/master/modbus/modbus-udp.c

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/stephane/libmodbus/issues/192#issuecomment-435546796, or mute the thread https://github.com/notifications/unsubscribe-auth/AqDq7BlbokO8AfcKeY6hzvIaro_1E6IRks5urOWcgaJpZM4BbSKN .

ahmedyousri commented 4 years ago

Hello! I suggest a patch for use modbus over tcp and modbus over udp. patch.zip

how to apply the patch

DmitriyVinogradov commented 4 years ago

after applying the patch will be able to use modbus over tcp and modbus over udp. looks like that: //выбираем modbustcp - mbtcp, modbusovertcp - mbotcp, modbusoverudp - mboudp if(strcmp(ip.type, "mbtcp") == 0){ ctx = modbus_new_tcp(ip.ipaddress, ip.port); }else if(strcmp(ip.type, "mbotcp") == 0){ sprintf(service, "%d", ip.port); ctx = modbus_new_over_tcp_pi(ip.ipaddress, service); }else if(strcmp(ip.type, "mboudp") == 0){ sprintf(service, "%d", ip.port); ctx = modbus_new_over_udp_pi(ip.ipaddress, service); }

other functions are the same in the library

lss4 commented 3 years ago

after applying the patch will be able to use modbus over tcp and modbus over udp. looks like that: //выбираем modbustcp - mbtcp, modbusovertcp - mbotcp, modbusoverudp - mboudp if(strcmp(ip.type, "mbtcp") == 0){ ctx = modbus_new_tcp(ip.ipaddress, ip.port); }else if(strcmp(ip.type, "mbotcp") == 0){ sprintf(service, "%d", ip.port); ctx = modbus_new_over_tcp_pi(ip.ipaddress, service); }else if(strcmp(ip.type, "mboudp") == 0){ sprintf(service, "%d", ip.port); ctx = modbus_new_over_udp_pi(ip.ipaddress, service); }

other functions are the same in the library

The patch applies, but it doesn't seem to be working against 3.1.6. I'm getting these:

In file included from modbus.h:291,
                 from modbus.c:23:
modbus-over-udp.h:25:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   25 | void recbufclear();
      | ^~~~
In file included from modbus.h:291,
                 from modbus-data.c:26:
modbus-over-udp.h:25:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   25 | void recbufclear();
      | ^~~~
In file included from modbus.h:291,
                 from modbus-rtu.h:10,
                 from modbus-rtu.c:19:
modbus-over-udp.h:25:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   25 | void recbufclear();
      | ^~~~
In file included from modbus.h:291,
                 from modbus-tcp.h:10,
                 from modbus-tcp.c:58:
modbus-over-udp.h:25:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   25 | void recbufclear();
      | ^~~~

And these...

/usr/bin/ld: .libs/modbus-data.o:(.bss+0x0): multiple definition of `recbuf'; .libs/modbus.o:(.bss+0x0): first defined here
/usr/bin/ld: .libs/modbus-rtu.o:(.bss+0x0): multiple definition of `recbuf'; .libs/modbus.o:(.bss+0x0): first defined here
/usr/bin/ld: .libs/modbus-tcp.o:(.bss+0x0): multiple definition of `recbuf'; .libs/modbus.o:(.bss+0x0): first defined here

And the build fails here because linking fails.

Is there a usable implementation at the moment? I need to use this to deal with MODBUS RTU devices connected behind a Ethernet-RS485 converter that doesn't support protocol conversion (transparently converting MODBUS RTU to TCP and vice versa).

EDIT: I've made a fork that incorporated the changes from #445, and fixed some issues that I encountered during building. The fork now builds, and it looks like that implementation does work as intended. I'm able to correctly get data from a slave device connected behind a Serial-to-Ethernet converter without using protocol conversion (so MODBUS RTU messages are being used). This is tested on Linux.

damago1 commented 3 months ago

I think support for RTU OVER TCP is really needed because very many devices from reputable companies like WAGO or are working this way, and almost all cheap modbus-ip gateways are designed this way (rtu-over-tcp). They are simply dd'ing rtu traffic to tcp stream. I know that theoretically you can create virtual serial devices with something like this:

socat pty,link=/dev/virtualcom0,raw tcp:192.168.254.254:8080&

and than try to work with libmodbus over such connection but it is a) not clean, b) requires privilege escalation to create /dev/xxxx device and change it's attributes to world-readable.

I desperately need such version of this library that adds new_rtu_over_tcp function. I know there is some patch in the forums but I was not able to make this patch correctly.

If there are some religious reasons why this library does not support rtu over tcp then I can even pay somebody to make a fork of this project to add support for rtu-over-tcp in such fork.