Hi all,
In PCS7 project I need to move indexed db data from one to other, but with different lenght....
For example I will need to define a start address like db10.dbx2.5 and a bit lenght like 30 (...so it will last 'till db10.dbx6.2) to a destination address like db20.dbw4 with the same lenght.
What I would like to have on my scl code is as Input parameters the "dbnn.dbxn.n" and "bit lenght" and the destination "dbnn.dbwnn" as output.
Anyone can give me a clue how to make it... or maybe someone have a code that makes it ??
Best regards,
[?]: Move DB data from one to other in SCL
-
- Posts: 104
- Joined: Sat Jun 13, 2009 12:25 pm
- Location: Europe
Re: [?]: Move DB data from one to other in SCL
Hi,
Search for SFC20 BLKMOV in Siemens Step7 help.
An other solution : use google and search for oscat.de : you could find a SCL block library for free.
Best regards.
Search for SFC20 BLKMOV in Siemens Step7 help.
An other solution : use google and search for oscat.de : you could find a SCL block library for free.
Best regards.
-
- Posts: 7
- Joined: Thu Jul 01, 2010 6:01 am
Re: [?]: Move DB data from one to other in SCL
Thanks for the answer...dehell wrote:Hi,
Search for SFC20 BLKMOV in Siemens Step7 help.
An other solution : use google and search for oscat.de : you could find a SCL block library for free.
Best regards.
I will try and inform.
Best regards
-
- Posts: 19
- Joined: Sun Oct 22, 2006 9:12 am
Re: [?]: Move DB data from one to other in SCL
This code is proven working
Show
Code: Select all
FUNCTION_Block "CopyDB"
AUTHOR : Someone
FAMILY : MoveDB
NAME : CopyDB
VERSION : '1.0'
KNOW_HOW_PROTECT
VAR_INPUT
Source : INT; // Source DB
Destination : INT; //Distination DB
END_VAR
VAR_OUTPUT
Error : WORD;
END_VAR
VAR_IN_OUT
Execute : BOOL ; //Execute Copy
END_VAR
VAR_TEMP
tiX : INT;
RETVAL : INT;
tiSourceDBLength : WORD;
tiDestinationDB1Length : WORD;
tbWriteProtected : BOOL;
END_VAR
BEGIN
IF Execute THEN
Error := 0;
// Get information of source DB
RETVAL := TEST_DB(DB_NUMBER := INT_TO_WORD(Source), DB_LENGTH := tiSourceDBLength, WRITE_PROT:=tbWriteProtected);
// If TEST_DB for source DB function was executed error free, the continue, otherwise indicate the error
IF RETVAL = 0 THEN
RETVAL := TEST_DB(DB_NUMBER := INT_TO_WORD(Destination), DB_LENGTH := tiDestinationDB1Length, WRITE_PROT:=tbWriteProtected);
// If TEST_DB for destination DB function was executed error free, the continue, otherwise indicate the error
IF RETVAL = 0 THEN
// Check if destination DB write protected
IF tbWriteProtected THEN
Error := W#16#000A; // Write protection error W#16#A
ELSE
IF tiSourceDBLength = tiDestinationDB1Length THEN // Check if both DBs have the same length
// both DBs have the same length. copy source to destination
FOR tiX := 0 TO (WORD_TO_INT(tiSourceDBLength) - 2) BY 2 DO
// word by word copy
WORD_TO_BLOCK_DB(INT_TO_WORD(Destination)).DW[tiX] := WORD_TO_BLOCK_DB(INT_TO_WORD(Source)).DW[tiX];
END_FOR;
ELSE // If length differs then output error W#16#B (Length Error)
Error := W#16#000B;
END_IF;
END_IF;
ELSE // destination DB error
Error := INT_TO_WORD(RETVAL);
END_IF;
ELSE // Source DB error.
Error := INT_TO_WORD(RETVAL);
END_IF;
Execute := False;
END_IF;
-
- Posts: 7
- Joined: Thu Jul 01, 2010 6:01 am
Re: [?]: Move DB data from one to other in SCL
Hi Janosch07,Janosch07 wrote:This code is proven working :
Enjoy
Tested and working. Your code copies a complete DB to another one exacty equal, but it does not makes exactly what I need.
I need to copy parts from one DB to another , but de source data may not start in DWn.0 and with a lenght different than 16 or 32 bits.
The source data I need to move is for example 30 bits starting in address db20.dbx2.4 and move them to another DB starting for example in the address db21.dbx0.0 .
How can I point to bits instead of words using an instruction like the one you've used:
Code: Select all
WORD_TO_BLOCK_DB(INT_TO_WORD(Destination)).DW[tiX] := WORD_TO_BLOCK_DB(INT_TO_WORD(Source)).DW[tiX];
-
- Posts: 104
- Joined: Sat Jun 13, 2009 12:25 pm
- Location: Europe
Re: [?]: Move DB data from one to other in SCL
Hi,
I test on PLCSIM and it seem OK
Best regard
Try this code
Show
Code: Select all
FUNCTION_BLOCK FB505
TITLE = 'Bit_DB_AREA_to_Word_DB_AREA'
//Take care, this block don't check if DB exist or enough long...
// Instruction
//
VERSION : '1.0'
AUTHOR : Dehell
NAME : BTW
FAMILY : BTW
VAR_INPUT
DB_IN: INT;// INPUT DB number
IN_BYTE:INT;// INPUT Byte number
IN_BIT:INT;// INPUT bit number
DB_OUT:INT;// OUTPUT DB number
DEST_WORD:INT;// OUTPUT Word number
LENGH:INT;// Number of bit to copy
END_VAR
VAR_OUTPUT
DONE:BOOL;
END_VAR
VAR
NUM_DB_IN: WORD;
NUM_DB_OUT:WORD;
NUMBER_BYTE:INT;
NUMBER_BYTE2:INT;
INDEX1:INT;
INDEX2:int;
INDEX3:INT;
INDEX4:INT;
INDEX5:INT;
MASK:BYTE;
NBR_BIT_MASK:INT;
BYTEARRAY: ARRAY[0..31]OF BYTE;// maximum 256 bits : you can increase this value
BITARRAY2:ARRAY[0..255]OF BOOL;
BYTEARRAY2 AT BITARRAY2:ARRAY[0..31]OF BYTE;
BITARRAY1 AT BYTEARRAY :ARRAY[0..255]OF BOOL;
END_VAR
BEGIN
NUM_DB_IN:=INT_TO_WORD(DB_IN);
NUM_DB_OUT:=INT_TO_WORD(DB_OUT);
DONE:=FALSE;
IF LENGH < 8 THEN
RETURN;// if LENGH<8 this function is aborted
ELSE
// Number of byte calculation
NUMBER_BYTE:=(LENGH/8)+1;
NUMBER_BYTE2:=(LENGH/8);
END_IF;
// Copy DB_IN into BYTE ARRAY
FOR INDEX1:=0 TO NUMBER_BYTE DO
BYTEARRAY[INDEX1]:=WORD_TO_BLOCK_DB(NUM_DB_IN).DB[IN_BYTE+INDEX1];
END_FOR;
// Copy ARRAYBIT1 into ARRAYBIT2 with offset
FOR INDEX2:=0 TO LENGH DO
BITARRAY2[INDEX2]:=BITARRAY1[INDEX2+IN_BIT];
END_FOR;
//Copy ARRAYBIT2 into WORDARRAY
FOR INDEX3:=0 TO (NUMBER_BYTE2-1) DO
WORD_TO_BLOCK_DB(NUM_DB_OUT).DB[DEST_WORD+INDEX3]:= BYTEARRAY2[INDEX3];
END_FOR;
// For last BYTE, create Mask
NBR_BIT_MASK:=((LENGH-(NUMBER_BYTE2*8))-1);
INDEX5:=DEST_WORD+(NUMBER_BYTE2);
FOR INDEX4:= 0 TO 7 BY 1 DO
IF INDEX4 >=0 AND INDEX4 <= NBR_BIT_MASK THEN
WORD_TO_BLOCK_DB(NUM_DB_OUT).DX[INDEX5,INDEX4]:= BITARRAY2[((NUMBER_BYTE2*8)+1)+INDEX4];
END_IF;
END_FOR;
DONE:=TRUE;
END_FUNCTION_BLOCK
Best regard
-
- Posts: 7
- Joined: Thu Jul 01, 2010 6:01 am
Re: [?]: Move DB data from one to other in SCL
Excellent answer dehell... This is exactly what I needed !!!!!
Thanks a lot !!
Thanks a lot !!
Last edited by cabrca on Tue Oct 25, 2011 3:29 pm, edited 2 times in total.
-
- Posts: 19
- Joined: Sun Oct 22, 2006 9:12 am
Re: [?]: Move DB data from one to other in SCL
Hi Cabrca,
Try this code for copying bits
test and see if it's good for you
Regards
Try this code for copying bits
Try this code for copying bits
Show
Code: Select all
FUNCTION_Block "CopyDBBits"
AUTHOR : abcd
FAMILY : efgh
NAME : CopyDBbx
VERSION : '1.0'
KNOW_HOW_PROTECT
VAR_INPUT
Source : INT; // Source DB
Destination : INT; //Distination DB
SourceBitOffset : INT; // Offset to start bit of source DB. (if DBx.DBX8.7 then Offset = 7)
DestinationBitOffset : INT; // Offset to start bit of destination DB. (if DBx.DBX1.0 then Offset = 0)
SourceByteOffset : INT; // Offset to start byte of source DB. (if DBx.DBXB8.7 then Offset = 8)
DestinationByteOffset : INT; // Offset to start byte of destination DB. (if DBx.DBX1.0 then Offset = 1)
// Offset must be between 0 and 7
BitsToMove : INT; // Number of bits to copy
END_VAR
VAR_OUTPUT
Error : WORD;
END_VAR
VAR_IN_OUT
Execute : BOOL ; //Execute Copy
END_VAR
VAR_TEMP
tiX : INT;
RETVAL : INT;
tiSourceBit : INT;
tiDestinationBit : INT;
tiSourceByte : INT;
tiDestinationByte : INT;
twSourceDBLength : WORD;
twDestinationDBLength : WORD;
tbWriteProtected : BOOL;
END_VAR
BEGIN
IF Execute THEN
Error := 0;
// Get information of source DB
RETVAL := TEST_DB(DB_NUMBER := INT_TO_WORD(Source), DB_LENGTH := twSourceDBLength, WRITE_PROT:=tbWriteProtected);
// If TEST_DB for source DB function was executed error free, the continue, otherwise indicate the error
IF RETVAL = 0 THEN
RETVAL := TEST_DB(DB_NUMBER := INT_TO_WORD(Destination), DB_LENGTH := twDestinationDBLength, WRITE_PROT:=tbWriteProtected);
// If TEST_DB for destination DB function was executed error free, the continue, otherwise indicate the error
IF RETVAL = 0 THEN
// Check if destination DB write protected
IF tbWriteProtected THEN
Error := W#16#000A; // Write protection error W#16#A
ELSE
// No errors when evaluating DBs information. copy source to destination
// Check for Parameter errors
IF ((INT_TO_WORD(SourceBitOffset) OR 16#7) <> 7) THEN
Error := W#16#000C; // Source bit offset out of range
END_IF;
IF ((INT_TO_WORD(DestinationBitOffset) OR 16#7) <> 7) THEN
Error := W#16#000D; // Source bit offset out of range
END_IF;
tiSourceBit := SourceBitOffset; // Initialise the source bit pointer
tiDestinationBit := DestinationBitOffset; // Initialise the destination bit counter
tiSourceByte := SourceByteOffset; // Initialise the source byte counter
tiDestinationByte := DestinationByteOffset; // Initialise the destination byte counter
// First, check for length errors
// Note : the length of a DB is always an even number. If for example the last entry in a DB is DBX6.7, this function will allow writing up to
// DBX7.7 and beyond that an error is returned
FOR tiX := 0 TO (BitsToMove - 1) DO // loop through the number of required bits to copy
IF ((tiDestinationByte + 1) > WORD_TO_INT(twDestinationDBLength)) THEN // Check if destination byte pointer exceeds the length of the destination DB
Error := W#16#000E; // Copy of bits interrupted due to possible write error on destination DB
END_IF;
IF ((tiSourceByte + 1) > WORD_TO_INT(twSourceDBLength)) THEN // Check if destination byte pointer exceeds the length of the source DB
Error := W#16#000F; // Copy of bits interrupted due to possible read error from source DB
END_IF;
IF Error <> 0 THEN
EXIT;
END_IF;
// word by word copy
WORD_TO_BLOCK_DB(INT_TO_WORD(Destination)).DX[tiDestinationByte,tiDestinationBit] := WORD_TO_BLOCK_DB(INT_TO_WORD(Source)).DX[tiSourceByte,tiSourceBit];
tiDestinationBit := tiDestinationBit + 1; // increment source bit pointer by 1
tiSourceBit := tiSourceBit + 1; // increment destination bit pointer by 1
IF tiDestinationBit > 7 THEN // If bit higher than 7 then
tiDestinationByte := tiDestinationByte + 1; // increment byte pointer by 1
tiDestinationBit := 0; // reset bit pointer to 0
END_IF;
IF tiSourceBit > 7 THEN // If bit higher than 7 then
tiSourceByte := tiSourceByte + 1; // increment byte pointer by 1
tiSourceBit := 0; // reset bit pointer to 0
END_IF;
END_FOR;
END_IF;
ELSE // destination DB error
Error := INT_TO_WORD(RETVAL);
END_IF;
ELSE // Source DB error.
Error := INT_TO_WORD(RETVAL);
END_IF;
Execute := False;
END_IF;
END_FUNCTION_BLOCK
Regards