Wednesday, February 9, 2011

Indirect Addressing in PLC

If you are a C++ programmer then you already know pointers. According to WikiPedia a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.

The same concept of pointers is used in PLC but named "Indirect Addressing". When an indirect memory address is specified, the designated memory word will contain the address of the memory word that contains the data that will be used as the operand of the instruction.

To make this more clear let's see an example using OMRON PLC:

1- Direct Addressing :
[url=http://www.servimg.com/image_preview.php?i=128&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/direct10.jpg[/img][/url]

This is an example of direct addressing. When the input "0.00" is on then "5" will be moved to memory word "DM0" directly.
2- Indirect Addressing :
[url=http://www.servimg.com/image_preview.php?i=129&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/indire10.jpg[/img][/url]


The previous image may look like the first one of direct addressing, but if you tried to find the differences between the two images you will notice an asterisk (*) in front of the memory address "DM0". This is indirect addressing. Here, when the input "0.00" is on, the value "5" will not be moved to "DM0" it self but it will be moved to the memory address whose value is stored in "DM0".
For example suppose that "DM0" holds a value of "10", then -simply speaking- the value "5" will be moved to the memory address "DM10".

Indirect addressing will simplify you ladder and make it easy to modify.
As a real example, I was working in a concrete batching plant project which is a plant to produce concrete by mixing different aggregates with cement and water. The recipe page in the HMI software was like this:

[url=http://www.servimg.com/image_preview.php?i=130&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/recipe10.jpg[/img][/url]
There was five set points (Agg1, Agg2, Agg3, Cement and Water) and these five set points are the recipe. There was a slider with values ranging from 0 to 99. The operator of the plant should enter the desired recipe then choose a value on the slider then press "Save Recipe" button to save the 5 set points (recipe) in the chosen location on the slider. To load the saved recipe the operator chooses a value from the slider then presses the button "Load Recipe".


Now how this is done in the ladder diagram using OMRON PLC:
The addresses are as follows:

Slider = DM18
Save Recipe button = 21.12
Load Recipe button = 21.13

If we don't use indirect addressing then the ladder would be like this:

1- Save Recipe :


[url=http://www.servimg.com/image_preview.php?i=131&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/savere10.jpg[/img][/url]
Here when "Save Recipe" button is pressed the slider value is compared to zero and if it equals zero the recipe starting from "DM8" to "DM12" will be saved to addresses "DM1500" to "DM1504".

2- Load Recipe :

[url=http://www.servimg.com/image_preview.php?i=132&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/loadre10.jpg[/img][/url]
Here when "Load Recipe" button is pressed the slider value is compared to zero and if it equals zero previously saved recipe will be loaded from addresses "DM1500" to "DM1504" to addresses "DM8" to "DM12" (the opposite of save operation)

So we used five registers (DM1500 to DM1504) to save and load only one recipe. To save 100 recipes we need 5*100=500 register. If this is done using direct addressing then we need to make 100 compare instructions, 500 move instructions and 100 rung to save recipe and the same numbers to load recipe. Of course this will be very boring and difficult to modify.

Now comes the solution of indirect addressing :

[url=http://www.servimg.com/image_preview.php?i=133&u=15207678][img]http://i70.servimg.com/u/f70/15/20/76/78/savelo10.jpg[/img][/url]

Believe or not, this is only the complete ladder to save and load 100 recipe (500 values are saved and loaded, No move instructions, No compare instructions and very easy to modify).

I decided to save the 500 value in the range of registers from "DM1500" to "DM2000". First the desired starting position in this range is calculated by the following equation:
Desired Save/Load Position = (Slider Value * 5) + 1500
So if the slider position was "0" then the desired save/load position would be:
(0*5)+1500=1500
If the slider position was "99" then the desired save/load position would be:
(99*5)+1500=1995


Then to save and load I used "XFER" instruction which transfers a set of consecutive registers to another set of consecutive registers. The instruction parameters are number of words to transfer, first source word and first destination word.

By using indirect addressing when "Save Recipe" button is pressed, 5 values starting from "DM8" will be moved to another five registers starting from "*DM310" which is the recipe pointer and its value is calculated using the above equation for calculating the desired save/load position.

When "Load Recipe" button is pressed, 5 value starting from "*DM310" will be moved to another five registers starting from "DM8".

Let's see some examples:
1- Slider position = 99
so Desired Save/Load Position=(99*5)+1500=1995
so 5 words from "DM8" to "DM12" will be Saved/Loaded to/from another 5 words from "DM1995" to "DM1999"

2- Slider position = 50
so Desired Save/Load Position=(50*5)+1500=1750
so 5 words from "DM8" to "DM12" will be Saved/Loaded to/from another 5 words from "DM1750" to "DM1754"
and so on.

Finally I hope this article was useful for you.
Good bye.

No comments: