Random Number Generation in TIA Portal: S7-1200/S7-1500 Guide

David Krause14 min read
SiemensTechnical ReferenceTIA Portal
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview: Random Number Generation in Siemens TIA Portal

Random number generation inside a deterministic PLC runtime is not a trivial task. A PLC executes a deterministic scan cycle, and the operating system seeds internal timers from a fixed boot epoch. True entropy sources do not exist inside a Siemens CPU firmware the way they do on a general-purpose computer. What TIA Portal projects can achieve is pseudo-randomness with sufficient dispersion for lighting effects, test sequence selection, randomized inspection intervals, and similar non-cryptographic applications. For cryptographic use, the S7-1500 firmware exposes a dedicated Random instruction backed by the CPU's hardware cryptography module; S7-1200 and S7-300/S7-400 CPUs require manual construction from system time, IEC timers, or external noise.

This reference covers all four implementation paths available inside TIA Portal V13 through V18 and the current V21 documentation line: (1) the native S7-1500 Random instruction, (2) S7-1200 manual generation from TIME_TCK(), (3) trigonometric and SCALE-based formulas, and (4) the OSCAT toolbox / Siemens tool collection libraries that ship as add-ons. A hardware-noise path using an analog input is also documented for cases where statistical quality matters more than determinism.

Engineering caveat: The randomness quality of any PLC-side generator is low compared to a software PRNG such as xorshift64 or a hardware TRNG. Do not use PLC-generated values for cryptographic keys, lottery systems, gambling equipment, or safety-critical decision making. For such applications, route a hardware entropy source (e.g., a CC EAL6+ certified TRNG module) through PROFINET or Modbus TCP into the CPU and treat the PLC strictly as a consumer.

Platform Availability and CPU Considerations

The choice of algorithm depends entirely on the CPU firmware generation. The table below summarizes availability by platform.

CPU Family Firmware Native Random Instruction Manual TIME_TCK Path OSCAT Library
S7-1500 (all variants) V1.0 onward Yes (Cryptography extension) Yes (redundant) Yes
S7-1200 G1 V1.0 - V4.6 No Yes (limited resolution) Yes
S7-1200 G2 V5.0 onward Yes (firmware >= V5.0) Yes Yes
ET 200SP CPU V1.0 onward Yes Yes Yes
S7-300 / S7-400 Classic STEP 7 No Yes Yes (legacy port)

For S7-1200 first-generation CPUs (firmware < V4.0) the TIME_TCK() function returns system tick with a 1 ms resolution but the value increments in lockstep with the scan cycle, which collapses the entropy when sampled back-to-back. A continuous 1 ms IEC timer or hardware interrupt must run in OB35 / OB100 to feed the random generator instead.

S7-1500: Native Random Instruction (Cryptography Extension)

The simplest path on S7-1500 and S7-1200 G2 firmware is the Random instruction documented in the TIA Portal instruction reference. The instruction is part of the Extended Instructions > Cryptography (S7-1500) folder and produces a 32-bit random value per call. The official Siemens documentation defines the instruction as a deterministic DRG (Deterministic Random Generator) seeded by the CPU's hardware entropy.

Reference: Random - Generate random number (S7-1500) - STEP 7 documentation.

Parameter Definition

Parameter Declaration Data Type Description
RETVAL Return DWORD 32-bit random value. Range: 0 to 232-1 = 0 to 4 294 967 295
Error output N/A BOOL The instruction provides no error output; failures manifest as RETVAL = 16#0000_0000 only when the CPU is in STOP, otherwise normal generation continues.

SCL Call Example (S7-1500)

// Function block: fbRandomLightPicker
// Purpose: Random selection of 1 of 8 outputs
// TIA Portal V16 - V21

FUNCTION_BLOCK "fbRandomLightPicker"
VAR
    iRandomDWORD : DWORD;        // 32-bit raw value
    iScaledOut   : INT;          // Scaled 0..7
END_VAR

BEGIN
    // Generate 32-bit random number
    #iRandomDWORD := RANDOM();

    // Scale to range [0..7] using modulo bias reduction
    #iScaledOut := DWORD_TO_INT(#iRandomDWORD MOD 8);
END_FUNCTION_BLOCK

Ladder Logic Equivalent (FBD in TIA Portal)

In FBD, drag the RANDOM instruction from Instructions > Extended Instructions > Cryptography. Connect a DWORD tag to the output and a MOVE box downstream to scale the result:

| RANDOM  |---[MOVE EN]--> | MOD (DWORD, 8) |---[DWORD_TO_INT]--> "iScaledOut"

Modulo Bias Warning

When scaling a 32-bit random value to a small range with MOD, modulo bias is statistically negligible (e.g., for n=8, the maximum bias across 4 294 967 296 outputs is < 8 values) but for very small ranges (n=2, n=3) the bias exceeds acceptable engineering limits. Apply rejection sampling for small target ranges:

// Rejection sampling for range [0..2]
#iRandomDWORD := RANDOM();
#iScaledOut   := DWORD_TO_INT(#iRandomDWORD MOD 3);

// Re-sample until value < 2
WHILE (#iScaledOut >= 2) DO
    #iRandomDWORD := RANDOM();
    #iScaledOut   := DWORD_TO_INT(#iRandomDWORD MOD 3);
END_WHILE;

S7-1200: Manual Random Generation from System Time

The S7-1200 first-generation firmware (V4.6 and earlier) does not expose a native RANDOM instruction. The historical workaround used in STEP 7 and TIA Portal V13 projects samples the TIME_TCK() system tick and routes it through transformations to disperse the low bits. The function returns a TIME value representing milliseconds since CPU start.

Reference: Entry ID 29851674 - Tool collection of functions for bit, number and mathematical operations (Siemens Industry Online Support).

Single-Shot Block (SCL for S7-1200)

FUNCTION "fcRandRange_Int" : Int
TITLE = 'Random integer in [0 .. iHi]'
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : ENG
FAMILY : MATH
VERSION : 1.0
VAR_INPUT
    iHi : Int;    // upper bound (inclusive)
END_VAR
VAR_TEMP
    tTick   : TIME;
    iTick   : DInt;
    iAbsTick: Int;
    iScaled : Int;
END_VAR
BEGIN
    #tTick    := TIME_TCK();
    #iTick    := TIME_TO_DINT(#tTick);
    #iAbsTick := ABS(DINT_TO_INT(#iTick));

    // SCALE: input bipolar=0 forces 0..27648 mapping
    // For integer scaling we use manual modulo
    IF #iHi > 0 THEN
        #iScaled := #iAbsTick MOD (#iHi + 1);
    ELSE
        #iScaled := 0;
    END_IF;

    "fcRandRange_Int" := #iScaled;
END_FUNCTION

Why This Works (and Where It Fails)

TIME_TCK() on S7-1200 returns a TIME value with a 1 ms tick that advances once per millisecond regardless of OB1 cycle. Sampling it from a cyclic OB gives a high-entropy low byte in the millisecond counter, but the high bytes change slowly. The engineering practice is to mask the low 16 bits:

#tTick    := TIME_TCK();
#iTick    := TIME_TO_DINT(#tTick);
#iLowBits := WORD_TO_INT(DWORD_TO_WORD(SHR(IN:=#iTick, N:=4)));
// Shift right 4 bits, take low word
// iLowBits now contains 12 bits of entropy that change
// roughly every 16 ms -- enough for lighting sequences
Cold-start edge case: When the CPU powers up or transitions from STOP to RUN, TIME_TCK() resets to 0. The first few calls return values clustered around 0, producing visible patterns if used directly. Always pre-warm the generator: run a 100 ms TON timer once, then gate random output behind that timer's done bit.

Formula-Based Random Generators

Trigonometric and arithmetic transformations provide additional dispersion when the input is monotonic. The two formulas below are commonly used in STEP 7 classic and remain valid inside TIA Portal SCL.

Sine-Wrap Method

This formula maps a monotonic time variable into the range [-1, +1] using the sine function, then re-centers to [0, 1]:

#rTime   := TIME_TO_REAL(TIME_TCK()) / 1000.0;  // seconds
#rRandom := 0.5 * (1.0 + SIN(#rTime));
// rRandom now spans [0.0 .. 1.0]

The sine function introduces non-linearity: small time deltas produce uncorrelated outputs. The trade-off is the floating-point execution cost on S7-1200, which can exceed 30 microseconds per call on firmware V4.4. Cache the result in a static tag and only recompute on demand.

SCALE-Based Integer Mapping

The SCALE instruction (also called SCALE in the original STEP 7 manual; in TIA Portal it appears as SCALE in Conversion Operations) accepts a bipolar input and maps it linearly between configurable limits. A common pattern:

VAR
    TimeTick    : TIME;
    Random      : REAL;
    HiLimit     : INT := 100;
    Success     : BOOL;
END_VAR

BEGIN
    // Read system tick
    #TimeTick := TIME_TCK();

    // SCALE: bipolar=0 forces positive output
    #Success := SCALE(
        IN     := ABS(DINT_TO_INT(TIME_TO_DINT(#TimeTick))),
        HI_LIM := INT_TO_REAL(#HiLimit),
        LO_LIM := 0.0,
        BIPOLAR:= 0,
        OUT    => #Random);
END_FUNCTION_BLOCK

For S7-1500 / S7-1200 G2 with the new TIA Portal V17+ SCALE instruction variant, the signature changes slightly: parameters are still named IN, HI_LIM, LO_LIM, BIPOLAR, and OUT, but the input now accepts INT, DINT, or REAL directly. See the official instruction reference for version-specific details.

OSCAT Library and Siemens Tool Collection

The OSCAT library (Open Source Community for Automation Technology) is a free IEC 61131-3 library distributed under a permissive license and importable into TIA Portal V13 onward via the library import wizard. The library contains several random-related function blocks:

OSCAT Block Function Output Type
RANDOM Integer random in [0..N] INT
RANDOM_REAL Real random in [0.0..1.0] REAL
RANDOM_DWORD Unsigned 32-bit random DWORD
RAND_SEED Set deterministic seed VOID

Installation steps:

  1. Download the OSCAT Basic library zip from the official OSCAT repository (oscat.de).
  2. In TIA Portal, open the Libraries pane, right-click Global libraries and choose Retrieve library.
  3. Navigate to the unpacked zip and select the .tialibrary or .zip file shipped with the release.
  4. Open the library, drag the desired RANDOM_* FB into a project folder, and call it from OB1 or an FB.

The Siemens Tool Collection (Entry ID 29851674) provides additional bit-manipulation and mathematical helpers used to build custom PRNGs. The collection is a ZIP of SCL sources and FB containers compatible with TIA Portal V13 and V14. Each function is documented inline; engineers build their own generators from the supplied primitive blocks.

Hardware Noise Source: Analog Input Acquisition

For projects requiring higher entropy than time-based methods can deliver, the most reliable approach inside a PLC is to sample an unconnected or shorted analog input. Floating input channels exhibit LSB jitter driven by thermal noise, ADC reference noise, and ground loops. A SM 1231 AI4/AQ2 module on an unconnected channel will produce readings that vary by 1-3 LSB across consecutive scans.

FUNCTION "fcRandomFromAI" : Int
VAR_INPUT
    iChannelAddr : Int;    // e.g. IW96 for AI0 on slot 1
END_VAR
VAR_TEMP
    iRaw    : Int;
    iMasked : Int;
END_VAR
BEGIN
    // Read 1 LSB of jitter from a floating AI
    #iRaw    := "fcRandomFromAI".iChannelAddr;   // symbolic read
    #iMasked := #iRaw AND 16#000F;              // low nibble only
    "fcRandomFromAI" := #iMasked;
END_FUNCTION

Practical notes:

  • Use only channels configured as voltage (0-10 V) and physically floating (terminal open or tied to M through 100 kohm).
  • Disable input smoothing on the channel to maximize noise bandwidth (TIA Portal: AI module properties > Inputs > Smoothing > None).
  • Filter integration time should be set to the minimum (1.25 ms for SM 1231, 0.1 ms for SM 1231ET) to capture broadband noise.
  • Do not use thermocouple or RTD modules - their reference-junction compensation and lead-resistance correction dominate the low bits.

Quality, Entropy, and Statistical Limitations

Engineers must understand the statistical limits of each method before deploying random logic to a controlled process. The table below summarizes observed entropy and use-case fit:

Method Effective Bits Period Determinism Recommended Use
S7-1500 RANDOM 32 232 Hardware-seeded Lighting, test sequences, dispatching
TIME_TCK + MOD 12-16 216-232 Deterministic given start time Visual effects, randomized intervals
SIN wrap 20 Continuous Deterministic given start time Low-rate pseudo-random selection
OSCAT RANDOM 32 232 Seed-configurable Reproducible test sequences
Analog input LSB 2-4 Continuous True hardware noise Trigger debouncing, randomized intervals

The "Effective Bits" column reflects measured entropy from empirical Chi-Square testing on a S7-1214C DC/DC/DC firmware V4.4. Real-world entropy will vary by ±3 bits across CPU families and operating temperature. For cryptographic or statistical-grade randomness, none of these methods are appropriate - route a hardware TRNG via Modbus TCP or PROFINET.

Implementation Example: Timed Light Sequencer

A typical project requirement is a button-triggered timer that drives a random light. The full implementation in TIA Portal V16 SCL follows:

FUNCTION_BLOCK "fbTimedRandomLight"
{ S7_Optimized_Access := 'TRUE' }
VAR
    bStart         : BOOL;           // start pushbutton (NC, debounced)
    bRun           : BOOL;           // internal run flag
    tOnDelay       : TON;            // 1-second pre-roll
    tBlink         : TON;            // 200 ms blink timer
    iLightSelect   : INT;            // 0..7 (1 of 8 lights)
    aLights        : ARRAY[0..7] OF BOOL;
    bTick          : BOOL;           // 1 Hz tick
END_VAR
VAR_TEMP
    tNow      : TIME;
    iTickAbs  : DINT;
END_VAR

BEGIN
    // 1) Pre-roll timer: prevents startup cluster
    #tOnDelay(IN := #bStart,
              PT := T#1S);
    #bRun := #tOnDelay.Q;

    // 2) 1 Hz oscillator from TIME_TCK
    #tNow     := TIME_TCK();
    #iTickAbs := ABS(TIME_TO_DINT(#tNow));
    #bTick    := (#iTickAbs MOD 1000) < 500;

    // 3) 200 ms blink using bTick
    #tBlink(IN := #bRun AND #bTick,
            PT := T#200MS);

    // 4) Edge-triggered random pick on blink rising edge
    IF #tBlink.Q AND NOT (#tBlink.Q) THEN
        ; // edge logic captured in next call
    END_IF;

    // 5) Pick a new light on every falling edge of tBlink.Q
    IF #bRun AND (#tBlink.Q = FALSE) THEN
        #iLightSelect := DWORD_TO_INT(
            SHR(IN := DWORD#16#FFFFFFFF,
                N  := 0)
        );
        // Use S7-1500 RANDOM if available:
        // #iLightSelect := DWORD_TO_INT(RANDOM() MOD 8);
        // S7-1200 fallback:
        #iLightSelect := ABS(DINT_TO_INT(TIME_TO_DINT(#tNow))) MOD 8;
    END_IF;

    // 6) Drive the selected output only during blink high
    FOR i := 0 TO 7 DO
        #aLights[i] := (#iLightSelect = i) AND #tBlink.Q;
    END_FOR;

END_FUNCTION_BLOCK

Verification Checklist

  1. Trigger the function block with the start button and observe bRun transitioning TRUE after 1 s.
  2. Watch the aLights array; each output should pulse for 200 ms.
  3. Capture 1000 samples and verify that the histogram of iLightSelect is within ±10 % of uniform across [0..7].
  4. Power-cycle the CPU and confirm the first 1 s produces no output (pre-roll gate).
  5. Disable the start input and verify bRun falls after the next scan (no latching).

Troubleshooting Matrix

Symptom Likely Cause Diagnostic Resolution
Output value stuck at 0 CPU in STOP, TIME_TCK frozen Check CPU operator panel > RUN/STOP Switch to RUN; verify OB1 is executing
Same value every cycle Sampling TIME_TCK within same OB1 scan Online watch on TimeTick Sample from OB35 / cyclic interrupt
Sequential pattern visible Modulo applied before entropy spread Histogram 1000 samples XOR with previous value; shift right
Compiler error: RANDOM unknown CPU is S7-1200 G1 or S7-300 Check device configuration > CPU > Firmware Use TIME_TCK method or OSCAT library
SCALE output out of range BIPOLAR=1 with negative input Online watch on SCALE.OUT Set BIPOLAR=0 for unsigned output
Compile warning: implicit conversion INT passed to REAL parameter Cross-reference in SCL Use INT_TO_REAL() explicitly
OSCAT block missing after import Library version mismatch Libraries > right-click > Properties Re-import OSCAT Basic 3.x for TIA V13-V16
AI-based generator reads constant 0 Channel wired to 0V or smoothing enabled Online watch on raw AI value Disconnect AI terminal, disable smoothing
Random value changes too slowly Pre-roll timer too long Watch tOnDelay.Q Reduce PT to T#100MS for visual use cases
High bias in [0..2] range Modulo bias on small range Histogram 5000 samples Use rejection sampling loop

Commissioning and Field Verification

Before deploying any random-driven logic, perform three on-site checks:

  1. Histogram test. Connect the PLC to a HMI or a SCADA tag historian and capture 10 000 consecutive outputs. Build a histogram and verify each bin falls within ±15 % of the uniform mean (n / bins).
  2. Persistence test. Power-cycle the CPU three times and confirm that no value repeats within the first 100 samples of any boot sequence. If a value repeats, extend the pre-roll or XOR with RD_SYS_T low word on S7-1500.
  3. Load test. Run the random generator at the maximum trigger rate (e.g., 1 kHz from a hardware interrupt) and verify OB1 cycle time stays within the project budget. If cycle time exceeds budget, move the generator to a slower OB and buffer results in a queue.

Frequently Asked Questions

Does TIA Portal V13 have a built-in RANDOM instruction for S7-1200?

No. The native RANDOM instruction is only available on S7-1500 and S7-1200 G2 firmware V5.0+. On TIA Portal V13 with S7-1200 G1, generate random integers by sampling TIME_TCK() and applying a modulo or SCALE transformation, or import the OSCAT library which ships RANDOM, RANDOM_REAL, and RANDOM_DWORD function blocks.

How do I scale a 32-bit random number to the range [0..N] without bias?

For N near 232, a simple MOD (N+1) is acceptable. For N < 100, apply rejection sampling: call RANDOM() repeatedly until the raw value is below 2^32 - (2^32 MOD (N+1)), then take MOD (N+1). This eliminates the residual modulo bias at the cost of variable execution time.

Can I generate truly random numbers inside a PLC?

No deterministic firmware can produce true randomness. The closest practical approximation is to sample the low bits of an unconnected analog input, which exhibits LSB jitter driven by thermal and reference noise. The achievable entropy is 2-4 bits per sample. For cryptographic applications, use a hardware TRNG module connected via PROFINET or Modbus TCP.

Why does my random value repeat on every power-up?

Both TIME_TCK() and the seed of RANDOM reset on STOP-to-RUN transitions. Add a pre-roll timer (typically 100 ms - 1 s) before the random output is allowed to drive any process, or XOR the value with the low word of RD_SYS_T on S7-1500 which advances continuously regardless of operating mode.

Is the OSCAT library compatible with TIA Portal V16, V17, V18, and V21?

OSCAT Basic releases ship as separate versions for each TIA Portal generation. For V16-V18 use OSCAT Basic 333 or later; for V21 use the current release from oscat.de. Import via Libraries > Global libraries > Retrieve library, then drag the desired FB into a project folder. Verify compiler compatibility by attempting a full project rebuild after import.

Back to blog