S7-1200 Non-Linear 4-20mA Sensor Lookup Table with SCL

David Krause13 min read
S7-1200SiemensTutorial / How-to
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

1. Problem Definition and Engineering Context

Many process sensors (pH probes, conductivity cells, ultrasonic level transmitters, capacitive pressure sensors, damped humidity probes, vortex flowmeters, and certain Coriolis density meters) produce a 4-20 mA output that is intentionally non-linear with respect to the measured variable. The sensor manufacturer publishes a calibration table where each integer raw count (after the S7-1200 analog input is normalized from 0-27648 to 0-20 mA, or from 5530-27648 to 4-20 mA) maps to a specific engineering value. When the table contains 100-300 points, hand-coding each block of IF...THEN statements or each comparison ladder rung becomes impractical and creates a maintenance burden.

The recommended engineering pattern on the S7-1200 platform is to store the engineering values in an ARRAY contained inside a dedicated FUNCTION_BLOCK, expose a single input (raw integer) and output (REAL engineering value) and search the table from a cyclic organization block (OB1 or OB30..OB38 depending on cycle time). Using SCL (Structured Control Language) instead of ladder keeps the lookup logic compact, version-controlled, and portable between CPU firmware V4.x and V5.x.

Important: SCL is supported on every S7-1200 CPU (1211C, 1212C, 1214C, 1215C, 1217C) from firmware V4.0 onward and is fully integrated into TIA Portal V13 SP1 and later. For 300-point lookup tables, use at least a CPU 1214C DC/DC/DC (6ES7214-1AG40-0XB0) with 100 KB work memory, or a CPU 1215C (6ES7215-1AG40-0XB0) with 125 KB work memory, to ensure enough load memory for the SCL compiled code and the data array.

2. Prerequisites and S7-1200 Hardware Selection

Before writing a line of SCL, confirm that the hardware and firmware meet the following minimum requirements.

Component Minimum Requirement Recommended
CPU CPU 1212C DC/DC/DC (6ES7212-1AE40-0XB0), FW V4.2 CPU 1214C DC/DC/DC (6ES7214-1AG40-0XB0), FW V4.4 or V4.5
Signal Module SM 1231 AI4 x 13 bit (6ES7231-4HD32-0XB0) SM 1231 AI4 x 16 bit (6ES7231-5ND32-0XB0) for higher resolution
Work Memory 50 KB free after program load 100 KB free to allow table growth
TIA Portal V15.1 with S7-1200 HSP V17/V18 with installed S7-1200 System Manual, edition 06/2024
SCL Compiler SCL V15.1 SCL V18 (bundled in TIA Portal)
Step 7 Basic License Step 7 Basic V15 Step 7 Professional V18 (allows SCL blocks)

The S7-1200 part-numbering logic follows the pattern 6ES7 2xx-yyy40-0XB0 for the fourth-generation 121xC family. Always cross-reference the MLFB against the SIMATIC S7-1200 Programmable Controller System Manual before ordering, because certain suffixes indicate conformal coating, extended temperature range, or different analog resolutions.

3. SCL Programming Environment Setup

  1. Open TIA Portal and select the project tree PLC_x > Program blocks.
  2. Right-click Program blocks > Add new block, choose Function Block, language SCL, name FB_SensorLUT, number 100. Enable the option Multi-instance capable.
  3. In Project tree > PLC_x > Properties > Protection, set the know-how protection only if the FB will be reused commercially; otherwise leave it open for service.
  4. Add a global DB named DB_LUT_Data (DB number 200) that will hold the engineering values. The DB is normally generated automatically as part of the FB instance, but having a global copy simplifies CSV export/import via the watch table mechanism described in section 7.
  5. Confirm that the SCL editor is set to IEC 61131-3 strict mode (TIA Portal default). This avoids implicit type conversions that can truncate raw integers.

4. Defining the Lookup Data Structure

The correct IEC 61131-3 data type for a fixed-size lookup table on the S7-1200 is an ARRAY of REAL. Historically, engineers on the older S7-200 and S7-300 platforms used separate WORD or REAL tags in a DB and addressed them by absolute name (e.g., DB100.DBD0, DB100.DBD4). On the S7-1200, this approach still works but is error-prone because the compiler does not check array bounds.

Declare the lookup array inside the FB static section:

FUNCTION_BLOCK FB_SensorLUT
{ S7_Optimized_Access := 'TRUE' }
VERSION : 1.0

VAR_INPUT
    iRawValue   : INT;     // 4-20 mA normalized to 5530..27648
    bExecute    : BOOL;    // Rising edge triggers one lookup
END_VAR

VAR_OUTPUT
    rEngValue   : REAL;    // Engineering value in physical unit
    bValid      : BOOL;    // TRUE when raw input lies inside the table
    bOverflowLo : BOOL;    // TRUE when raw input < first point
    bOverflowHi : BOOL;    // TRUE when raw input > last point
END_VAR

VAR
    aRaw   : ARRAY[1..300] OF INT;     // Sorted ascending raw counts
    aEng   : ARRAY[1..300] OF REAL;    // Engineering values
    iCount : INT := 300;               // Active number of points
END_VAR

VAR_TEMP
    iLow  : INT;
    iHigh : INT;
    iMid  : INT;
    rFrac : REAL;
END_VAR

The optimized bit access attribute (S7_Optimized_Access := 'TRUE') is the S7-1200 default from firmware V4.2 and stores the array in a way that the symbolic name is preserved in the watch table. Symbolic access is mandatory if the lookup table has to be loaded from a CSV file using the TIA Portal "Export/Import" wizard.

Common compile error: "Invalid data type BLOCK_DB". The keyword BLOCK_DB belongs to the legacy S7-300/400 STL world. On the S7-1200 use only the IEC 61131-3 generic keywords BOOL, INT, DINT, REAL, ARRAY, STRUCT. If you need to pass a DB to a function, use VARIANT instead.

5. SCL Lookup Function Block Implementation

The fastest deterministic lookup for a 300-point sorted table is a binary search with eight iterations (2^8 = 256, 2^9 = 512). SCL syntax for the algorithm is shown below. The block runs in well under 100 microseconds on a CPU 1214C, easily fitting into any OB1 cycle.

BEGIN
    // ---- 1. Boundary checks -------------------------------------------------
    IF iRawValue < aRaw[1] THEN
        rEngValue   := aEng[1];
        bValid      := FALSE;
        bOverflowLo := TRUE;
        bOverflowHi := FALSE;
        RETURN;
    END_IF;

    IF iRawValue > aRaw[iCount] THEN
        rEngValue   := aEng[iCount];
        bValid      := FALSE;
        bOverflowLo := FALSE;
        bOverflowHi := TRUE;
        RETURN;
    END_IF;

    // ---- 2. Binary search for bracketing indices ---------------------------
    iLow  := 1;
    iHigh := iCount;

    WHILE (iHigh - iLow) > 1 DO
        iMid := (iLow + iHigh) DIV 2;
        IF iRawValue > aRaw[iMid] THEN
            iLow := iMid;
        ELSE
            iHigh := iMid;
        END_IF;
    END_WHILE;

    // ---- 3. Linear interpolation between iLow and iHigh --------------------
    IF aRaw[iHigh] = aRaw[iLow] THEN
        rFrac := 0.0;     // Avoid divide-by-zero on duplicate entries
    ELSE
        rFrac := (INT_TO_REAL(iRawValue - aRaw[iLow])) /
                 (INT_TO_REAL(aRaw[iHigh] - aRaw[iLow]));
    END_IF;

    rEngValue   := aEng[iLow] + (aEng[iHigh] - aEng[iLow]) * rFrac;
    bValid      := TRUE;
    bOverflowLo := FALSE;
    bOverflowHi := FALSE;
END_FUNCTION_BLOCK

The algorithm guarantees O(log n) execution time and is constant across the entire input range. With 300 points the loop executes at most nine times. Because aRaw is declared as ARRAY[1..300] inside the FB static area, the compiler places it in the instance DB (DB100) and the IEC check Array bounds option can be enabled for early debugging.

6. Linear Interpolation Between Sample Points

If the calibration certificate gives only 100 points but the engineering tolerance is ±0.5 percent of span, interpolation between the bracketing points is essential. The interpolation factor rFrac computed in section 5 is dimensionless and clamped implicitly by the boundary checks. For monotonic curves this yields sub-LSB accuracy between the discrete calibration points.

For curves that are very steep at the low end (e.g., pH sensors where 4 mA = pH 0 and 5 mA = pH 2), use logarithmic interpolation by transforming both raw and engineering values to log space before the lookup:

// Pre-compute in the initialization section (OB100) once per warm restart
FOR i := 1 TO 300 DO
    aLogRaw[i] := LN(INT_TO_REAL(aRaw[i]));
    aLogEng[i] := LN(aEng[i]);
END_FOR;

// Then run the binary search on aLogRaw and exponentiate the result
rEngValue := EXP(aLogEng[iLow] + (aLogEng[iHigh] - aLogEng[iLow]) * rFrac);

Logarithmic interpolation is also the correct choice for level sensors where the 4-20 mA output represents a non-linear function of the tank geometry (sphere, horizontal cylinder, or inverted cone).

7. Loading the 300-Point Table Efficiently

Manually typing 300 pairs of integers and REALs into the FB instance DB is the single largest time sink. Three practical methods are supported on the S7-1200 firmware.

7.1 CSV Import via TIA Portal

  1. In the project tree, right-click Program blocks > FB_SensorLUT (FB100) > Instance DB > DB100 and choose Export to CSV.
  2. Open the CSV in Microsoft Excel. Columns A (Index), B (Raw), C (Eng). Sort ascending by raw count.
  3. Save as FB100_DB100.csv using File > Save As > CSV UTF-8.
  4. Right-click the instance DB and choose Import from CSV. The import wizard validates the row count and flags any raw value that is not strictly increasing.

7.2 Watch Table Fill via Initial Value Download

A watch table with 50 or fewer entries is fully supported by the S7-1200 web server according to the SIMATIC S7-1200 Web Server Watch Tables documentation. Larger tables must be split across multiple watch tables or, preferably, downloaded as the initial values of the instance DB during the program download.

7.3 Recipe Data Block (Recipe DB)

For applications where the calibration changes when a different sensor is connected (e.g., a test rig with swappable probes), store the table in a separate global DB DB_Recipe and use the PLC recipe functions of TIA Portal. The recipe function generates the READ_DBL and WRIT_DBL SCL calls automatically and writes the data block directly to load memory.

8. Calling the Lookup FB from a Cyclic OB

Wire the FB in OB1 (or in OB30 if the sensor is read at 100 ms). The instance DB is generated automatically on first download.

// OB1 - Main program sweep
"FB_SensorLUT_DB"(iRawValue   := "iw_AI0_Norm",
                  bExecute    := TRUE,
                  rEngValue   => "rPressure_bar",
                  bValid      => "bPressure_OK",
                  bOverflowLo => "bPressure_Under",
                  bOverflowHi => "bPressure_Over");

// Scale the raw AI to 5530..27648 in OB1 before the call
"iw_AI0_Norm" := "Scale_AI_To_0_27648"("iw_AI0_Raw");

The S7-1200 analog input module SM 1231 returns 0-27648 for a 0-20 mA signal or 0-27648 with clipping at 5530 for 4-20 mA (overrange to 0 and 27648 if the channel is configured for current, not voltage). Always confirm the channel configuration is Current 4-wire or Current 2-wire in the device configuration; a voltage configuration on a current-output sensor will produce negative raw counts and immediately trip bOverflowLo.

9. Commissioning with Watch Tables and the Web Server

  1. Connect the CPU to the engineering station via Profinet or the integrated Ethernet port.
  2. Open Online & Diagnostics > Watch tables and create a watch table named WT_Pressure_Cal. Add the symbolic tags "iw_AI0_Norm", "rPressure_bar", "bPressure_OK", "bPressure_Under", and "bPressure_Over".
  3. Enable the S7-1200 web server (CPU properties > Web server > Activate web server on this module). The web server watch tables then become accessible from any browser at http://<cpu-ip>/ under Watch tables, which is invaluable when a tablet or a phone is the only available HMI on site.
  4. Force a known reference signal (e.g., a Druck DPI 880 calibrator at 12.000 mA) and verify that the resulting raw count and engineering value match the calibration certificate within ±0.1 percent.
Security note: Activate web server access only with HTTPS and a user with the right Read watch table. Siemens documents the security configuration in the S7-1200 System Manual section "Web server > Security".

10. Verification and Calibration Checks

Verification consists of a five-point up-scale and down-scale calibration. Use the following acceptance criteria.

Calibration Point Reference mA Expected Raw Count Expected Eng Value Pass Criterion
0 percent 4.000 5530 1.000 bar (example) ± 1 LSB raw, ± 0.05 bar eng
25 percent 8.000 11060 per certificate ± 2 LSB raw
50 percent 12.000 16589 per certificate ± 2 LSB raw
75 percent 16.000 22118 per certificate ± 2 LSB raw
100 percent 20.000 27648 per certificate ± 1 LSB raw

Record the up-scale and down-scale values in a calibration log. A hysteresis larger than 0.3 percent of span indicates a sensor issue, not a PLC scaling issue.

11. Troubleshooting Matrix

Symptom Likely Root Cause Diagnostic Step Fix
Compiler error "Invalid data type BLOCK_DB" Legacy STL keyword used in SCL Search source for BLOCK_DB Replace with VARIANT or remove type declaration
All values return the first array element aRaw not sorted ascending Open watch table, sort aRaw[1..300] Re-import CSV sorted by raw count
rEngValue jumps erratically Duplicate raw count entries Watch table search for duplicates Remove duplicate row, re-import
bOverflowLo always TRUE Channel configured for voltage instead of current Device configuration > AI channel > Signal type Change to Current 4-wire
SF (System Fault) LED on CPU OB121 not loaded and array out-of-bounds occurred Online & Diagnostics > Diagnostic buffer Download OB121 and verify array bounds
Compile error "Array index out of user range" Index variable type mismatch (SINT vs INT) Check iMid, iLow, iHigh declarations Declare all loop variables as INT
Web server watch table missing tags More than 50 entries in a single watch table Count entries in WT Split into multiple watch tables per S7-1200 Web Server documentation
CPU goes STOP with "IO access error" SM 1231 not inserted in device configuration Device view > compare to physical rack Add SM 1231, download HW config

12. Performance, Memory, and Optimization Notes

  • Code size: The compiled SCL binary for a 300-point lookup FB occupies roughly 8-12 KB of work memory on a CPU 1214C. Verified against the S7-1200 resource tables in the System Manual.
  • Execution time: Binary search + interpolation requires < 100 microseconds on a CPU 1214C DC/DC/DC at firmware V4.4. This is well inside the OB1 minimum cycle of 1 ms.
  • Memory layout: Two arrays of 300 elements each cost 600 * 4 bytes = 2400 bytes of work memory for REAL, plus 600 * 2 bytes = 1200 bytes for INT. The remaining memory is available for additional program blocks.
  • Optimization: If the sensor curve is polynomial of degree 3 or 4, replacing the table with a Horner-evaluated polynomial (rEngValue := K0 + X * (K1 + X * (K2 + X * K3))) shrinks the memory footprint by 99 percent at the cost of small fitting error. Use polynomial only when the manufacturer provides certified polynomial coefficients (common for Pt100/Pt1000 and thermocouples).
  • Multi-sensor scenarios: For more than four sensors of the same family, instantiate the FB four times with the multi-instance flag. The total instance DB size scales linearly with the number of sensors and remains inside the work memory of a CPU 1215C (125 KB).

13. Frequently Asked Questions

What is the maximum number of array elements I can declare in an S7-1200 SCL FB?

The S7-1200 supports arrays with index range -32768 to 32767. Practical limits depend on work memory; a 300-element ARRAY of REAL plus a parallel 300-element ARRAY of INT uses about 3.6 KB, which fits in any CPU 1212C or higher. The S7-1200 System Manual lists exact work memory per array element in section "Data types".

Why does my SCL block compile with "Invalid data type BLOCK_DB" on the S7-1200?

The keyword BLOCK_DB is an S7-300/400 STL remnant and is not part of the IEC 61131-3 grammar accepted by the S7-1200 SCL compiler. Replace it with VARIANT if a DB pointer is needed, or remove the explicit type declaration entirely if the FB is called directly with a symbolic instance DB name.

Can the web server display watch tables with more than 50 entries?

The S7-1200 web server documentation explicitly states that watch tables with 50 or fewer entries are fully displayed. Larger watch tables must be split into multiple tables of at most 50 entries each. Refer to the S7-1200 web server watch tables page for the exact behavior.

How do I import a 300-row sensor calibration file into the instance DB?

Export the instance DB to CSV (right-click the DB > Export to CSV), edit the columns in Excel sorted ascending by raw count, save as CSV UTF-8, then right-click the DB and choose Import from CSV. The wizard validates the row count and flags duplicate or non-monotonic raw values.

Does linear interpolation between lookup points satisfy typical process accuracy requirements?

For most process-grade 4-20 mA sensors with a published calibration table of 100-300 points, linear interpolation between bracketing samples delivers sub-LSB accuracy of 0.05 percent to 0.1 percent of span, which meets ISA RP 7.7 for typical measurement loops. For higher accuracy, switch to logarithmic interpolation in the FB initialization as shown in section 6.

Back to blog