indexed/indirect adressing

pauly

Member
Join Date
May 2002
Location
South Wales,U.k
Posts
244
Could someone shed a little more light on the subject of indexed or indirect addressing?
If I wanted to utilise the above method to enable recipe
handling in an slc500 5/05, could it be as simple as say assigning an integer of 1 to register N7:0 when no.1 recipe button is pressed on an HMI, and a value of say 2 for no. 2 recipe etc? How do you utilise register N7:0 in the ladder, what functions would you use, any examples?
Regards
Pauly
 
One thing you might do is to build a sequencer where all the setpoints are in file N10: for example.

Say something like this:

Start the process
START DONE_LAST RUN
----| |----+----|/|--------( )
|
RUN |
----| |----+


Fill the tank to level
RUN +--- GEQ ---+ DONE_1
----| |----| LEVEL |-----+----( )
| N10:0 | |
+-----------+ |
|
DONE_1 |
----| |----------------------+


Run Mixer for a time

DONE_1 +--- MOV ---+
------| |--------+---------| N10:1 |
| | T4:0.PRE |
| +-----------+
|
| +--- TON ---+
+---------| T4:0 |
| +-----------+
|
| T4:0/DN DONE_2
+----| |-----------( )

... and so on....



Now you can set up a bunch of setpoints for your recipes, all stored in file N11:

Recipe #1
Level = 100 (N11:0)
Mix Time = 20 (N11:1)
etc...

Recipe #2
Level = 150 (N11:10)
Mix Time = 25 (N11:11)
etc...

...and so on ....



Now, you can use the Copy command to load your N11: recipes into the N10: "usage" file.

Without indirect addressing, you would do it like so:

+--- EQU ---+ +--- COP ---+
-----| N7:0 |-------| #N11:0 |
| 1 | | #N10:0 |
+-----------+ +-----------+

+--- EQU ---+ +--- COP ---+
-----| N7:0 |-------| #N11:10 |
| 2 | | #N10:0 |
+-----------+ +-----------+

... and so on....



With indirect addressing, you don't need one rung for each recipe. You've laid your data tables out so that everything is in groups of 10. Therefore you can calculate the offset, and do the copy in one instruction, like so:

N7:0 HAS A RANGE 1-x. N7:1 WILL HAVE VALUES OF 0, 10, 20, etc.
+---------- CPT ---+
--------| N7:1 |
| (N7:0 - 1 ) * 10 |
+------------------+

+------- COP ---+
-----------| #N11:[N7:1] |
| #N10:0 |
+---------------+





If you run out of data table space (if you have 20 recipes with 40 setpoints each) you can always indirect the file number instead. You could put Recipe #1 in N11:; Recipe #2 in N12, and so on. Then your indirect addressing would be of the type N[N7:1]:0.

Another advantage to this approach would be that you could use N[N7:1]:0 in place of N10:0 in the code above, N[N7:1]:1 in place of N10:1, ect.



Yet another way to do this is with index addressing. In indexed addressing, when the PLC encounters the '#' sybmbol in front of an address, it adds the value currently residing in S:24 to the base address to come up with a new address. That is, if S:24 has a value of 20, and the PLC encounters the address #N10:0 in an instruction, it will use the value stored in N10:20, not N10:0 in that instruction.

So using indirect addressing, you could rewrite the sequencer as follows:


Point to the correct recipe
+---------- CPT ---+
----+----| N7:1 |
| | (N7:0 - 1 ) * 10 |
| +------------------+
|
| +--- MOV ---+
|-----------| N7:1 |
| S:24 |
+-----------+


Start the process
START DONE_LAST RUN
----| |----+----|/|--------( )
|
RUN |
----| |----+




Fill the tank to level
RUN +--- GEQ ---+ DONE_1
----| |----| LEVEL |-----+----( )
| #N11:0 | |
+-----------+ |
|
DONE_1 |
----| |----------------------+


Run Mixer for a time

DONE_1 +--- MOV ---+
------| |--------+---------| #N11:1 |
| | T4:0.PRE |
| +-----------+
|
| +--- TON ---+
+---------| T4:0 |
| +-----------+
|
| T4:0/DN DONE_2
+----| |-----------( )

... and so on....



A few words of caution: Not all instructions allow the use of indirect addressing. The Bit instructions (-| |-, -|/|-, -( ) ) and timers/counters especially. Also, some instructions hijack S:24 for their own purposes - the COP, FLL, and anything which automatically use the '#' symbol.

The subject of Indexed, indirect, and recipe handling comes up here regularly. Do a search of the site and you should find more info if I haven't given you enough already.
 
Last edited:
I'm not famillar with how allen bradley handles it but if your lookin for a conceptual answer I can help there.

The use of indirect addressing (aka pointers) is the practice of using a value in a fixed memory location (called the pointer) to tell your program what other memory location to retreave data from.

The most common use is to fill a data table with a set of values.

For example the memory location used as the "pointer" would hold the address of the refrenced memory location that you want to read data from or write data into. You can then change the Pointer value to reference other memory.

This allows you to use the same code to read and write to many different memory areas rather than having to have repetitive code (one for each) code to read or write each different location.

I hope this helps some, I'm out of time for now.

Postscript. I see that Allen beat me to the puch with a more complete answer!(y)
 
Last edited:
Ok.......

Send me your email and I can send you a program that does what you are looking for..........

Its one I did for a hydraulic metal press that stores like 200 recipes of like 10 parameters for different die and tooling setups.

Dave
 
Hi Pauli,

A couple of things here.

1) You can use indirect addressing as a file pointer as well. For example:

N7:0 = Word address - set to 15 for this example
N7:1 = File Address - set to 22 for this example

N[n7:1][n7:0] would reference N22:15

This means that you can divide your recipe data accross different files easily. Build a subroutine that accepts the recipe number in a register and outputs a file-word pair. Use this pair to access the data as above.

(BTW, indirect addressing works with most of the SLC instructions)

2) You can use _indexed_ addressing to access multiple files as well but it's a bit trickier. If the "indexed addressing accross file boundries" feature is enabled (see SLC status file) then the actual address is an offset of the initial address and file numbers will be ignored. For Example:

If N10 is 10 words long and N11 is 10 words long and the index value = 15 #N10:0 will reference as N11:15.

I don't recommend using this feature even if it's slightly faster. It's difficult to document more difficult to use than indirect addressing. It also requires more programming, is less intuitive and it leaves lots of room for errors in the future.

Good Luck,

(8{)} :) .)
 
You're close, Pauly.

Indexed addressing is like what you've decscribed. You pick a starting register, then apply and offset of 1 to read the next register. Sometimes, this is nice because then you can use an incremental counter and the program stays relatively easy to read.

Usually, I use indirect addressing for what you describe. I'll set aside a memory file for recipes or setpoints. Then if I want recipe #n I use indirection to find register "n * block length." Using a MOV command, you can grab all your setpoints.

This is a rough example for AB, but other PLCs have similar functions.

AK
 

Similar Topics

I have upgraded an old RS500 project to Studio 5000, it has thrown multiple errors which I am currently working through. I have looked through...
Replies
8
Views
1,724
Hello all. Just wondering if anybody can help me understand this instruction. MOV source= #N11:10 dest= #N14:[n7:7] length= 20 I...
Replies
3
Views
1,662
hi everybody,i have a problem as follow, there is an array of data with a specific start address in a DB block,i want to read a byte from this...
Replies
1
Views
1,637
I'm doing some MSG'ing with a few SLC 5/04's - I'm polling data in two SLC's with another one - once a minute(T4:1). I want to put the data...
Replies
29
Views
10,834
Hello guys, I use Tia Portal V16. What is the best way to change the indexed HMI tags when I change the format of an Udt in my plc program...
Replies
0
Views
1,308
Back
Top Bottom