michaelchenca
Member
Dear Sir,
I try to write a function use SCL to read the string from a DB and convert it to real and transfer to another DB. But the simple task turnout to be a tough one. I need to use SFC20 to transfer the string to temporary one and split it and coverts it to be real. Final, I have to send it back to real DB by SFC20 again. It pass the compiler but doesn’t work. I am a new hand on STL and SCL. Siemens PLC is kind of hassle to program. A simple loop needs to use Any pointer. What a life! Following is my SCL. Your help is appreciated.
FUNCTION FC112 : VOID
VAR_INPUT
DB_Number_Real : BLOCK_DB;
DB_number_string: BLOCK_DB;
DB_String_Address : INT;
DB_real_address:INT;
END_VAR
VAR_TEMP
Decimal : INT;
Length:INT;
Temper_string:STRING[6];
leftstring:STRING[4];
rightstring:STRING[4];
d_factor:INT;
temper_real:REAL;
StringDST : ANY; // Any type refers to unknown variable type.
String_from_db AT StringDST : STRUCT
wType:WORD;
iLength:INT;
wDB:WORD;
dwAreaWORD;
END_STRUCT;
real_locate: ANY;
Destination AT real_locate: STRUCT
wType:WORD;
iLength:INT;
wDB:WORD;
dwAreaWORD;
END_STRUCT;
real_offset:WORD;
wStringOffset : WORD;
iSFCError : INT;
END_VAR
BEGIN
wStringOffset := INT_TO_WORD(8 * DB_String_Address);
real_offset:=Int_TO_WORD(4 * DB_real_Address);
// Data stucture of the "ANY" Type variable. Refer to ANY type in help for block diagram
STRING_from_DB.wType := w#16#1002; //any pointer for destination of string
STRING_from_DB.iLength := 8; // Set the length to 6: 8 String + 2 for the stuf in the beginning
STRING_from_DB.wDB := BLOCK_DB_TO_WORD(DB_number_string);
STRING_from_DB.dwArea:=dw#16#84000000 OR wStringOffset;
iSFCError:= BLKMOV(SRCBLK :=STRING_from_DB,DSTBLK :=temper_string );
// Find length for string value
Length := LEN(S:=temper_string);
Decimal:=FIND(In1:=temper_string,in2:='.');
IF decimal>0 THEN
CASE (length-decimal)of
1:d_factor:=10;
2:d_factor:=100;
3:d_factor:=1000;
4:d_factor:=10000;
ELSE: d_factor:=1;
END_CASE;
Leftstring:=LEFT(In:=temper_string,l:=(decimal-1));
rightstring:=RIGHT(in:=temper_string,l:=(length-decimal));
temper_real:=(STRING_TO_INT(in:=rightstring))/d_factor;
temper_real:=temper_real+ STRING_TO_INT(in:=leftstring);
ELSE
temper_real:=STRING_TO_INT(in:=temper_string);
END_IF;
Destination.wType:=w#16#1005;// type real// data
Destination.ilength:=4;
Destination.wDB:=BLOCK_DB_TO_WORD(DB_Number_Real);
Destination.dwArea:=dw#16#84000000 OR real_offset;
iSFCError:= BLKMOV(SRCBLK :=temper_real,DSTBLK :=Destination );
END_FUNCTION
I try to write a function use SCL to read the string from a DB and convert it to real and transfer to another DB. But the simple task turnout to be a tough one. I need to use SFC20 to transfer the string to temporary one and split it and coverts it to be real. Final, I have to send it back to real DB by SFC20 again. It pass the compiler but doesn’t work. I am a new hand on STL and SCL. Siemens PLC is kind of hassle to program. A simple loop needs to use Any pointer. What a life! Following is my SCL. Your help is appreciated.
FUNCTION FC112 : VOID
VAR_INPUT
DB_Number_Real : BLOCK_DB;
DB_number_string: BLOCK_DB;
DB_String_Address : INT;
DB_real_address:INT;
END_VAR
VAR_TEMP
Decimal : INT;
Length:INT;
Temper_string:STRING[6];
leftstring:STRING[4];
rightstring:STRING[4];
d_factor:INT;
temper_real:REAL;
StringDST : ANY; // Any type refers to unknown variable type.
String_from_db AT StringDST : STRUCT
wType:WORD;
iLength:INT;
wDB:WORD;
dwAreaWORD;
END_STRUCT;
real_locate: ANY;
Destination AT real_locate: STRUCT
wType:WORD;
iLength:INT;
wDB:WORD;
dwAreaWORD;
END_STRUCT;
real_offset:WORD;
wStringOffset : WORD;
iSFCError : INT;
END_VAR
BEGIN
wStringOffset := INT_TO_WORD(8 * DB_String_Address);
real_offset:=Int_TO_WORD(4 * DB_real_Address);
// Data stucture of the "ANY" Type variable. Refer to ANY type in help for block diagram
STRING_from_DB.wType := w#16#1002; //any pointer for destination of string
STRING_from_DB.iLength := 8; // Set the length to 6: 8 String + 2 for the stuf in the beginning
STRING_from_DB.wDB := BLOCK_DB_TO_WORD(DB_number_string);
STRING_from_DB.dwArea:=dw#16#84000000 OR wStringOffset;
iSFCError:= BLKMOV(SRCBLK :=STRING_from_DB,DSTBLK :=temper_string );
// Find length for string value
Length := LEN(S:=temper_string);
Decimal:=FIND(In1:=temper_string,in2:='.');
IF decimal>0 THEN
CASE (length-decimal)of
1:d_factor:=10;
2:d_factor:=100;
3:d_factor:=1000;
4:d_factor:=10000;
ELSE: d_factor:=1;
END_CASE;
Leftstring:=LEFT(In:=temper_string,l:=(decimal-1));
rightstring:=RIGHT(in:=temper_string,l:=(length-decimal));
temper_real:=(STRING_TO_INT(in:=rightstring))/d_factor;
temper_real:=temper_real+ STRING_TO_INT(in:=leftstring);
ELSE
temper_real:=STRING_TO_INT(in:=temper_string);
END_IF;
Destination.wType:=w#16#1005;// type real// data
Destination.ilength:=4;
Destination.wDB:=BLOCK_DB_TO_WORD(DB_Number_Real);
Destination.dwArea:=dw#16#84000000 OR real_offset;
iSFCError:= BLKMOV(SRCBLK :=temper_real,DSTBLK :=Destination );
END_FUNCTION