RSLogix 5000 v20 Array Subscript Fault

creativepaper

Lifetime Supporting Member
Join Date
Feb 2008
Location
Worcester
Posts
168
I have a subroutine that gets called to copy a UDT In an array to a tag.
This subroutine will be called around once per minute and has been running unchanged for 8 years.
Last night I got a PLC fault for subscript overrun.
Looking at the code, the tag tSummary_Prod_Nbr = 201
How could this occur when the LIM instruction should not allow the AD instruction to be executed?

This tag tSummary_Prod_Nbr is not used anywhere else in the PLC program and is not overwritten by a MSG, HMI, or transaction.

The only idea I have is if I have a copy with mismatched source and destination somewhere in the PLC (STRING copied to STRING with fixed length).
I haven't looked in the code to see if this occurs, but wondering if there is anything else that could potentially cause it.

RoutFault.PNG
 
The LIM says if the value is between 0 and 200. That includes 0 and 200. That breaks down to greater than or equal to 0 and less than or equal to 200.

If the value equals 200 then it will add +1. I think you might need to change the limit to 199 if you never want to exceed 200. Or you could move/copy the LIM so it is after the ADD but before each of the CPS instructions.

OG
 
Last edited:
Opera,

I think you might just have that.
Array sizes for both CPS destination array size = 201

The only way that this will occur is if FTTM_Product_Enable_Summary_Trans.Trig_Ready = 1 when
FTTM_Product_Enable_Summary_Trans.Complete = 0

Checking the interaction between the two tags, the scenario can occur if the transaction errors out and does not complete
This is highly unlikely since we have redundant servers on this transaction, but I guess we just got unlucky when the fail-over occurred.

Thank you for this, there are a two simple patches that I'll do.
One is what you mentioned about the LIM upper value (should be 199 anyway for protection)
Second is ensuring that when an error is thrown up, the .Trig_Ready = 0 instead of 1

Thank you for your troubleshooting skills
 
I learned a very important lesson on this topic several years ago, when I put some diagnostic logic in a PLC from several thousand km away in a different country with intermittent internet access. Let's just say that it's a lesson I'll never forget.

Just because your LIM instruction evaluates false, it does not mean that the PLC ignores the rest of the rung.

Think about it. If you have a rung with an XIC at the start, and a TON at the end, what happens when the XIC goes false? The TON instruction must still be executed, because it has to reset the ACC to zero and turn off the .EN, .TT and .DN bits (if applicable).

Every single instruction on every single rung* is executed every single scan. It just executes differently depending on whether the rung-in condition is true or false.

This means that (and as alluded to above, I know this from bitter experience), you can put an AFI (always false instruction) at the very start of a rung with some dodgy indirect addressing logic at the end of it, and that dodgy indirect addressing will still be evaluated, and on certain hardware and firmware combinations, will crash your PLC. I'd bet a six pack of my favourite craft beer that this is exactly what happened here. The tSummary_Prod_Nbr got to 201, and the LIM instruction did in fact evaluate false. But the PLC carries on along the rung anyway. When it gets to the COP instruction, it doesn't need to actually move any data, because the COP instruction doesn't move any data if it's executed with the rung-in condition false, but it still tried to evaluate the source and destination, and that's what crashed your PLC.

What you need to do is to not only check that your index tag is within the limits of the target array, but also force it back within those limits if it is not, immediately before any instruction that uses indirect addressing. Even if your rung is going to evaluate false because of an XIC or a LIM or even an AFI at the start of the rung. You must enforce the limits, not just check them.

*The only way an instruction on a rung is not scanned is if the subroutine it is contained in is not called, or the program it is contained in is not scheduled. But then you also have to consider prescan, which is a whole 'nother post.
 
Last edited:
Thank you for all your help.

ASF,
I agree that your statements are what we know, but in my case, choose to ignore unless its important to me (as in a OTE or TON instruction).

What I believe happened was we got a timeout on the transaction which did NOT set .complete =1, but set .Trig_Ready = 1
This allowed the LIM instruction to evaluate 200 (as Opera mentioned accepted) and then the rung-in = true for the add and the COP instructions.

I patched the system for correctly executing code when we receive an error, and changed the LIM to upper value to 199.
I have updated after the LIM to protect the COP to respect the array size.

Thank you all again.
 

Similar Topics

Hello All, A program was downloaded to a CompactLogix PLC by a colleague. When I attempt to open the program I get a message: Failed to open...
Replies
13
Views
3,460
Ive recently been having trouble with the stability of my connection when online with a plc, The software intermittently freezes (cogwheel...
Replies
4
Views
2,068
I've googled and searched for this error but can't see it anywhere. When I try to open this program I get the following. Error 0x8004201d...
Replies
12
Views
3,983
Hello, I am trying to export some add on instructions & sub routines and import them into a program that is in Rslogix 5000 v20. The program...
Replies
3
Views
1,765
Hi all, I installed a RSLogix 5000 V20.04 to my Windows 10 system today, and it seemed everything is ok before I started it. The software gave me...
Replies
2
Views
2,948
Back
Top Bottom