Siemens S7 indexed addressing

PLCdave

Member
Join Date
Apr 2003
Posts
15
Hi
I'm using siemens step7 for the first time and would like to use indexed addressing to check or set a signal state in an array of boolean, can anyone help?

e.g. I have an integer variable called Fred and an array of booleans called Harry[0-31]. Fred gets set to a number in the program and I want to check if Harry[Fred] is set, how do I do this?

In RSlogix this would simply be for example N7:[N10:3] but in S7 the help files just refer to checking I/O and fixed pointers and as you might guess I'm having a spot of bother.

Thanks in advance for any pointers (no pun intended)

PLCdave
 
A step7 POINTER, in its simplest form, is made up of a double word.
Bits 0, 1 and 2 are bit pointers. The rest that word points to the byte.
This is the P#x.y format you may have seen (y=bit, x=byte).

This is MEMORY-INDIRECT addressing

If you:
L P#12.4 //byte 12 bit 4
T MD10
A M[MD10]

The AND statement will look at M12.4

Similary...

L 12 //byte (your variable)
T MD10
SLD3 //move it to the byte pointer area
T MD10
L 4 //bit (your variable)
OW //update the pointer
T MD10
A M[MD10]

The problem with the first method is Step7 only allows 0-7 in the bit pointer part (Step7 is byte addressed).
To access upto bits 31 of a double word you'll need to do some jiggery-pokery.

Register-Indirect Area-Internal Addressing (say that after a few pints)

You can also use the address registers. It's a bit more complicated, but I believe is faster to scan (if scan time is a concern)

Example
L P#12.4
LAR1 //load the address register with byte12 bit4
A M[AR1,P#0.0] //access

the P#0.0 in the last instruction is an offset.

The pointer can be manually created as before and moved to an address register with LAR1

Note: LOAD normally puts something into the Accumulator except with the Address register where it takes it out of the accumulator
and puts in in the address register.

Paul
 
Thanks Paul, that looks promising, I see what you mean regarding jiggery-pokery, may be I ought to have a few pints first. I'll give it a try this afternoon.

Thanks again

Dave
 
Hi Dave,

indirect adressing in an AB is a bit more straightforward compared to S7. And the manuals are sometimes more confusing than helpful.

Here are some examples that should make the transition from AB to S7 a little easier.

Example 1: Indirect adressing of a MW.
LP#2.0 //initialize MD10 := adr.pointer "2.0"
T MD 40
L MW 10
T MW [MD 40] //Put the content of MW10in MW2


Example 2: Indirect adressing within a DB.
OPN DB 10 //Open DB10 first (required when adressing DB's)

L P#4.0 //initialize MD40 := adr.pointer "4.0"
T MD 40
L MW 12
T DBW [MD 40] //Put the content of MW12in DB10.DBW4


Example 3: Looping thru several MW adresses via indirect adressing.
L P#100.0 //initialize MD40 := adr.pointer "100.0"
T MD 40 //Pointer for words to check
L P#120.0 //initialize MD44 := adr.pointer "120.0"
T MD 44 //Pointer for bits to store result in

L 4 //We are going to test 4 words MW100 .. MW106
Next: T MW 6 //Loop counter
L 123 //Some value to compare (just an example)
L MW [MD 40] //Load the value from MW100 (or MW102, MW104, MW106)
>I //do the test
= M [MD 44] //store the result in M120.0 (or M120.1, M120.2, M120.3)
L MD 40
+ 16 //Increase the word counter with 2 bytes (16dec=10000bin >> x.y=2.0)
T MD 40
L MD 44
+ 1 //Increase the bit counter with 1 bit (x.y=0.1)
T MD 44
L MW 6 //Loop counter
LOOP Next //Jump to next pass as long as loop counter > 0


Hope you (or somebody else) can get some inspiration from this :)
 
hi PLCdave, I answer your post no. 1.

declare Fred as INT and Harry as Array [0..31] of BOOL

then:
L P##Harry; // load the address of Harry[0]
L #Fred; // Load Fred
+D ; // 32 bit sum
LAR1 ; // assign to AR1 register
A [AR1,P#0.0];

regards
 
Last edited:
@rgua
that bit of code looked really promising but doesn't seem to work, if I add to the end of it
= #valid
where valid is a Bool then it should get set for example if fred = 3 and harry[3] bit is set, am I missing something?

@JesperMP
yes I am inspired to
a) find a different solution to the problem, not using indexing
b) use a different plc

Actually I am learning a lot about S7 whilst doing this so thanks to all who have posted.

cheers

Dave
 
Hi PLCDave
ln step 7 the use of the variables is a little complex. The temp(orary) variables are produced and lost in every scanning.
For my test I created a FB2 with a DB2 of static variables.

FB2
var Declaration

>out valid BOOL
>stat Harry ARRAY[0..31]
> BOOL
>stat Fred INT

>A I 0.0 // test input
>= #Harry[3] // assign to Harry[3]
>L MW 10 // index, you can write L 3
>T #Fred
>L P##Harry // Load the address of Harry[0]
>L #Fred
>+D // 32 bit sum
>LAR1 // assign to AR1 register
>A [AR1,P#0.0]
>= #valid // output


In OB1

CALL FB 2 , DB2
valid:=Q4.0

I tested this code by a true CPU 315 and by the plcsim 4
The Step 7 package is the more difficult that I know.

Regards
 
Last edited:
Hello !
In normal PLC-programing you do almost NEVER have to use indexing, people who use them are usually people that only know how to program eg. C++ or other high level programing languages.
Using indexing only makes the program hard to test and manage, if not impossible.
Im sorry to say but the question sounds like a school task ?

If you are new with S7 you should learn the basics first...
 
Dear Experts,

Im working on step7 since few months and im trying to write a program wich can do the following:

Lets say we have a DB1 wich contains 20 bytes:

DB1.DBB0
Db1.DBB1
.
.
DB1.DBB19

I wanna load a byte accordinly to an entered value in MB0 for example

So when i tranfser 1 to MB0 i wanna open DB1 and load only the first byte to compare it with some inputs,

I taught to do the following:
OPN DB1
L DBB[MB0]

Etc

But its not easy as it shows, what is the right way to this

And thank you.
 
Dear Experts,

Im working on step7 since few months and im trying to write a program wich can do the following:

Lets say we have a DB1 wich contains 20 bytes:

DB1.DBB0
Db1.DBB1
.
.
DB1.DBB19

I wanna load a byte accordinly to an entered value in MB0 for example

So when i tranfser 1 to MB0 i wanna open DB1 and load only the first byte to compare it with some inputs,

I taught to do the following:
OPN DB1
L DBB[MB0]

Etc

But its not easy as it shows, what is the right way to this

And thank you.

OPN DB1
L MB 0
SLW 3 // (or multiple MB0 with 8), int -> pointer conversion
LAR1 // load int to LAR1, LAR1 register is 32bits/dint
L DBW [AR1,P#0.0]
T MW 100
L 2#0000 0000 1111 1111 (16#00FF)
AW // remove second byte with 16#00FF
T MW102 // MW102 has first 8bits (MB102)


OPN DB1
L MB0
SLW 3 //int -> pointer
T MD 4 // transfer/convert int to dint (or temp-located dint or db.dbd variable, pointer is dint-datatype)
L DBW [MD4] //load DB1.DBWxx
T MW100
L 2#0000 0000 1111 1111 (16#00FF)
AW // remove second byte with 16#00FF
T MW102 // MW102 has first 8bits (MB102)


Your 8bits can also be at MB103 address?, check if bytes get swapped at MW100 = MB100 + MB101, and MW102 =MB102 + MB103. I don't have Siemens PLC now, so I can't check if writed everything right...
 
Last edited:
Thanks for the quick answer, even if ill need few hours to figure out what ur code exactely do :D since im new in STL programming, however this forum will be surely instructive since it regroup the best programmers from the whole world,

Thank you again for accepting the information exchange :)
 
Thanks, even that I don't know much of Siemens indirect adressing ;)

You maybe need to go to bit level if you want also look db1.dbb1 values, earlier code works if you load both bytes at same time.

changed code would be something like:

OPN DB1
L MB 0
LAR1 // load bit pointer to LAR (points now to bit level)
A DBX [AR1,P#0.0] // AR1 Pointer + offset
= M100.0
A DBX [AR1,P#0.1]
= M100.1
A DBX [AR1,P#0.2]
= M100.2
A DBX [AR1,P#0.3]
= M100.3
A DBX [AR1,P#0.4]
= M100.4
A DBX [AR1,P#0.5]
= M100.5
A DBX [AR1,P#0.6]
= M100.6
A DBX [AR1,P#0.7]
= M100.7

this way should work:
MB0=0 -> Load DB.1.DBB0
MB0=1 -> Load DB.1.DBB1

if you don't use AR1 register, then you need add 1 bit to pointer. (with loop command you can shorten this, but basic idea)

OPN DB1

L P#0.0
T MD2 // load zero to pointer, this is not necessary.

L MB 0
T MD2 // bit pointer value

A DBX [MD2] // pointer points to DBX.0
= M100.0

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.1
= M100.1

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.2
= M100.2

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.3
= M100.3

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.4
= M100.4

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.5
= M100.5

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.6
= M100.6

L MD2
L P0.1
+D
T MD2

A DBX [MD2] //pointer points to DBX.7
= M100.7



;)
 
Or something simple, thinked hard way first 🙃:


OPN DB1
L MB 0
SLW3
LAR1
L DBB [AR1,P#0.0] // AR1 Pointer + offset
T MB100


or


OPN DB1
L MB 0
SLW3
T MD2
L DBB [MD2] // load byte with pointer
T MB100
 
Last edited:
This looks more short, have you a document where the use of AR1 and code that u used is explained?

Thanks for giving interest to my question :)
 
Last edited:

Similar Topics

Hi All, I have written an indexed program that controls 8 identical machines. Each machine has an identical DB which contains a map of all its...
Replies
1
Views
2,352
Hi everyone, I am an omron plc tec , lately I came across a siemens s7 200 cn plc . Can someone help me regarding the software required and...
Replies
26
Views
400
This is the first time I am working with Simatic Manager Step7 as I started my siemens journey with TIA which is pretty easy and do a lot of stuff...
Replies
3
Views
103
Hi, I have PLC S7-1200 and switch XC-208 and Iam trying to implement this SNMP library: SIOS I am not sure, what I am doing wrong, but there is...
Replies
3
Views
111
Hi all, i am the new controls guy at the plant and i have inherited a pc from the previous controls guy with Siemens tia portal version 16 and 17...
Replies
17
Views
633
Back
Top Bottom