Array index within RSLogix 5000

stinklizard

Member
Join Date
Jul 2017
Location
Martinsville, VA
Posts
10
I have really hit a wall in a few situations, and asked a professor at a college this question. He said no, but I will ask it here.


Can you use a variable as the index for an array?


I swear it seems insane if you cannot. Array_1(x) or so on. Maybe he was referring to just the ladder logic side. Can the ladder logic or structured text handle this? I am positive if I read the reference material, I could find this; but it would be a lot easier to just ask the pool of experts here. I've searched and found answers to people asking about general arrays for PLC5, but I can't seem to find a plain answer for this question in regards to the 1756 (5000) platform.
 
I use arrays with variables a lot inside of structured text with RSLogix 5000. They're typically tied together with FOR/IF statements though.
 
You can do it on ladder as well.

Array[100]

Index

Array[index]

If index end up higher than your array size it will trip a recoverable fault.
 
Well this needs expanding on....

Any array index, (the thing that is enclosed in square brackets), such as Array[35] can be replaced by a tag, e.g. Array[Index]. At runtime the system reads the value of the tag "Index", and uses it as the index into the array "Array".

This is called "Indirect Addressing".

But Logix5000 takes this to a new level... You can put an expression inside the square brackets, which is evaluated at runtime into a single numeric value, which then becomes the index value into the array.

Suppose you had to look at the previous position in the array... You could address it as Array[Position - 1]. Or the next, Array[Position + 1], etc.

This is a very flexible addressing arrangement, limited only by the programmer's imagination. Any expression within the square brackets is allowed, it can be as complex as it needs to be for the application, but you just need to make sure it doesn't equate to a position outside of the array, or the processor will fault and shut down.
 
The array bounds variables are checked before the program starts so if you manage to get a subscript out of bounds, the processor will fault before running the main task.
 
The array bounds variables are checked before the program starts so if you manage to get a subscript out of bounds, the processor will fault before running the main task.

But if the program manipulates the variables.....
 
I always put a LIM instruction on the index variable before using it.

You can't do that if you are using an expression as the array index within the square brackets.

Perhaps a better way is to use a dummy tag as the destination for a CPT instruction, and use the dummy tag as the array index, trapped by LIM if required.
 
You can't do that if you are using an expression as the array index within the square brackets.

Perhaps a better way is to use a dummy tag as the destination for a CPT instruction, and use the dummy tag as the array index, trapped by LIM if required.

Thats exactly the way I do it.
 
You can't do that if you are using an expression as the array index within the square brackets.

Perhaps a better way is to use a dummy tag as the destination for a CPT instruction, and use the dummy tag as the array index, trapped by LIM if required.

A quick warning on this.

Take the example of an array of DINT's, with 10 elements. Call it DINT_Array[0] through DINT_Array[9]. Let's say you call DINT_Array[Pointer].

If Pointer has a value of 10, your PLC will crash.

Now let's say that you check the value of Pointer with a LIM instruction and only execute your indirect address instruction if Pointer is in the range of 0-9. So your rung goes:

LIM 0 Pointer 9 MOV DINT_Array[Pointer] Some_Tag

If your Pointer value is 10, the LIM instruction will evaluate false, and so the MOV instruction will not be executed. However, the indirect address will still be evaluated, and your PLC will still crash.

Even if you put an AFI at the start of that rung, so that the MOV instruction can never, ever be executed, your PLC will still crash if the Pointer value reaches 10.

So, it's not enough to just check the limits, you need to enforce the limits - i.e. if Pointer is greater than 9, MOV 9 to Pointer, and if Pointer is less than 0, MOV 0 to Pointer.

This check must not be conditional. For example, it's no good to say "if I need to perform this operation, check and clamp my Pointer value to the range 0...9 and then perform the operation". You must perform the clamping unconditionally, because even if you're not intending to execute the indirect address in an instruction, it will get evaluated anyway, and crash your PLC if it's incorrect.

Interestingly, this doesn't happen on a SoftLogix PLC. The SoftLogix will keep running until you actually execute the offending instruction. On a Control Logix, it'll fault straight away whether your'e executing the instruction or not.

Of course, you could use JMP/LBL or end subroutines to avoid the issue, but if you use JMP and TND to avoid crashing a PLC you deserve to be slapped across the face with a large fish.
 
Interestingly, this doesn't happen on a SoftLogix PLC. The SoftLogix will keep running until you actually execute the offending instruction. On a Control Logix, it'll fault straight away whether your'e executing the instruction or not.

It appears this has been "fixed" at some point in the revision progression. Earlier today I was getting ready to offer the same advice, having been burned by it in the past, and found I could not get a Rev 20 processor to fault using a similar example. When putting an out-of-range value in the index, the move instruction following the limit test showed "????" in Logix 5000 as the unresolved indirect value instead of faulting the processor.
 
It appears this has been "fixed" at some point in the revision progression. Earlier today I was getting ready to offer the same advice, having been burned by it in the past, and found I could not get a Rev 20 processor to fault using a similar example. When putting an out-of-range value in the index, the move instruction following the limit test showed "????" in Logix 5000 as the unresolved indirect value instead of faulting the processor.

I concur, same experience here, though I didn't check the minor fault log. I will tomorrow.
 

Similar Topics

I am using a function block that has a in/out parameter that is a structure. The structure has an array as one of the elements. I can index the...
Replies
1
Views
706
Sorry for the word salad title, I'm having trouble putting my problem into words. Basically I have two arrays of DINTs, both the same size...
Replies
29
Views
7,895
Hi, Unity has the option to index its arrays between any two numbers; e.g. "ARRAY[13..27] OF INT". I am writing a DFB which needs to take in a...
Replies
3
Views
2,336
I have a variable IDX that varies from 0-10, can I use the following: CONCAT ArrayStr[IDX] ArrayStr[5] Destination To write to a string...
Replies
1
Views
1,464
I've got a rung that uses the first pass bit to initiate a For argument. In the Routine named 'Alarm' I have something like this...
Replies
15
Views
9,881
Back
Top Bottom