A CAB printer can receive print jobs via Ethernet Raw using it’s own JScript syntax. Each command is separated by a line.
In order to do this from a SIMATIC S7-300 PLC, I’ve made an array of string (1-20) representing each line. Then the commands can be written directly in the code, and with CONCAT function dynamic data from tags can be added.
// // Generate lines // statLines[1] := 'J'; // Line of JScript statLines[2] := 'S l1;0,0,50,53,85;ErrLbl'; // Line of JScript statLines[3] := 'H 125,0,T,R0,B0'; // Line of JScript statLines[4] := 'O R,P'; // Line of JScript statLines[5] := 'T 0,7.77,0,3,4,u,k,q80;[J:c38.25]Production ID'; // Line of JScript statTempLine := 'B 8.16,12.58,0,datamatrix,1;'; // 1. part of line of JScript statLines[6] := CONCAT(IN1:=statTempLine,IN2:=statProductCode); // Combine 1. part with product code statLines[7] := 'T 36.16,8.02,0,3,4,u,k,q80;[J:c48.84]Error Code'; // Line of JScript statTempLine := 'T 37.6,14.64,0,3,6,k,q80;[J:c47.4]'; // 1. part of line of JScript statLines[8] := CONCAT(IN1:=statTempLine,IN2:=statErrorCode); // Combine 1. part with error code statTempLine := 'T 0,46.47,0,3,4,k,q80;[J:c78.93]'; // Line of JScript statLines[9] := CONCAT(IN1:=statTempLine,IN2:=statProductCode); // Combine 1. part with product code statLines[10] := 'G38.59,3.52,0;R:44.26,38.33,0.2,0.2'; // Line of JScript statLines[11] := 'A 1'; // Line of JScript statLines[12] := ''; statLines[13] := ''; statLines[14] := ''; statLines[15] := ''; statLines[16] := ''; statLines[17] := ''; statLines[18] := ''; statLines[19] := '';
Now each line can be combined into a array of characters and send as a TCP telegram using the T-Blocks (TCON, TSEND, TRCV etc.). What I do is to run a loop through each line and move each character to an array. At the end of each line I add a Carriage Return (0xD) to the array.
// Convert all lines to array of charactors for telegram handling FOR statIndexLines := 1 TO 11 DO // Find length of string statStringLength := LEN(statLines[statIndexLines]); // Run through string and move every charactor to array IF (statStringLength <> 0) THEN FOR statIndexLength := 1 TO statStringLength DO // Get charactor from string and move to array of charactors statSendCharactors[statMemoryCharIndex] := STRING_TO_CHAR(MID(IN:=statLines[statIndexLines],L:=1,P:=statIndexLength)); // Increment charactor index for every cycle statMemoryCharIndex := (statMemoryCharIndex + 1); END_FOR; END_IF; // Add Carriage Return after each line statSendCharactors[statMemoryCharIndex] := '$R'; // Increment charactor index statMemoryCharIndex := (statMemoryCharIndex + 1); END_FOR;
The block itself handles the TCP/IP communication and acts as client.
Attachements:
Hedeby August 3rd, 2016
Posted In: Automation, IT, S7-300/400, SIMATIC, Structured Text (SCL/ST)
In a project I needed information in a SIMATIC S7-300 PLC from a Data Matrix code containing a string with values separated by semicolon, like this
Value1;Value2;Value3;Value4
Because of the different length of each value I could not just read data from a fixed byte position, but had to search for the right position in the string to read from. And after that I didn’t knew the length of the value I had to read.
I came up with this;
//================================================================================================ // Hedeby.Net // (c)Copyright 2015 All Rights Reserved //------------------------------------------------------------------------------------------------ // file name: ReadDataMatrix // created by: LHH // library: - // system: Simatic S7-300 V3.3 // version: Step 7 V5.5 // restrictions: Cyclic task // requirements: - // functionality: This function block read the data matrix string from Jumo sensor and returns // the selected strings //================================================================================================ // Compiler Options //================================================================================================ { OverwriteBlocks := 'y'; // Overwrite the blocks GenerateReferenceData := 'y'; // Generate reference data CreateObjectCode := 'y'; // Create the object code OptimizeObjectCode := 'y'; // Optimize the object code MonitorArrayLimits := 'n'; // Monitor the array limits CreateDebugInfo := 'n'; // Create the debug info SetOKFlag := 'n'; // Set the OK flag SetMaximumStringLength := '254' // Maximum string length } //================================================================================================ // Change Log: //------------------------------------------------------------------------------------------------ // Version Date Author Description //------------------------------------------------------------------------------------------------ // 0.1 2015.09.02 LHH Created // 1.0 2015.09.02 LHH First release after testing // //================================================================================================ FUNCTION_BLOCK ReadDataMatrix TITLE = 'Read Data Matrix' VERSION: '1.0' AUTHOR: LHH VAR_INPUT valueIndex : INT; arrData : ARRAY[1..520] OF CHAR; END_VAR VAR_OUTPUT valueOutput : STRING; END_VAR VAR statIndex : INT; statFieldNumber : INT; END_VAR statFieldNumber := 0; valueOutput := ''; // Run through array of charactors FOR statIndex := 1 TO 520 DO // Read value index IF (valueIndex = statFieldNumber) AND NOT (arrData[statIndex] = ';') THEN valueOutput := CONCAT(IN1:=valueOutput,IN2:=CHAR_TO_STRING(arrData[statIndex])); END_IF; // Find separator IF (arrData[statIndex] = ';') THEN statFieldNumber := (statFieldNumber + 1); END_IF; // Stop when reached IF (valueIndex < statFieldNumber) THEN EXIT; END_IF; END_FOR; END_FUNCTION_BLOCK
The code is searching through the array of charactors to find the separator “;”. If valueIndex is equal to the actual field number the valueOutput is generated by adding a single character to the end of the string until the next separator i found.
When the valueIndex is reached the search stops to save cycle time.
Hedeby February 19th, 2016
Posted In: Automation, S7-300/400, SIMATIC, Structured Text (SCL/ST)