Siemens s7 ladder indirect addressing

guest

Guest
G
In siemens step 7 i want to use indirect
addressing in ladder form. How would I
set this up? For example I have a DB
of 1000 bits. I want to ability to change
the position of the bit through a register.
Something like this : DB1.dbx0.0 would be db1.dbx[md100] md100=0.0 would equal the bit location. Is this possible?
I have done it before with AB SLC 500
and it works great for the application
i have. Thanks!
 
S7 doesn't have idirect addressing in ladder. They recommend using SCL. If you want to stay in ladder you will have to build your own.
 
Beryl,
I guess you mean STL (statement list) rather than SCL (Structured Control Language). Indirect adressing is possible in both, but not everyone has the SCL option package.

guest,
The good Hans Berger book "Programming in STL and LAD" states that indirect adressing in LAD is possible to a limited degree with SFC20 BLKMOV.
If you dont have this book, then get it ! Its worth every penny.
But prepare yourself for a steep learning curve. Indirect adressing in AB is straightforward. In S7 it is not.
 
Do you mean STL?
That is fine if you have the time to learn
it but with deadlines and such. This is a
pain. Its bad enough the manuals and help
notes assume everyone is an expert or had
classes. Siemens step 7 so powerful yet so weak....
 
You can use the address register's and pointers to use indexed or indirect addressing, but you will need to do it in SCL (Optional package) or STL (Built in).

In STL, the basics are:
OPN #DB ; whatever DB you are using
LAR1 P#DBX0.0 ; Load address register 1 with a pointer into open DB
TAR1 #BaseAdrPointer ; Save address base into a DWORD for later

L #Curr_Idx ; Index into the actual word of the DB you want
L 4 ; If indexing Dwords, Reals, multiply by 4,
*I ; This assumes Curr_Idx increments by 1 for each element
SLD 3 ; Shift left 3 places to make offset a Pointer
LAR1 #BaseAdrPointer ; Load AR1 with the base pointer
+AR1 ; Adds in the calculated value above to AR1
L #Test_Val
T D [AR1,P#0.0] ;transfer our test value into the indexed offset into the data block.


You can put checks and loops on Curr_Idx in this example to fill a DB of DWords or reals with a common value.

It's not intuitive, but if you hammer at it enough, you'll get the idea :)

Good luck
 
Jesper,
I ment SCL for easy of learning...

Guest,
I'd say not so powerful and very weak... Not a big S7 fan if you couldn't tell.
 
Guest, it's too bad that you don't have the time to invest right now, but in the future you should consider using symbolic priority programming. This allows you to indirectly address just about everything using the actual names in your data blocks. I always use STL, but there is no reason it wouldn't work in ladder as well. I just finished a huge project using this method, and it minimized pointer calculations while still allowing me to use generic functions throught the code.
 
Hi s7guy,
Can you elaborate on
symbolic priority programming. Show an example?
 
Here you go. In this example, I created a data block that contains the tags for twenty conveyor systems. Each conveyor is represented by a UDT, and is made up of varying data types. It is not necessary to add “fillers” to provide for new data later on, because the length of the UDT is determined at the startup of the PLC anyway, and the pointer will be adjusted accordingly. This is sometimes a big headache with absolute programming, where you might have to comb through the code and adjust indirect addresses.

I’m not sure which PLC you will want to test this in, so I created a startup function (FC 100) that you will have to call in your startup OB. This startup function will determine the length of a conveyor UDT and record it in MD50. I used a simple method of determining the UDT length (check the length of the data block and divide by 20), but there are other ways to do it that are more powerful.

If you look in FB20, you will see that I assign the conveyor UDT as a STAT variable, and that there are no other variables assigned. When I call FB20, the UDT will just map to the data block, using a pointer offset based on the UDT length (it sounds complicated, but bear with me). I tossed some simple code in FB20 just so you can see that you will be programming in a true symbol format.

Now, look in OB1. You can see that I call FB20 one time for each conveyor, while adding MD50 to AR2 for each call. Also, you will see that since I am calling FB20 unconditionally, I don’t have to include parameters or an instance data block, as FB20 just uses the UDT listed on its STAT variable, and it uses the instance data block that happens to be open. Technically, I could have used an FC instead, but FCs work differently and the scan time would skyrocket.

Stepping through the program, this is what happens:

1. The PLC goes from STOP to RUN, and FC100 is called from my startup OB.
2. I look at the length of DB100 and divide by 20. This gives me the length of the conveyor UDT in bytes. I multiply this by 8 to get the length in bits, and transfer it to MD50. If you change the number of conveyors, remember to change the number “20”.
3. Now, OB1 is called. The first thing it does is open DB100 as an instance data block. It then sets AR2 to zero, so that we will start looking at the very first conveyor when FB20 is called.
4. FB20 is called, the code is executed, and it returns to OB1.
5. AR2 is increased by the length of one UDT by adding MD50 to it.
6. FB20 is called again, but this time it points to the second conveyor’s addresses.
7. Upon the return to OB1, AR2 is indexed again and the next conveyor is called, and so on.

I also added a second FB (FB21) where I index AR2 within the function to take a look at the conveyor in front of it (Conveyor 1 checks to see if Conveyor 2 is running, Conveyor 2 looks at Conveyor 3, and so forth, with the exception of Conveyor 20). So, with a little imagination you can see that you can jump all over the place without using “traditional” indirect addresses (i.e. L DBW[AR1,P#10.0]). Also, remember that you can still use absolute addresses within a function. For instance, if you always want to stop all conveyors if Conveyor 20 is faulted, then you could just look at the direct state of Conveyor 20 without using a pointer (I did this in FB20).

Unfortunately, it is not possible to use ladder 100% of the time, but this method reduces the manipulation of pointers so much that it doesn’t matter much anyway. Also, by using a shared data block as an instance data block, you will avoid the management of instance data blocks and the function calls become simpler.

Again, if you find out six months from now that you have to add some new IO or some additional run data for each conveyor, and the conveyor UDT length changes drastically, you won’t have to change your code at all. Just download the new data block and restart the PLC, and your pointer (MD50) will be adjusted automatically. One thing to keep in mind though with symbolic programming is that if you ever change the UDT, you will have to recompile the blocks. You do this from the Simatic Manager by clicking Blocks>Check Block Consistency>Compile All. And, to make your project use symbolic priority, from the Simatic Manager click Blocks>Address Priority>Symbolic.

If you decide to experiment with this (and trust me, once you get the hang of it you won’t believe how much it speeds up development), make sure you experiment with a test PLC first, so you don’t break the real machine. Indirect addressing is powerful, but it can be destructive (I still have a bad day once in a while :). )
 
Question for S7guy

Hi
Read your program with interest.
Been using Step7 for a while and knew there was a tidier way of doing things. Step 5 habits die hard!
Can I ask a question?
What does OPN DI100 do?

Secondly does FB20 automatically use AR2?

Thanks

pp
 
ParafinPower,

in S7 you can open 2 datablocks at the same time. To distinguish the one from the other, one is opened with OPN DB, the other with OPN DI. When using data from those blocks DIX, DIB, DIW, DID are entities from the block opened as DI while DBX, DBB, DBW and DBD are parts from the block opened as DB. In other words: it's only a naming convention of some kind.

Kind regards,
 
Parrafin,

OPN DI100 simply opens DB100 as an Instance Data Block. Function Blocks, by definition, use instance data blocks, so you have to open one for global use if you use FB's unconditionally (you probably remember that if you use the CALL function with an FB, you have to declare the instance DB as well, i.e. "CALL FB20, DB10"). Personally, using the conveyor program as an example, I would rather deal with one global instance data block than 20 individual blocks.

As for AR2, yes, FB uses it automatically. I'm not sure if you can find that little fact in a Siemens manual anywhere, but I am pretty sure that any STAT variables automatically point to addresses via AR2.

I came from the S5 world too, and it's easy to continue on to S7 using the same methods, but there are a lot of new, powerful ways to do things if you really dig for them. Usually the people who say that S7 isn't powerful just don't understand it very well.
 
As for AR2, yes, FB uses it automatically. I'm not sure if you can find that little fact in a Siemens manual anywhere, but I am pretty sure that any STAT variables automatically point to addresses via AR2.

The FB's use AR2 to keep track of the offset in the common instance db when you are using multiple instances capability. If you unckeck this option when you create your fb's you can use AR2 freely within your fb call.
 
Bratt, can you think of a good reason to uncheck this option? I mean, I always leave it checked, but I can still freely use AR2 in FCs as a second pointer, and if you look at my sample project, I manipulate AR2 in the FB as well.

I suppose I could use an FB like I would use an FC and not use an instance data block at all, but I can't think of a good reason to do that.
 

Similar Topics

Hi. I have 2 files where I would like to see the ladder logic differences (similar to the Rockwell compare function). I am using TISoft Siemens...
Replies
1
Views
1,228
Hi guys, first time posting on this site. I'm a Maintenance Electrician and am having trouble understanding some ladder logic on one of our...
Replies
16
Views
3,643
Hi, I need a bit of help from you more experienced programmers please. I have a bit of ladder logic, which "works", I don't think it is the...
Replies
8
Views
2,316
I'm having a heck of a time figuring out how to efficiently move the decimal value 1150 into MW20. Can this be done using the MOVE command? Does...
Replies
17
Views
6,786
Hey hi, I have written a logic in ladder in Siemens s7 300 plc and then converted it into STL . Now I m trying to convert it into ladder again...
Replies
1
Views
2,912
Back
Top Bottom