SCL array element copy

MWA_DATA[MWA_STA_DST] := MWA_DATA[MWA_STA_SRC] ;

That is very simple. I was wondering how it would be done since there isn't a OPNDB command like STL

As far as the symbolic names, I'm not a fan either :(


It also might be that they have over simplified it, that block might be easy to use incorrectly. Also it might be that it is case depended. Atleast that block cant move udt if size of that udt aint hardcoded inside the block.
True, that is why I kinda liked the STL version with the input of the Array,First Element, and then the Source and Dest. Makes for a nice re-usable block :) Thanks again for that LD!!!

So you dont have that SCL source? In that case, if you can, maybe post stl source of that block.

If you feel like looking thru it more power too ya :)
It made me dizzy just looking at it, that's when I figured I would ask the pro's at this site :)
It won't let me genereate the source, I'm guessing since it is already genereated by SCL but here is the pasted code from the block


INPUTS:
MWA_STA_SRC = INT
MWA_STA_DST = INT

IN/OUT:
MWA_DATA = Array[0..100] Struct
-String[10]
-Byte

TEMP:
i = INT
match = BOOL


Code:
      SET   
      SAVE  
      =     L      2.2
      L     #MWA_STA_DST
      ITD   
      L     L#112
      *D    
      L     L#96
      +D    
      L     #MWA_STA_SRC
      ITD   
      TAK   
      T     LD     4
      TAK   
      L     L#112
      *D    
      L     L#96
      +D    
      L     P##MWA_DATA
      LAR1  
      TAK   
      T     LD     8
      TAK   
      L     W [AR1,P#0.0]
      T     LW    12
      OPN   DB [LW 12]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     B [AR1,P#0.0]
      T     LD     8
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    12
      OPN   DB [LW 12]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD     8
      T     B [AR1,P#0.0]
      L     #MWA_STA_DST
      ITD   
      L     L#112
      *D    
      L     #MWA_STA_SRC
      ITD   
      TAK   
      T     LD     4
      TAK   
      L     L#112
      *D    
      L     P##MWA_DATA
      LAR1  
      TAK   
      T     LD     8
      TAK   
      L     W [AR1,P#0.0]
      T     LW    12
      OPN   DB [LW 12]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     D [AR1,P#1.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     D [AR1,P#1.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     D [AR1,P#5.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     D [AR1,P#5.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     W [AR1,P#9.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     W [AR1,P#9.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     B [AR1,P#11.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     B [AR1,P#11.0]
      =     L      2.2
      SAVE  
      BE
 
He said in post # 12 that MWA_DATA is an Array. And he needs to recreate an existing block.
So it is actually not a requirement that it must be reusable code for general usage.

But how to use ANY pointers in SCL is of course an interesting topic nonetheless.
 
Given on this information, I suggest this:
(It seems that the temps "i" and "match" are not used anywhere in the code).

Code:
{Scl_MonitorArrayLimits := 'y'}
{Scl_SetOKFlag := 'y'}
FUNCTION SYS_MWA_move : VOID
VAR_INPUT
    MWA_STA_SRC : INT ;
    MWA_STA_DST : INT ;
END_VAR
VAR_IN_OUT
    MWA_DATA : ARRAY[0..100] OF STRUCT
        str1 : STRING[10] := 'undef' ;
        by1 : BYTE ;
    END_STRUCT ;
END_VAR
VAR_TEMP
  i : INT ;
  match : BOOL ;  
END_VAR ;

OK := TRUE ;
MWA_DATA[MWA_STA_DST] := MWA_DATA[MWA_STA_SRC] ;
   
END_FUNCTION

the generated STL looks like this. I dont have the time to scrutinise it, but superficially it looks very much like your STL code.

Code:
      SET   
      SAVE  
      =     L      2.2
      =     L      2.2
      L     #MWA_STA_DST
      ITD   
      L     L#0
      >=D   
      A     L      2.2
      =     L      2.2
      TAK   
      L     L#100
      <=D   
      A     L      2.2
      =     L      2.2
      TAK   
      L     L#112
      *D    
      JO    I007
      JU    I008
I007: CLR   
      =     L      2.2
I008: L     #MWA_STA_SRC
      ITD   
      TAK   
      T     LD     4
      TAK   
      L     L#0
      >=D   
      A     L      2.2
      =     L      2.2
      TAK   
      L     L#100
      <=D   
      A     L      2.2
      =     L      2.2
      TAK   
      L     L#112
      *D    
      JO    I009
      JU    I00a
I009: CLR   
      =     L      2.2
I00a: L     P##MWA_DATA
      LAR1  
      TAK   
      T     LD     8
      TAK   
      L     W [AR1,P#0.0]
      T     LW    12
      OPN   DB [LW 12]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     D [AR1,P#0.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     D [AR1,P#0.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     D [AR1,P#4.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     D [AR1,P#4.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     D [AR1,P#8.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     D [AR1,P#8.0]
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    16
      OPN   DB [LW 16]
      L     D [AR1,P#2.0]
      L     LD     8
      +D    
      LAR1  
      L     W [AR1,P#12.0]
      T     LD    16
      L     P##MWA_DATA
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    20
      OPN   DB [LW 20]
      L     D [AR1,P#2.0]
      L     LD     4
      +D    
      LAR1  
      L     LD    16
      T     W [AR1,P#12.0]
      CLR   
      A     L      2.2
      SAVE  
      BE
 
One last thing.
The code would have achieved the same as the below code which will be fine in both STL and LAD:

Code:
      CALL  "BLKMOV"
       SRCBLK :="SYS_PART_TRACKING_IDB".MWA_DATA[5]
       RET_VAL:=MW10
       DSTBLK :="SYS_PART_TRACKING_IDB".MWA_DATA[15]
      NOP   0
I cant tell if we are overlooking something, or if the original programmer was oblivious to the existence of BLKMOV.
 
This is first iteration for general usage block, there is stuff that needs to be added (data validity checks like no only DB inputted to any and like). And it expects to work inside one array.

Code:
FUNCTION CopyElement : VOID

(*
Function: Copies one element of array at index SrcIndx to same array at index DstIndx.
          Needs one element to be inputted for data width calculation.
ToDo : Checks for input data validity.
*)


VAR_INPUT
    SourceArray, ArrayElement : ANY;
    SrcIndx, DstIndx : INT;
END_VAR

VAR_TEMP
    tSource, tDestination, tArrElement : ANY;
    Src AT tSource : STRUCT
        S7 : BYTE;
        DataType : BYTE;
        RepFactor : INT;
        DBnum : WORD;
        Ptr : DWORD;
    END_STRUCT;
    
    Dst AT tDestination : STRUCT
        S7 : BYTE;
        DataType : BYTE;
        RepFactor : INT;
        DBnum : WORD;
        Ptr : DWORD;
    END_STRUCT;
    
    Elm AT tArrElement : STRUCT
        S7 : BYTE;
        DataType : BYTE;
        RepFactor : INT;
        DBnum : WORD;
        Ptr : DWORD;
    END_STRUCT;
    
    Err, i : INT;
  
END_VAR

//init
tSource := SourceArray;
tDestination := SourceArray;
tArrElement := ArrayElement;

//select datatype modifier
CASE BYTE_TO_INT(Elm.DataType) OF
    2..3 : i:=1; //byte, char or udt
            
    
    4..6 : i:=2; //word or int
    
    
    7..9 : i:=4; //dword, dint or real
    
END_CASE;

//calculate element offset based on index, datatype and arrays offset
//for source
Src.RepFactor := Elm.RepFactor*i;
Src.Ptr :=(Src.Ptr AND dw#16#FF000000) OR
          DINT_TO_DWORD(
          DWORD_TO_DINT(Src.Ptr AND dw#16#00FFFFFF) +
          DWORD_TO_DINT(SHL(IN:=INT_TO_DWORD(SrcIndx*Elm.RepFactor*i) ,N:=3)));
           
//for destination
Dst.RepFactor := Elm.RepFactor*i;
Dst.Ptr :=(Dst.Ptr AND dw#16#FF000000) OR
          DINT_TO_DWORD(
          DWORD_TO_DINT(Dst.Ptr AND dw#16#00FFFFFF) +
          DWORD_TO_DINT(SHL(IN:=INT_TO_DWORD(DstIndx*Elm.RepFactor*i) ,N:=3)));     

//do copy
Err := BLKMOV(SRCBLK:=tSource, DSTBLK:=tDestination);

END_FUNCTION
Jesper, this is why I talked about General usage block:

Seems like you will always end up creating new code everytime you want to work with a different size array or UDT, I may just not fully understand it at the moment. I'm looking to create so "Canned" FC's and FB's to use as a plant standard. So when we have a machine builder programming machines for us there will be some similarities. At the moment we have a builder building 4 lines for us and I'm amazed at how different they are comeing from one builder.
 
Last edited:
I'm not sure why they created this block. I typically use the SFC20 route. Or FC1000, I've seen this block alot from different builders doing similar things but a little different. FC1000 we use has inputs: DbSrc, DbDst, ByteSrc, ByteDst, and Bytes. And then it creates the anypointers and uses SFC20.

At least now I know more about SCL then when I started this thread. I'll be working on some function blocks when I have free time :)


I also need to do some reading on the AT command as I don't fully understand it
Code:
Src AT tSource : STRUCT
S7 : BYTE;
DataType : BYTE;
RepFactor : INT;
DBnum : WORD;
Ptr : DWORD;
END_STRUCT;
 
AT basically aliases memory area with other datatype.

Code:
VAR_TEMP
    iVar : INT;
    wVar AT iVar : WORD;
END_VAR
This would enable you to use wVar when doing word operations and iVar when doing calculations. Instead of:

Code:
VAR_TEMP
    iVar : INT;
END_VAR

iVar := WORD_TO_INT(INT_TO_WORD(iVar) AND w#16#00FF);
you could do:

Code:
wVar := wVar AND w#16#00FF;

Variable made with AT must fit in original variable, but it can be less. There is restrictions on when and how AT can be used. That is the reason why ANY's need to be copied to temp mem area before using ANY's parts trough AT struct.
 

Similar Topics

Hello I wanna know if are some function to check what is the max value from an array or if I have to loop the array to compare all numbers to get...
Replies
4
Views
1,907
Hello, When you want compare values of an array to a range of numbers is it a right way to do that? FUNCTION ADD VAR_IN_OUT A:ARRAY[1..50]...
Replies
5
Views
2,090
Hi guys. I have a challenge that I'm struggling with and I can't help thinking there's a really easy solution. I want to move a series of...
Replies
18
Views
5,866
Hi, I just can't wrap my head around this one so all ideas and comments are more than welcome. My SCL programming skills are beginner level. What...
Replies
3
Views
1,954
Hello I am writing a small code, I have two problems populating the arrays? I am getting an error Non-existing identifier. I also need help to...
Replies
12
Views
5,947
Back
Top Bottom