Siemens S7 Any pointer to array

JERA

Member
Join Date
Feb 2006
Location
Copenhagen
Posts
320
Must modify / expand a program which is made with a many block move (SFC20) as shown in the attached image.

It moves data between array of different data blocks and needs to be expanded. I would like to change the addressing of calling for indirect to get rid of the large number of block move that will come.

Have tried some different solutions but have not found the right one.
So does anyone have the solution to make a ANY pointer for use in array?

sfc20.JPG
 
may be you mean is indirect addressing?, i have sample program for this

A #TRIGER
JNB M014
L #STAT11
T MW 500
L MW 500
SLD 4
T MD 502
L #DB_NO
T MW 508
OPN DB [MW 508]
L DBW [MD 502]
T #STAT9
L MW 500
T #STAT11
M014: NOP 0
 
I am somewhat of a noob on the subject, but I'd solve it with something like this: (The UDT is just an example of what an array might contain. The code should work with any kind of arrays and of any size)

Code:
TYPE _UDT_TEST
    STRUCT
    S_BOOL : ARRAY [0..7] OF BOOL;
    S_BYTE : BYTE;
    S_WORD : WORD;
    S_DWORD: DWORD;
    END_STRUCT;
END_TYPE

DATA_BLOCK _TEST_DATA
    STRUCT
        Channel_Status : ARRAY [1..20] OF "_UDT_TEST";
    END_STRUCT;
BEGIN
END_DATA_BLOCK

FUNCTION _TEST : INT
VAR_INPUT
    Channel_nr : INT;
END_VAR
VAR_TEMP
    Status_Data : "_UDT_TEST";
    T_RET_VAL: INT;
END_VAR

    T_RET_VAL:= BLKMOV(SRCBLK := _TEST_DATA.Channel_Status[Channel_nr], DSTBLK := Status_Data);
    _TEST := 0;
END_FUNCTION
 
Last edited:
You don't have to use BLKMOV, you can use an assignment. If a function does not have a return value then make it of type VOID.

Code:
TYPE udt333
    STRUCT
    S_BOOL : ARRAY [0..7] OF BOOL;
    S_BYTE : BYTE;
    S_WORD : WORD;
    S_DWORD: DWORD;
    END_STRUCT;
END_TYPE

DATA_BLOCK db333
    STRUCT
        Channel_Status : ARRAY [1..20] OF udt333;
    END_STRUCT;
BEGIN
END_DATA_BLOCK

FUNCTION fc333 : void
VAR_INPUT
    Channel_nr : INT;
END_VAR
VAR_TEMP
    Status_Data : udt333;
    T_RET_VAL: INT;
END_VAR

Status_Data:=db333.Channel_Status[Channel_nr];   

END_FUNCTION
 
Source code might be the only way of "protecting your code" at the moment though. If you have that need, that is.

Code:
Status_Data:=db333.Channel_Status[Channel_nr];
You are right, this is superior as long as the data amount in each array element isn't too large.
 
I beg to differ.

Code:
  SET   
      SAVE  
      =     L     12.1
      L     #Channel_nr
      ITD   
      L     L#1
      -D    
      L     L#80
      *D    
      LAR1  
      OPN   DB   333
      L     DBD [AR1,P#0.0]
      T     LD     0
      TAK   
      T     LD    14
      TAK   
      L     DBD [AR1,P#4.0]
      T     LD     4
      L     DBW [AR1,P#8.0]
      T     LW     8
      SAVE  
      BE
Or does the compiler verify the size to be moved and implement SFC20 if justified? I guess it wouldn't surprise me.

*Edit: Haha! You win, it really does.
 
Last edited:
Here's an STL implementation and test example that allows generalised array accesses including arrays of structs. The code assumes that the array indexes are zero based.
 
Thanks for your help and now I can see what I should do.

The array as #Channel_Status[1] refers to is a DB built by a UDT of 50 word (mix of BOOL, BYTE and INT).

In the program data will be:
1 Retrieved from the array DB
2 Processed with data from another DB (also array)
3 Saved data back in the first array DB again

Therefore it will be good to have the number of block move reduced since I have to extend the program up to 50 channels
 
Can anybody explain this program...It is very helpful to me if anybody explain this...tnx in advance...

L P##POINTER_SOURCE
LAR1
L P##POINTER_DEST
LAR2
L W#16#1002
T LW [AR1,P#0.0]
T LW [AR2,P#0.0]
L #SOURCE_DBNO //DB50
T LW [AR1,P#4.0]
T LW [AR2,P#4.0]
L #SOURCE_BEGIN //DB50.DBD28
SLD 3
OD DW#16#84000000
T LD [AR1,P#6.0]
L DW#16#84000000
T LD [AR2,P#6.0]
L #SOURCE_LENGTH //28 BYTES
T LW [AR1,P#2.0]
T LW [AR2,P#2.0]
 
Can anybody explain this program...It is very helpful to me if anybody explain this...tnx in advance...

L P##POINTER_SOURCE
LAR1
L P##POINTER_DEST
LAR2
L W#16#1002
T LW [AR1,P#0.0]
T LW [AR2,P#0.0]
L #SOURCE_DBNO //DB50
T LW [AR1,P#4.0]
T LW [AR2,P#4.0]
L #SOURCE_BEGIN //DB50.DBD28
SLD 3
OD DW#16#84000000
T LD [AR1,P#6.0]
L DW#16#84000000
T LD [AR2,P#6.0]
L #SOURCE_LENGTH //28 BYTES
T LW [AR1,P#2.0]
T LW [AR2,P#2.0]

What I can tell it creates two ANY pointers. POINTER_SOURCE has starting adress Db50.dbx0.0, POINTER_DEST has a starting address Db50.dbx28.0. Both have a repetition factor of 28 bytes.
 

Similar Topics

I have a word in some DB which I want to load to AR1 and use as a pointer. In order to do this I need to write L DBxy.DBW xy SLD 3 LAR1 I...
Replies
3
Views
543
Hi people. I am having some trouble with siemens Step7, i'm not expert on it by any stretch. I'm more of a Bradley person with some TIA portal...
Replies
31
Views
11,097
Is it possible to make I/O filed on HMI of POINTER data type? Pointer data type can be either temp, IN or IN_OUT variable inside FB. it would be...
Replies
1
Views
1,781
Hi All, I have a system where there are parameters loaded into a DB from a DCS system. When I check the address's I find no locations in...
Replies
4
Views
2,893
Hy Experts, I have some problem with this intsructions: - CREA_DBL - READ_DBL - WRIT_DBL I want to create a recipie management in 314 CPU via...
Replies
3
Views
3,572
Back
Top Bottom