Is it possible to build a modbus-RTU ethernet gateway using a linux box or arduino?
I have plc slaves linked together using modbus RTU, and I want to connect one of them over TCP with my pc as master.
I wonder if I can use a linux box (rasbery pi/raspbian) connected to a router, as a modbus-to-tcp converter by piping the usb port to my local ip on some port, as one plc will be connected in modbus rtu to the linux box`s usb port.
Piping command will be something Like this:
nc -l 5626 > /dev/ttyUSB0 < /dev/ttyUSB0
My goal is to connect a pc (networked with the linux box) to that plc through the linux box using modbus.
Yes you can use a linux box with ethernet port.
Its not a simple 'nc' is it.
First things first, you need to know, Does your PLC's support Modbus TCP or Modbus RTU over TCP.
bcos both the formats are not the same, they are not interchangeable.
once you ascertain this, you need to write a TCP Client to Connect to the Slaves as they run the Servers.
If they don't support Modbus TCP yet, you need to write a TCP servers as well.
on top of that, you have the handshaking delays and half open connections and what not.
If it is a commercial device, you need to look at the setup it will be running as well.
Hope this helps
I'm not entirely sure as to what your requirements are, but you may want to have a look at the following library. It's a Modbus TCP->RTU library I assume you can use.
https://github.com/3cky/mbusd
Best Regards
While it's certainly possible to build a Modbus TCP/RTU gateway, you won't be able to do it with a simple nc command, for two reasons:
The actual Modbus protocol data unit (PDU), merely containing the Modbus function code and data, is embedded in an application data unit (ADU) so the request reaches the correct device free of communication errors. This ADU is different for RTU and TCP. Generically, the ADU looks like this:
------------------------------------------
| Additional address | PDU | Error check |
------------------------------------------
For RTU, the "Additional address" is a single byte identifying the unit/slave on the serial line, and the "Error check" is a 16-bit CRC.
For TCP, the "Additional address" is the 7-byte Modbus application protocol header (MBAP), consisting of transaction identifier, protocol identifier, and a length field (2 bytes each), plus a single byte identifying the unit/slave (usually 255, though for a gateway, this would be the ID of the RTU slave behind it). The "Error check" is empty (zero bytes) as that is already taken care of by TCP.
The communication semantics are different for RTU and TCP.
For RTU, you write a request to the serial line, wait for the reply, and only then write the next request. There must be 3½ characters of silence between frames.
For TCP, you can in principle have multiple connections being served concurrently. If you tried to forward two TCP requests to the serial line simultaneously, chaos would ensue.
Still, you can build a working gateway with a slightly more complicated program than nc:
Accept connections on TCP port 5626 (note that the actually recommended port number for Modbus TCP is 502), convert the received TCP ADUs to RTU ADUs and put them into a queue together with a back channel.
Another part of your program takes one item at a time from that queue, sends the ADU over the serial line and reports the result back through the back channel. Then it goes on the to the next item, and so on.
The results arriving on the back channels are converted to TCP ADUs and sent back on the respective TCP connection.
This would certainly work on a Raspberry Pi, and possibly also on Arduino, depending on how large you want your queue to be.
Sources:
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
Related
I'm setting up a traffic generator using pktgen-DPDK. What am having a hard time understanding is why DPDK plays a part when sending packets. From what I understand, when the receiver gets a packet and have their system configured to handle it using DPDK the NIC will send the packet to the app directly which then uses DPDK to do packet processing there (by passing inefficient Kernel network layers). So why do the transmitter also need to use DPDK for this? And how does it alter the packets that are being sent?
Here is an example to explain my thinking:
A transmitter is trying to send an image to receiver. The image is divided into small packets, which uses IP and TCP to get the packet from transmitter to receiver. After the packets have traveled over the internet, they finally get to the receiver. The receiver has configured their system to use DPDK, bypassing some Linux Kernel network layers. Through this the packet processing becomes faster.
Based on this example above, I don't see the point of using DPDK for sending packets or even how it would play a part in that. When we send packets, do we not simply use some protocols like TCP and IP to make sure the packet get where it needs to.
What is wrong with the example I'm giving and how could you rephrase it to be correctly?
I am an embedded software developer who has any experience with TCPIP on connected devices. Also, I am not a software protocol expert, so I am a bit confusing about TCPIP protocol stack + responsiblities of its various phy layers.
First of all, I have experiences with such protocols like UART, SPI, CAN, USB... As you know, the phy layer directly affects you while selecting the protocol you used at the software level. For example, if you use usb and you build a software protocol on it, you do not occasionally deal with some details like checking corrupted frame in your sofware protocol, because phy layer of it guarantees this operation. CAN also has some CAN Controller facilities like crc and bit stuffing so, it is really reliable. But the situation is not the same for simple peripherals like UART/USART. Let's say you are using a bluetooth module to upgrade your firmware, you need to be aware of almost everything that can occur while communicating like delays, corrupted frames, payload validating etc.
Briefly, i am trying to understand the exact role of newtork interfaces come included in MCUs, that are interfaced with RJ45 phy sockets directly. In another words, imagine that I wrote a server application on my pc. Also i configured and ran an application in my development board which has an RJ45 socket and it runs as a client. Also imagine they established a connection over TCP. So, what will be the situation at the client side, when i send a 32 bytes of data to the socket from the server side? What will I see at the lowest level of MCU that is an RxCompleteInterrupt()? Are the data I sent and some other stuffs appended to the TCP packet guaranteed to be delivered by the eth controller in the MCU and ethernet controller of my PC? OR am i responsible (or the stack i used) check all the things necessary to validate whether the frame is valid or not?
I tried to be as clear as it would be. Please if you have experience, then try to write clean comments. I am not a TCPIP expert, maybe I used some wrong terminology, please focus the main concept of the question.
Thanks folks.
If you don't have any prior experience with the TCP/IP protocol suite, I would strongly suggest you to have a look at this IBM Redbook, more specifically at chapters 2, 3 and 4.
This being said:
So, what will be the situation at the client side, when i send a 32
bytes of data to the socket from the server side? What will I see at
the lowest level of MCU that is an RxCompleteInterrupt()?
You should have received an Ethernet frame in your buffer. This Ethernet frame should contain an IP packet. This IP packet should contain a TCP packet, which payload should consist in your 32 bytes of data. But there will be several exchanges between the client and the server prior to your data to be received, because of TCP being a connection-oriented protocol, i.e. several Ethernet frames will be sent/received.
Are the data I sent and some other stuffs appended to the TCP packet
guaranteed to be delivered by the eth controller in the MCU and
ethernet controller of my PC? OR am i responsible (or the stack i
used) check all the things necessary to validate whether the frame
is valid or not?
The TCP packet will ultimately be delivered, but there there are not warranties that your Ethernet frames and IP packets will be delivered, and will arrive in the right order. This is precisely the job of TCP, as a connection-oriented protocol, than to do what is needed so that the data you are sending as a TCP payload will ultimately be delivered. Your MCU hardware should be the one responsible for validating the Ethernet frames, but the TCP/IP stack running on the MCU is responsible for validating IP and TCP packets and the proper delivery of the data being sent/received over TCP.
You can experiment with TCP on a Linux PC using netcat, and capture the exchange using Wireshark or tcpdump.
Create a 'response' file containing 32 bytes:
echo 0123456789ABCDEFGHIJKL > response.txt
Start Wireshark, and filter on lo interface using filter tcp port 1234
Start a TCP server listening on TCP port 1234, which will send the content of response.txt upon receiving a connection from the client:
netcat -l 1234 < response.txt
In another console/shell, connect to the server listening on tcp/1234, and display what was received:
netcat localhost 1234
0123456789ABCDEFGHIJKL
On Wireshark, you should see the following Wireshark Network Capture, and be able to expand all frames/packets of the full exchange using the IBM Redbook as a reference.
Your 32 bytes of data will be in the payload section of a TCP packet sent by the server.
So I was curious if this is possible at all. Currently i have a program running in a micro controller (digi rabbit) that reads SPI data from a chip. I also have TCP/IP protocol set in this program so it sends the SPI data to the server. Microcontroller is programmed in C. Server is in java. I convert SPI data into string and send it over, the server reads the raw data.
But i wanted to know if there is a way that I can read the data from Ethernet port. So what i want is one end of cat 5 cable on micro controller and the other on Ethernet port of the computer. Just for testing purposes that micro controller port and everything is installed properly, before i turn on the server. I am not that experienced with networking. So if anyone can point to a blog, or any tips that would be great. My question is how would i go about it?
Thank You
What you want to do is called raw Ethernet. Of course this can be done.
On the microcontroller side you need to follow its Ethernet controller datasheet to send out and receive packets. On the PC side this is a bit more complicated and depends on the OS that is running on the PC. On Windows you can use the WinPcap driver to send and receive raw Ethernet packets.
Be aware, that both Ethernet controllers, the one on the PC and the one on the microcontroller, filter all incoming packets that do not contain the receivers MAC address or any multicast/broadcast address. For a simple check the broadcast address (all address bits are 1) will do.
Also note, that the OS on your PC will transmit all kind of packets as soon as the link is established. So you may use a unique protocol identifier in the type field of your raw Ethernet frame. Check Wikipedia's article about Ethernet frames. Btw. don't get confused. You only need to send MAC-adresses, Ethertype and the payload. Everything else, like the CRC, preamble etc., is added by the Ethernet controller automatically.
I develop a network program that is used to transfer files , it works . But I just know it can works , and I don't know how to monitor and evaluate it . So I want to know what aspects a network program usually need to consider and monitor and how to monitor .
First make sure which protocol you have been used to send files (either TCP or UDP).
1.If you are using TCP at transport layer ,at the receiving end you can use TCPDUMP
packet analyzer to analyze all packets receiving on TCP port and its content.
2.If you want to analyze packets irrespective of protocols used at different layers, you can use wireshark packet analyzer to analyze all packets received on different networks like ethernet,PPP, loop back ,frame relay. you can use IP address of sender host as a reference to extract packets ( you need some reference to extract packets because wire shark will return all the packets received on the NIC interface). Once you extract the packets received from your sender host, you can analyze the packet payload to check whether files content has been received properly or not.
3.you can redirect data ( payload) of all received packets into some file. Once your program is done with receiving packets, you can check with that file to check data has been properly received or not. ( you can use this method only to test your client/server programs within a system)
I have a simple xbee network operating where there are a bunch of slaves operating remotely and all talking to one master, who is connected to the server computer. That works no problem.
The slaves all send their ID as part of the packet and I'd like to have the master deliberately send an Ack after a delay. I'm trying to figure out how to do this efficiently and it seems that the only plausible way that doesn't involve reprogramming the master before each Ack is to send the Ack to all slaves and have them ignore the packet if it's not meant for them.
That solution is ok - I just can't figure out the command to use to do this. Is there some sort of Serial sendAll command? All of the devices are on the same ATID.
Typically in this situation, you would configure the master in API mode so you would get "Receive Explicit" frames with source addressing information, and could send with the "Transmit Explicit" frame type, and include addressing information in your frames.
If you use AT mode (transparent serial mode), then you're stuck having to change the DH and DL parameters on your coordinator every time you want to change who you send to. You should avoid using broadcast packets, since each one results in lots of network traffic (IIRC, each router will send the broadcast packet three times).
I do not know of a good XBee library on the Arduino, but it might be possible to port Digi's Open Source ANSI C XBee Host Library to that platform.