Efficient polling of Modbus devices?

Epy

Lifetime Supporting Member
Join Date
Jul 2012
Location
no
Posts
376
I'm working with a MicroLogix 1400 controller (RSLogix Micro) and pulling some registers from several different Modbus RTU devices through Channel 0. I am using the MSG command to do this.

My question is, what is the best way to do this when you have both multiple devices and multiple chunks of registers to pull? I'm going to have 11 MSGs to send when it's all said and done...

I would think that the best way to do this is to wait x, do MSG 1, wait x, do MSG 2, wait x, do MSG 3, etc. i.e. spread the MSGs out evenly across a set period of time. Is this correct?

Any suggestions in general? Thanks
 
I agree with the general approach to put a small time delay in between messages.

I do this to prevent trouble with slave devices that might have limited bandwidth, as well as to allow the MicroLogix controller time to service other communication functions.

I usually poll all data from one node, then move on to the next node.

My reason for that method is that if I have a malfunctioning device or radio or network interface, I can skip to the next node after only one timeout, rather than encountering the same timeout every time I go through a poll list.
 
I agree with the general approach to put a small time delay in between messages.
Do you really think it is necessary? PLCs are relatively slow. What is necessary is to wait 3.5 character times between the messages but unless the scan is very fast I don't see where that is a problem. I would try simply using the done bit from the previous MSG to trigger the next.

Some devices do not adhere to the specifications and will not time out after just 3.5 character times. In this case you may need to wait. If you have a poll list as Ken suggested then you can have separate interval and time out times for each node.
 
Thanks guys. So what exactly should that interchar timeout be set at? The config asks for millisecs, and I'm running at 19200 baud.
 
I generally do things the way Peter suggests. I rarely induce artificial time delays into communications unless they prove to be needed. In those cases I experiment a bit to find the threshold where comms break down and then usually put the delay to about double that. Might not be a bad idea to build the timers in regardless and just set them to zero at first.

Also, it can help to structure the communication routine such that it cycles through at least one scan every time it processes a part of the execution chain. I find that allowing the .DN condition to remain high for one full scan before re-triggering comms makes things pretty robust.
 
3.5 character times is only about 1.5 milliseconds. That isn't long. If you don't start the next message block until the next scan like Damian suggested there is more than enough time between messages. If the scans times are long I would start the next MSG block as soon as possible.

Do make a scan list like Ken suggested. A set of bits should be enough. If a MSG block gets an error then clear its bit is the set of bits and generate an alarm. You don't want to hang up scanning waiting for a non functioning I/O device. Sometimes it makes no difference because the whole machine is down anyway.
 
Since you're dealing with Modbus and the timeouts I recommend programming a slow-mode for messages to devices that aren't on-line. What I usually do is set a register with a number that is a multiple of the poll time when a message times out. As long as this register is > 0 that message is not executed. Each pass through the poll list I decrement the register until it = 0 at which point I try to read from the device again.

Doing this will save you that time-out time each pass through the poll list.

Good Luck

(8{)} :) .)
(Yosi)
 
I use Ken's method, but I will split it up into multiple reads, and always program the ER bits appropriately. I have one in which I have three poll lists but I want the frequency as fast as possible and nodes do occasionally go offline for maintenance. I want the total poll time to about 1 second, so I will tweak the speed to test the system by simply adjusting a preset. I want to know at what rate i start to have problems as a baseline, since my cable runs through a lot of pipe to some nasty spots. Then I slow it back down at least by half, preferrably 1/4 or less of the known good max speed.

I read relatively large groups of data, rather than two messages for bytes within a few dozen words of each other. Once you go to the overhead to make a message get a good size chunk, none of this one word here two words there business. I'll read 30 words to get the first two and the last one, no problem, I can make space and may find something useful in between them later.

I opt for multiple round robins on one network due to the fact that the message targets addresses are represented in different files anyway, and it's better to have the available information fast, and not wait for the built in timeout, nor have to mess with the defaults for the channel.

Not dealing with the inevitable ER bit correctly can hang your polling in a SLC/PLC channel 0
 
Last edited:
Well what I was doing at first was using a timer set at 0.15s to increment a counter, and then have rungs with EQU and MSG blocks to fire off the different messages on a timed interval. I have 8 total reads, the other 3 messages will be writes and be very rare. Anything less than 0.15s resulted in time-outs and packet loss. So with that setup, any one thing was getting updated every 8 x 0.15 = 1.2 seconds, which isn't acceptable.

I started fooling around with using the DN bits, but every time I did that it would do 4 at a time and timeout (internal queue full?), and did worse than the previous setup.

Next I put timers on each message and started time with each ST bit, and if it took too long I'd set the TO bit. This didn't seem to work either until I added a pre-transmit delay.

What I finally did, is elegant, and works very well, is went back to simply using the DN bit to start the next message in a round-robin fashion. Basically got rid of the timers and just noticed that the pre-transmit delay works very nicely. With a delay of 50 ms I have almost no packet loss, like 1 every 3000 sends. With this setup, It's a total of 8 rungs, and each message is run once every ~0.63 seconds (timed it), which is almost twice as good as the timer/counter method.

This is just the beginning of my program, when all is said and done I'll probably set this pre-transmit delay higher to get an even 1 Hz refresh rate and to nearly guarantee no packet loss except in the case that a meter fails. To be extra diligent, I'll probably add the timers back in too just so a 1 second timeout doesn't screw up my program.

Should've done the DN bit sooner, as my reads are different amounts of registers...the static timed interval method is naive in regards to that fact.
 

Similar Topics

Hello, I have to deal with iFix again and am looking at the most efficient way to create alarms to display in iFix, i.e. not creating an...
Replies
0
Views
154
Hey all, I'm doing a more standardize version of one of my programs and organizing things into UDTs and whatever else I can do to shrink the...
Replies
0
Views
416
Hello All, I’m working on a project that requires filling/discharging from 30 batch tanks that are the exact same. Simplifying things some here...
Replies
7
Views
1,854
Hello, I have a modicon background where there is a "Pulse" function that accepts an input for the deisred pulse time length. I effectively...
Replies
8
Views
2,031
RSLogix5000 I have an application where I would like to be able to ADD the values of multiple arrays, or even "all" the arrays, in a given data...
Replies
11
Views
4,088
Back
Top Bottom