Does anyone have some sample code that reads and writes data to PLCs through XBee RS485 serial adapters (modbus RTU). I am a newcomer to Python and Digi and am looking for some code that works so I can test it with my application and figure out the basics for myself. I have looked through some of the wiki pages such as “how to create read requests from Modbus RTU” but I cannot see how to easily execute them within a larger Python program.
My application consists of a ConnectPort X4 which is set-up to collect temp/humidity data from six XBee LTH Sensors and feed the values through to six separate PLCs using Modbus RTU. I also want to collect register values from the PLCs.
I already have a discovery program written which finds and labels the sensors and adapters and then periodically collects the TH values from the sensors but I am struggling with the Modbus/Rs485 read and write part.
I would appreciate any and all help.
Thank you,
Neil
My rather massive Modbus code add-on for the Dia platform is here:
http://www.digi.com/wiki/developer/index.php/Modbus_Dia_Code_Add-On
The problem is it gets complex fast. All of my code uses a UDP socket on local host 127.0.0.1 to talk with the normal Digi gateway “IA/Modbus Bridge”, which offloads the timing and details to remote XBee and TCP/UDP servers/clients.
In truth, when writing Modbus out to the XBee 485 Adapter, all of the complexity is related to the comms and timing/timouts. Modbus is just a binary string and could be any protocol. Make sure you get the XBee 485 set correctly, as explained here:
http://www.digi.com/wiki/developer/index.php/XBee_RS-485_Adapter
http://www.digi.com/wiki/developer/index.php/Modbus_Example_Serial_Adapter
To talk out the direct serial port, you can find code samples in dia\lib\digi_serial.py.
If you have the XBee 485 set up correctly, then you read/write to much like you’d read/write to a UDP Socket. The Python Wiki has several examples of simple Ethernet to Xbee bridges. Here is one example:
http://www.digi.com/wiki/developer/index.php/UDP_to_XBee_Network
Great - Thank you!
Lots to look at there.
I have no problem assembling the modbus strings and I can see how the mbrtu_make_request( {‘dest’:1, ‘func’:3, ‘rdOffset’:0, ‘rcCount’:10}) from the wiki at http://www.digi.com/wiki/developer/index.php/How_to_create_Modbus/RTU_request_in_Python goes together but I am struggling with how that string gets sent to the wireless network.
I’ll let you know how it goes - thanks again!
Neil
Hi again Lynn,
Have spent a few days going through your code. Unfortunately some of it is lost on me due to its complexity and my lack of understanding.
I am still struggling!! I don’t know if I need such a complex set-up for my application - I want to read and write small amounts of data (2-4 bytes) to each of six Modbus nodes once every 3-5 minutes. I don’t want the data to go anywhere else - the read data will be used by my script toi change the write values to be sent back out to the nodes in the next set of writes - simple as that!
I’ve been able to create all of the necessary Modbus strings but cannot see how to bind them to an appropriate socket that will get the requests to the right nodes and read the responses.
I have looked through pages and pages of documentation, sample code and support threads and simply cannot see how to bind to the ZB mesh. I have seen how to bind to the serial port but not to the mesh to get at the RS485 adapters.
I saw your post (below) on another thread and wondered if this would be a solution for me but again I cannot see how to use Python to get the string to the localhost - is there a specific operand that I should use?
“So your Python can issue Modbus/TCP requests to localhost (127.0.01) and… direct ALL of the Modbus through a UDP socket on localhost (127.0.0.1) and then your Python would own the 232 channel”
I’d appreciate any input.
Thank you - Neil
The basic concept is here - but you’d create a client, not server. Your Python code would connect to UDP or TCP port 502 on localhost and use the Unit-Id to indicate which of your 1 of 6 remotes to poll:
http://www.digi.com/wiki/developer/index.php/Integrating_the_Digi_IA_Modbus_Bridge_to_Python
http://www.digi.com/wiki/developer/index.php/Modbus_Bridge_on_CPX4
So allow the IA/Modbus Engine to ‘own’ the XBee RS-485 adapters. Enable Modbus/TCP as both TCP and UDP on port 502 (2 masters), then route by slave-address/unit id to your six remote Modbus/RTU nodes by MAC address. This much you can actually test live by using an existing Modbus/TCP poller like ModScan32 or MDBus or an OPC server. The X4 will move your Modbus requests through the mesh for you.
You would create requests in Modbus/TCP form, setting the Unit Id as required. Then send via TCP or UDP port 502, blocking to wait for an answer. This is safe since the IA engine will return an error response if the slave fails to respond. UDP uses less system memory, but TCP works fine also.
The nicest thing about this is that your code can work concurrently with an OPC server.
Hello,
I’m very interested in the concept which you are talking about.
The idea is developing a python code that pools some Modbus slave devices (with different natures and modbus number of register ) using the integrated IA DIGI Modbus Brigde.
Can I use a local Python BBDD running on the ConnectPort?
Can I use a thread that reads this local BBDD and send data to external server, over internet?.
Is there any similar application developed for the ConnectPort X4 (a multi slave master that collect data and send it to exterior)?
Thank you very much!
Hi to everyone,
I don’t have never used DIGI tecnology, but I want to understand:
I need to create a communication between the PLC and the CPX4 gateway to collect data from the XBee nodes.
I can do it via TCP/IP or via MODBUS TCP/IP. In both cases, simply connect CPX4 with the PLC via ETHERNET cable or is DIGI One IA required?
Thank you!