FUNCTION_BLOCK "Decode_PTP_Message"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Length : UInt := 10;
Message_Number : UInt;
END_VAR
VAR_OUTPUT
ReturnCode : Int;
o_ReturnString : String;
END_VAR
VAR_IN_OUT
Recv_Buffer : Array[1..511] of Byte;
IL150_Data : "IL150_Data";
END_VAR
VAR
Current_String : Int;
Strings : Array[1..6] of String;
Return_String : String;
Delimiter_Char : Char;
Delimiter_Int : Int;
END_VAR
VAR_TEMP
iTemp : Int; // Temp
END_VAR
VAR CONSTANT
Do_Nothing : Int;
Check_Analogue : Int := 1;
Check_Material : Int := 2;
Check_Rate : Int := 3;
Check_Shutter : Int := 4;
Check_Thickness : Int := 5;
Check_Version : Int := 6;
Check_Crystal : Int := 7;
Lock_Keyboard : Int := 8;
Reset_Unit : Int := 9;
Shutter_Close : Int := 10;
Program_Material : Int := 11;
Select_Material : Int := 12;
Program_Analogue : Int := 13;
Thickness_Look : Int := 14;
Thickness_Change : Int := 15;
Max_String : Int := 6;
END_VAR
BEGIN
(**************************************************************************************************
//Name: Decode_IL150
//Author: Nick Maclean
//Date: 11/2016
//
// Read through the recieve buffer, check the return code, Create strings of the result
//
//**************************************************************************************************)
//initialise the data fields
FOR #Current_String := 1 TO #Max_String DO
#Strings[#Current_String]:= '';
;
END_FOR;
//Start at 1
#Current_String := 1;
#Return_String := '';
#iTemp := 1;
#Delimiter_Char := #Recv_Buffer[2];
#Delimiter_Int := CHAR_TO_INT(IN := #Recv_Buffer[2]);
// Find the return code as string delimited by first CR (0D)
WHILE CHAR_TO_INT(#Recv_Buffer[#iTemp])<> 13 AND #iTemp <= #Length DO // Look for Carriage return (0D)
#Return_String:= CONCAT_STRING(IN1:=#Return_String,
IN2:= CHAR_TO_STRING(IN:=#Recv_Buffer[#iTemp]));
#iTemp := #iTemp + 1;
END_WHILE;
// Evaluate the return code
#ReturnCode := STRING_TO_INT(IN:= #Return_String);
CASE #ReturnCode OF
0:
#o_ReturnString := 'Command OK';
1:
#o_ReturnString := 'Unknown Command';
2:
#o_ReturnString := 'Command Not OK Shutter Open';
3:
#o_ReturnString := 'Command Not OK Shutter Closed';
4:
#o_ReturnString := 'Error Converting Command to Real Value';
5:
#o_ReturnString := 'Command Parameter exceeds allowed range';
6:
#o_ReturnString := 'Command String Exceeds 15 Chars';
7:
#o_ReturnString := 'Parameter String Exceeds 15 Chars';
8:
#o_ReturnString := 'Internal Error';
9:
#o_ReturnString := 'Input Buffer Full';
ELSE // Statement section ELSE
#o_ReturnString := 'Comms Error';
END_CASE;
IF #ReturnCode = 0 THEN;
//decode
//#iTemp := #iTemp + 1; // point to next character in the buffer
FOR #iTemp := #iTemp +1 TO UINT_TO_INT(IN:= #Length) DO
IF #Recv_Buffer[#iTemp] = '$R' THEN; //Check for string delimiter
#Current_String := #Current_String + 1; //point to next string
IF #Current_String > #Max_String THEN
;
#Current_String := #Max_String; //range check
END_IF;
ELSE
#Strings[#Current_String] := CONCAT_STRING(IN1 := #Strings[#Current_String],
IN2 := CHAR_TO_STRING(IN := #Recv_Buffer[#iTemp]));
END_IF;
END_FOR;
CASE UINT_TO_INT(IN:= #Message_Number) OF
#Check_Analogue: // Statement section case 1
#IL150_Data.Analogue_Mode := STRING_TO_INT(IN := #Strings[1]);
;
#Check_Material: // Statement section case 2
IF #Current_String = 6 THEN // Full message recieved?
#IL150_Data.Material_Data.Density := STRING_TO_REAL(IN := #Strings[2]);
#IL150_Data.Material_Data.Z_Value := STRING_TO_REAL(IN := #Strings[3]);
#IL150_Data.Material_Data.Temination_Thickness := STRING_TO_REAL(IN := #Strings[4]);
#IL150_Data.Material_Data.Tooling := STRING_TO_REAL(IN := #Strings[5]);
#IL150_Data.Material_Data.Crystal_Number := STRING_TO_UINT(IN := #Strings[6]);
;
#iTemp := STRING_TO_INT(IN := #Strings[1]);
IF #iTemp > 0 AND #iTemp <= 8 THEN
#IL150_Data.Material[#iTemp].Density := STRING_TO_REAL(IN := #Strings[2]);
#IL150_Data.Material[#iTemp].Z_Value := STRING_TO_REAL(IN := #Strings[3]);
#IL150_Data.Material[#iTemp].Temination_Thickness := STRING_TO_REAL(IN := #Strings[4]);
#IL150_Data.Material[#iTemp].Tooling := STRING_TO_REAL(IN := #Strings[5]);
#IL150_Data.Material[#iTemp].Crystal_Number := STRING_TO_UINT(IN := #Strings[6]);
END_IF;
END_IF;
#Check_Rate: // Statement section case 3
#IL150_Data.Current_Rate:=STRING_TO_REAL(IN := #Strings[1]);
;
#Check_Shutter: // Statement section case 4
#iTemp := STRING_TO_INT(IN := #Strings[1]);
IF #iTemp = 1 THEN
#IL150_Data.Shutter_Is_Open := true;
ELSE
#IL150_Data.Shutter_Is_Open := false;
END_IF
;
#Check_Thickness: // Statement section case 5
#IL150_Data.Current_Thickness:= STRING_TO_REAL(IN := #Strings[1]);
;
#Check_Version: // Statement section case 6
#IL150_Data.Version_Number := #Strings[1];
;
#Check_Crystal: // Statement section case 7
#IL150_Data.Crystal_Number:=STRING_TO_INT(IN := #Strings[1]);
#IL150_Data.Crystal_Hz:=STRING_TO_DINT(IN := #Strings[2]);
;
#Lock_Keyboard: // Statement section case 8
#IL150_Data.Lock_Keyboard := false;
;
#Reset_Unit: // Statement section case 9
#IL150_Data.Reset := false;
;
#Shutter_Close: // Statement section case 10
#IL150_Data.Close_Shutter := false;
;
#Program_Material: // Statement section case 11
#IL150_Data.Program_Material := false;
;
#Select_Material: // Statement section case 12
#IL150_Data.Select_Material := false;
;
#Program_Analogue: // Statement section case 13
#IL150_Data.Program_Analogue := false;
;
#Thickness_Look: // Statement section case 14
#IL150_Data.Thickness_Look := false;
;
#Thickness_Change: // Statement section case 15
#IL150_Data.Thickness_Change := false;
;
ELSE // Statement section ELSE
;
END_CASE;
END_IF;
END_FUNCTION_BLOCK