PLCS.net - Interactive Q & A

PLCS.net - Interactive Q & A (http://www.plctalk.net/qanda/index.php)
-   LIVE PLC Questions And Answers (http://www.plctalk.net/qanda/forumdisplay.php?f=2)
-   -   Siemens s7 ladder indirect addressing (http://www.plctalk.net/qanda/showthread.php?t=7641)

guest March 17th, 2004 07:06 AM

Siemens s7 ladder indirect addressing
 
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!

Beryl March 17th, 2004 07:32 AM

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.

JesperMP March 17th, 2004 07:44 AM

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.

guest March 17th, 2004 07:46 AM

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....

rdrast March 17th, 2004 07:49 AM

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

Beryl March 17th, 2004 07:50 AM

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.

S7Guy March 17th, 2004 09:28 AM

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.

guest March 17th, 2004 10:29 AM

Hi s7guy,
Can you elaborate on
symbolic priority programming. Show an example?

S7Guy March 17th, 2004 10:48 AM

Sure, no problem. I'll work up something tonight and post it.

S7Guy March 18th, 2004 08:23 AM

1 Attachment(s)
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 :). )

paraffin power March 18th, 2004 09:23 AM

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

jvdcande March 18th, 2004 09:28 AM

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,

S7Guy March 18th, 2004 10:03 AM

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.

Bratt March 18th, 2004 02:41 PM

Quote:

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.

S7Guy March 18th, 2004 11:51 PM

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.

Bratt March 19th, 2004 09:31 AM

1 Attachment(s)
S7Guy i created a very simple project to explain what i mean.

S7Guy March 22nd, 2004 09:57 AM

Thanks Bratt! I’m going to test a little bit with this tonight. I can see the effect of switching off MultiInstance capability, but I can’t see a good application for it yet (meaning, what can I do with it switched off that I can’t do with it switched on). But I learned 20 years ago to never second guess Siemens, so I’m going to dig into this further.

parkotron February 18th, 2009 09:05 AM

Quote:

Originally Posted by S7Guy (Post 46655)
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, ...

I find this method very interesting and am considering using it for an upcoming project.

My biggest concern is how to effectively troubleshoot such a setup. When using FBs with multiple DIs it is possible to go online and select which DI data we want to display in the logic. This particular program has some rather large and complicated rungs, so the ability to view the logic "live" for a particular instance is a must.

Is there a way to view the logic "live" with a particular instance with your method?

Also, have you ever used this method with nested FBs and nested UDTs.

Many thanks,

Parker

PeterW February 18th, 2009 11:22 AM

Quote:

Originally Posted by parkotron (Post 310185)
I find this method very interesting and am considering using it for an upcoming project.

My biggest concern is how to effectively troubleshoot such a setup. When using FBs with multiple DIs it is possible to go online and select which DI data we want to display in the logic. This particular program has some rather large and complicated rungs, so the ability to view the logic "live" for a particular instance is a must.

Is there a way to view the logic "live" with a particular instance with your method?

Also, have you ever used this method with nested FBs and nested UDTs.

Many thanks,

Parker


When you watch on-line you can select a path so you can isolate the call you want.

Not sure how good this is if the same block is called multiple times from within the same block.

Apel June 23rd, 2009 04:51 AM

Hi, S7Guy
Thank you for the exmple program.I saw you have called the FB20 many times for different conveyors( guess, 20 different conveyors- with different sizes and so on). Now my question is how do you pass the parameter to the FB for controlling the conveyor?

another question, when we are calling the FB we can not see user I/O interface because no I/O variables are used.Why you didn't use the I/O variables of the FB?

In our case we have many generic control modules like valves, agitator, PID...many, We need to pass the parameter from one to another. How do do that in you case?

Thanks,

Peter Nachtwey June 23rd, 2009 11:26 AM

Quote:

Originally Posted by JesperMP (Post 46508)
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.

Siemens should be embarrassed for making one jump through those hoops. However, someone should make some FCs LDI_X, LDI_B, LDI_W, LDI_DW etc and the complementary STI_X, STI_B, STI_W, STI_DW etc. Hmm.

Apel June 27th, 2009 06:39 AM

Hi,S7Guy, I want to use your method, but I found one problem. I can not monitor the Shared DataBlock online.Can you tell me how we can monitor the shared Db online so that we can see online data.


All times are GMT -5. The time now is 05:19 PM.

.