Lasse Hedeby

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

I’ve made a random key generator for a S7-1200 PLC. It uses a random integer generator from Siemens to select the character position in a string of charactors and then add this particular character to a new string. This new string is the unique key.

The random integer generator reads the realtime clock in the CPU and uses the nanosecond data type for random integer generator.

This is not at truly random, unique safe generator that can be used in cryptography or other ways to secure anything. It can add an extra level of security but it can also be predicted.

// Reset in every cycle
#tempError  := False;
#tempStatus := #NO_JOB;

// Rising edge on execute
#statExecuteTrig   := #execute AND NOT #statExecuteMemory;
#statExecuteMemory := #execute;

// Generate key on rising edge
IF #statExecuteTrig THEN
  // Define list of charactors
  #tempCharactors := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA9876543210-';
  #tempCharLength := LEN(#tempCharactors);

  // Charactor loop
  #tempString := '';
  #statRandomInt := 0;
  FOR #tempIndex := 0 TO (#length - 1) DO
    #tempRepeat := 0; // Prevent cycle time overflow
    REPEAT
      #tempRepeat := #tempRepeat + 1;
      // Generate a random number for charactor index
      #tempRandomInt := "LGF_RandomInt"(minValue := 1, maxValue := #tempCharLength);
    UNTIL (#statRandomInt <> #tempRandomInt) OR (#tempRepeat > 4) // Prevent dublicates next to each other
    END_REPEAT;
    // Add to string
    #tempString := CONCAT(IN1 := #tempString, IN2 := MID(IN := #tempCharactors, P := #tempRandomInt, L := 1));
    // Save last random int
    #statRandomInt := #tempRandomInt;
  END_FOR;

  // Write key and length
  #uniqueKey  := #tempString;
  #keyLength  := LEN(#tempString);
  #tempStatus := #JOB_COMPLETE;
END_IF;

// Reset if not execute
IF NOT #execute THEN
  #uniqueKey := '';
  #keyLength := 0;
END_IF;

// Update outputs
#error  := #tempError;
#status := #tempStatus;

Attachements:

 

February 20th, 2016

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

Tags: , , , ,

Discovery Channel Denmark has made a video on how VELUX Roof Windows are made (In Danish):

FF Velux vinduer from Mediehuset Ingeniøren on Vimeo.

An English version is available on YouTube:

February 19th, 2016

Posted In: Automation, Industry

Tags: , , ,

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.

February 19th, 2016

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

Tags: , , , ,

Next Page »