S7 - Indirect Address Bits in Bool Array

mhopley

Member
Join Date
Jun 2005
Location
Manchester
Posts
65
I'm sorry is this is a FAQ but most indirect addressing samples I have found deal with bytes & words.
I have come from an SLC500 background and most of my S7 programming has been in ladder but I understand that Indirect addressing is only available in STL or SCL.

I have an array Result[1..40] of type Bool and I want to look up Result[MW2] where MW2 is my pointer and return a 0 or 1

I have worked out that i need a pointer and if I load a value and SLD 3 it puts in the correct pointer format but this is pointing at byte and not bits?

Any pointers [pun :)] would be greatly appreciated.

Thanks,
Mark
 
A pointer is a bit address and if you want to access bytes you SLD 3 (i.e. multiply by 8) the index to access the correct byte. If you are accessing bits, you don't need to perform any processing on the index.
 
Thanks for the quick reply Simon, but I am still struggling with syntax for this

L #pointer //Temp variable declared as Any?
L MW20 //index for array element
T AR1
= Result[AR1] // Get select bool from result array

STL is still new for me so the above is probably garbage so please feel free to correct me. :)

Thanks,
Mark
 
Last edited:
Here's an example:

MD0 - Pointer
MW4 - Return Value
M10.0-M49.7 = Array Data

-------------------------------

L P#10.0
T MD 0

LOOP: A M [MD 0]
JCN FALS
L 1
T MW 4
JU TRUE
FALS: L 0
T MW 4

TRUE: L MD 0
L P#0.1
+D
T MD 0

L P#50.0
<D
JC LOOP
 
I made a change to the previous example. The logic below will scan through bits M10.0 - M49.7, and MW4 will equal 1 if any of the bits are ON, or 0 if all the bits are off.

----------------------------------------

L P#10.0
T MD 0

LOOP: A M [MD 0]
JCN FALS
L 1
T MW 4
JU END

FALS: L 0
T MW 4

L MD 0
L P#0.1
+D
T MD 0

L P#50.0
<D
JC LOOP

END: NOP 0
 
Now that I've re-read and understood your question, here's my final answer!

You can sort of cheat the pointers in Siemens by using an integer to offset the desired bit. For example, if you want to examine bit M0.5, you would use the integer 5. If you wanted to examine the bit M1.6, you would use the integer 14. Here some sample code below:

Keep in mind that:
- The data array still starts at M10.0 (the offset 80 is used because of 10 bytes (10 x 8)
- Loading a 0 into MW2, would examine M10.0. Loading a 16 into MW2, would examine M12.0.
- MW4 will equal 1 if the bit is true, otherwise equal 0.

----------------------------------------------------

L MW 2
L 80
+I
ITD
T LD 0

A M [LD 0]
JCN FALS
L 1
T MW 4
JU END
FALS: L 0
T MW 4
END: NOP 0
 
Your pointer should be a double word not word, i.e. MD20 and not MW20. This is because the address field is over two words.
See this link for an overview of the pointer:

http://www.plctalk.net/qanda/showthread.php?t=24092&page=2&pp=15

I imported the pointer description into this thread.

Basically the pointer part that is used in your function is as follows

Byte 1----Byte 2----Byte 3----Byte 4

dddddddd 00000yyy yyyyyyyy yyyyybbb

d = data type code (not needed in this type of function so leave blank)

0 = not used

y = byte address

b = bit address

So your if you want to point to DB10.DBX50.3

Then the following code

Declare a TEMP and call it DBX_Address and make it a DWORD.

Imagine your code calcs the offset and MW20 = Byte = 50 and MB22 = Bit = 3

L MW20
SLD 3
L MB22
OD
T #DBX_Address

OPN DB10
A DBX[#DBX_Address]
= #Result
 
Your bit of code doesn't make much sense

L #pointer //Temp variable declared as Any?
L MW20 //index for array element
T AR1
= Result[AR1] // Get select bool from result array

the # indicates that it is a declared variable from the top of the the block, either a TEMP or a STAT (stat only in FB's), it says it is declared as an ANY. You could not load an ANY or a POINTER, as the most you can load into the accumulator is 4 bytes, a pointer is 6 bytes and an any is 10.

You can use the pointer format for the last 4 bytes, which is effectively what the code in my previous message done.

You then load MW20 into the accumulator, then the contents of AR1 is loaded into the acculator.

TAR1 is transfer AR1 into Accu 1

= Result[AR1], the first part you have written as result must be a valid data type, i.e :

= M [MD20].

To use AR1 you must first load an address into it, an example from real code is below.

L P##paEA_Status
LAR1
L D [AR1,P#0.0]
T LD 0 //! absolute Adressierung
L D [AR1,P#4.0]
T LD 4
L W [AR1,P#8.0]
T LW 8

L P# is loading the acculator with the address in pointer format of the next part, in this case #paEA_Status, a STAT. It could just as easily have been L P#M50.0 which would set it us as M50.0 in pointer format.

LAR1 transfers the accu 1 (which holds the pointer format of the temp flag) into AR1 (address register 1)

L D [AR1, P#0.0] is loading a double data word, offset with the address in AR1 plus P#0.0, which means just AR1 .


L D [AR1,P#4.0] is loading a double data word, offset with the address in AR1 plus P#4.0, which means the address in AR1 offset by 4 bytes.
 
Thanks for all your replies.
I was trying to modify some code for a 40 head filling machine. Boolean data was stored in DBs in 40 bit arrays and integer data in 40 dword arrays.

I found an example posted by Simon Goldsworthy
http://www.plctalk.net/qanda/showpost.php?p=143085&postcount=4

I am not quite sure how the decoding of the format works but I know the block works a treat. I can look up arrays of Dword or bits. I don't use the offset on the output side but the flexibity is great.

So thanks again 🍻 to PeterW and lendyck and to Simon :geek: for posting that example back in Feb.

After seeing some recommendations on here, I have ordered The Hans Berger book Automating with Step 7 in STL and SCL from amazon so hopefully I will get my head around pointers and will not have to come here and show my ignorance :oops:
 
...will not have to come here and show my ignorance
- hey, don't worry. All that concerns the users of this forum is the type of ignorance shown. Ignorance is simply a lack of knowledge (facts, information etc). We've all got areas in which we are ignorant. However of much greater concern to the community is intelligence: the ability to take these facts and that information, and extrapolate from them, to understand and comprehend, to come up with something new as a result. Sometimes, no matter how much data you throw at someone, their level of understanding does not rise at all. That type of ignorance is hard to deal with. Nobody minds intelligent ignorance, it gives all of us the chance to show off our stupid knowledge!

regards

Ken
 
Once you have looked at the pointers section in the Berger book (page 334 for example in my 2nd edition 2001) the mists should clear from the type decoding and how any pointer data is used.
 
hiii peter,
I think u r very much familier with pointers.i am just a beginner.can u pls explain me what is pointer and how to use or ref any manuals with examples.
pls feel free to advice me in this case.
 

Similar Topics

Hi everyone, I hope you can help me. Im working with get the production parts of all hours-day using STL. My idea is to use an array [0..23] of...
Replies
9
Views
3,839
Hi, I have a DB in my program with all the alarms of a machine, but the machine is divided in stations. So I want to check if any station is with...
Replies
2
Views
2,079
I have an indirect PLC5 code conversion I can not figure out how to convert to CLX Anyone have a solution Thanks
Replies
11
Views
4,144
In an old PLC5 I see an output like this B37 -()- [N19:21] If I remember correctly that says to set the bit of word 37 thats equal to the value...
Replies
13
Views
6,936
Good day all. I have an alarm that has been triggered and I can't figure out what is triggering it. When I go to the alarm table it shows an...
Replies
4
Views
2,153
Back
Top Bottom