Lasse Hedeby

Sharing my passion for automation, programming, IT and other geeky stuff

Simple CRC32 function for SIMATIC controllers.

  { S7_Optimized_Access := 'TRUE' }
  VERSION : 0.1
    data : Array[0..4095] of Byte;
    length : Int;

    rem : DWord;
    i : Int;
    j : Int;

    POLYNOMIAL : DWord := 16#ABCDEF01;  // Chose your polynomial here

  #rem := 16#ffffffff;
  FOR #i := 0 TO (#length-1) DO
    #rem := #rem XOR #data[#i];
    FOR #j := 0 TO 7 DO
      IF #rem.%X31 THEN // if leftmost (most significant) bit is set
        #rem := SHR(IN := #rem, N := 1) XOR #POLYNOMIAL;
        #rem := SHR(IN := #rem, N := 1);
  #FCCRC32Calc := #rem XOR 16#ffffffff;

If the function does not work as expected, it’s often because the endianess is not correct between sender and receiver. Change the #rem.%X31 bit to #rem.%X0 to see if it helps.

March 28th, 2018

Posted In: Automation, Coding, S7-1200/1500, Security, SIMATIC, Structured Text (SCL/ST)

Tags: , , ,

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);
   // Add Carriage Return after each line
   statSendCharactors[statMemoryCharIndex] := '$R';
   // Increment charactor index
   statMemoryCharIndex := (statMemoryCharIndex + 1); 

The block itself handles the TCP/IP communication and acts as client.



August 3rd, 2016

Posted In: Automation, IT, S7-300/400, SIMATIC, Structured Text (SCL/ST)

Tags: , , , , ,

Although SIMOTION does not support Modbus out-of-the-box, it does support TCP/IP socket communication. Siemens has not made a library for Modbus TCP/IP, so when I needed one, I had to make it myself.

What is Modbus and how does it works? I started reading the Protocol Specification and then the TCP/IP Implementation Guide from

Protocol Specification

This document describes the protocol and how it works, disregard of communication form. The Modbus protocol  is a simpel protocol data unit called PDU (nice right?) that consists of a function code and some data.


The additional fields is added when mapping the protocol on different networks or busses. In this case we use TCP/IP.

TCP/IP Implementation Guide

This document describes how to map the modbus protocol onto a TCP socket communication. When doing so an additional field is added called MBAP Header.


The MBAP Header contains;



The function block I made for SIMOTION only implements the functions codes 0x03 (Read Holding Registers) and 0x10 (Write Multiple Registers). Others I don’t need. I used the MB_CLIENT for S7-1200/1500 from Siemens as templates, hence the naming is similar and not following the programing style guide from PLCOpen.

Because we use TCP the function also requires the LCom Library for SIMOTION from Siemens. I could use the system functions for TCP but, it is just easier to use LCom since Siemens are maintaining it, and it works. It can be downloaded here:

Also the help content provided in TIA Portal for the MB_CLIENT block can be used, as the parameters behave the same.



May 11th, 2016

Posted In: Automation, SIMOTION, Structured Text (SCL/ST)

Tags: , , , , ,

Next Page »