RSLogix5000 (Indexing bits using tags)

Salman S.

Member
Join Date
Oct 2016
Location
Malaysia
Posts
41
I would like to address bit location of tag X with another tag, so that I can create logical rungs that are dynamic.

Example lets say X and Y are 16 bit integers, and POS is an integer that represents position. I would like to evaluate the following:

X[0].POS AND Y[0].POS should energize an output. Hard coding this to a particular position works but I was hoping there is a generalized method.

Thanks in advance (y)
 
I'm not sure exactly what you mean, but what you're trying to do, I'm fairly certain, is achievable.

The example above (X[myTag].POS and Y[myOtherTag].POS) would apply if X and Y were an array of CONTROL elements. But you say that X and Y are INTEGERS.

General rule of thumb: indirect addresses go inside square brackets. Other than that, the syntax is the same. So, if X and Y were integer ARRAYS (i.e. if the data type of X was INT[10], so you have ten 16-bit integers from X[0] through X[9], you could enter X[mytag] and if the value of "mytag" is 5, the instruction will execute using X[5].

If you're looking to address one of the individual bits within a single integer, same rule of thumb - just add the square brackets. If you were to address the fourth bit in a hard-coded example, you'd enter "X.4", so to make it based on the value of "mytag" it becomes "X.[mytag]".

Two cautions here. In the first example, if "mytag" has a value higher than 9 or lower than 0, your PLC will fault, as it will try to address an array element that does not exist. Likewise with the bit addressing - if you're using a 16-bit integer, you need to ensure that "mytag" is only ever in the range of 0-15, or again, PLC crash. It's important to note that this applies whether or not you actually "use" the logic. For example, if you were to put a LESS THAN instruction at the start of your indirect addressing rung to ensure that "mytag" was 15 or less, and only execute the indirect addressing if it is - your PLC will still crash if the value of "mytag" is above 15. Even if the rung is false, the indirect address is still assessed, and will still cause the PLC to crash (ask me how I know this). You must check that the value is within range and force it to be within range if it's not before you get to the rung with the indirect addressing.

The second caution is to do with using this method to turn bits on. If you use an OTE with X.[mytag], and the value of "mytag" is 4, then that OTE will turn on X.4. No problems there. If the OTE then goes false, it will turn X.4 off. Still no problems. But what if the OTE turns X.4 on, and then the value of "mytag" changes to 5? X.4 is now not addressed anywhere in the code, and so it will stay in the last commanded state. If that state is on, your output will stay on until something else acts on it to turn it off. There are a few ways around this, but it depends on your application. One way, if your goal is to only have one bit in the integer on at any given time, is to move zero to the integer immediately before you set the bit with the indirect OTE. That way you'll turn all your bits off unless the OTE is specifically acting to turn them on.

Hope that helps!
 
I think the OP meant 'POS' in a generic sense and not as that named element of a 'control' type tag. The information of using the brackets [] to surround a tag for indirect is very helpful.
 
There's a couple of things not mentioned yet....

1. The default (unless changed), and most efficient data-type usage for Logix5000 series processors is 32-bit DINT. That is because the processor is a 32-bit wide architecture. Any other data-type is always converted before processing, and converted back for storing results.

2. Square brackets is used for indirection. The runtime execution resolves what is inside square brackets to a unique number to form the effective address. Interpretation of that has some meanings...

MyTag[7] refers to the 8th element of an array tag called MyTag

MyTag[7].5 refers to bit 5 of the above element.

MyTag[MyPointer] firstly enumerates the tag MyPointer (i.e.looks at the value of the tag), and uses that as the index into the MyTag array.

MyTag[MyPointer].[MyBitPointer] enumerates both indirections, and uses both results to formulate the effective address.

It is perfectly acceptable to put expressions inside the square brackets,

e.g. MyTag[MyPointer * 10].[MyBitPointer + BitOffset]

Whatever those tag values are, the effective array and bit addresses are calculated.

Do take heed of ASFs warnings, using indirection can throw you outside of the data structures you have defined, causing a "major fault" shutdown, so use limit checking where appropriate.
 
Thanks for the feedback everyone.
The solution was fairly straightforward, and I can't believe I didn't try it. I just didn't put [] for the bit positioning since the general syntax while hardcoding doesn't require it.

As Bernie stated I meant POS in a generic sense.

daba it was an arbitrary choice to use INT as my interest lies in bit addressing, which isn't affected by the data type. My actual application involves predefined tags of a module which I have no control over. Anyway thanks for the info regarding indirection as I took the syntax for granted.
 
Don't know if this is what you need but I use the following method to set bit x in an array of INT's. BitPointer is the bit to set. Kind of like the old SLC files you could set bit B3/127.
BFile[(BitPointer -16)/16].[BitPointer AND 15]
 
Well in my case for some reason I have Error. Before all Im Migrating PLC-5 to CLX and receive error: Unverified tag

Translator defined the tag as N20[N25_5].13
- is not recognizing this as a bool cause data type field is blank and cant be changed.
- N25_5 is allias of another C tag array N25[5]
- Arrays N20 and N25 are made of DINTs

Im very frustrated for the moment. Please i need Help!!!

Rabbit hole.png
 
Last edited:
You can't alias an indirect address. The alias has to point to an absolute tag.

If you need indirect addressing like that then move the n20[n25_5] to another dint before using it and then create aliases to the bits in that dint instead.
 

Similar Topics

Hi, I am dealing with a single SBR subroutine thats handed 1 input paramter UDT P.x multiple times: (Pump) P.1/2/3/4/5. I JSR into the same...
Replies
3
Views
1,991
I have worked before with PLC's programing software and tables (I mean N7:0 and so) and also used address like N7:[N20:0] Can I do the same in...
Replies
1
Views
4,830
Hi! So my problem is a little funky, I had Studio 5000 v 24 and 30 installed, but forgot to install RSLogix (which I cannot go without). Is there...
Replies
2
Views
122
So I had an odd request from a customer for the above. I have written the logic and tested it all in one PLC with only using 7 outputs and 7...
Replies
15
Views
428
Hello everyone, I have an RSLogix5000 project which is running live in the factory but I need to make some changes to the logic. I want to test...
Replies
0
Views
1,121
Back
Top Bottom