Validating Numeric Pad Input on Siemens HMI in TIA Portal
Siemens HMI panels (Basic, Comfort, and Unified) present a built-in numeric pad widget for operator entry. The pad has no native list validation, so any value within the configured data type range is accepted. When the application requires membership in a discrete set - recipe numbers, job IDs, machine constants, alarm codes - the validation must be implemented in PLC code. This article builds a three-layer validator: HMI tag limits, PLC membership check, and operator feedback, optimized for the S7-1200 CPU in TIA Portal V16 or later.
1. The Validation Problem in Operator Entry
The numeric pad on a KTP400, KTP700, KTP1200, or Comfort Panel is a text-entry widget: it accepts any character that maps to a valid integer or float. The widget has no list picker, no dropdown, no autocomplete. Range limits are the only built-in control. Common failure modes observed in field deployments include:
- Operator enters
10instead of100on a 3-digit recipe number. - Operator enters
0when the minimum valid value is 4. - Operator enters
255when the maximum is 250. - Operator scrolls the input spinner past the valid range and the panel accepts it.
- Operator types on a resistive-touch panel while wearing gloves and the value is misread.
A common field application requires the operator to select one of approximately 30 specific valid values - for example, recipe numbers that match an internal product catalog. The naive approach of building 30 individual comparators in ladder is unmaintainable, and the S7-1200 lacks a built-in in-list instruction. The robust solution distributes validation across three layers:
- HMI-side tag limits - clamp gross range errors (e.g., below 1 or above 255) on the panel itself.
- PLC-side lookup - check membership in the valid set inside the S7-1200 CPU.
- Operator feedback - visual and audible indication of accept/reject so the operator can correct immediately.
2. Prerequisites
Before starting, confirm the project meets the following requirements:
- SIMATIC S7-1200 CPU with firmware V4.2 or later (V4.4 recommended). Earlier firmware supports most features but not all SCL optimizations. See the S7-1200 Programmable Controller System Manual for firmware-to-feature mapping.
- STEP 7 Basic (for S7-1200) or Professional (for S7-1500 and S7-1200) in TIA Portal V16 or later. V18 is the current long-term release at time of writing; V19 is the most recent.
- HMI panel: KTP400 Basic, KTP700 Basic, KTP1200 Basic, or any Comfort Panel (TP700 Comfort through TP1900 Comfort).
- Configured HMI connection in the Devices & Networks editor.
- Defined set of 1-30 valid integer values for the application, ideally exported to a CSV for data-driven import.
- Familiarity with SCL (Structured Control Language) syntax. SCL is required for the lookup patterns; pure ladder is supported for small sets only.
3. HMI-Side Tag Limits (Layer 1)
Layer 1 catches out-of-range values before they reach the application logic. Configure limits on the HMI tag, not the PLC tag, so the entry is rejected on the panel.
3.1 Configuring the HMI Tag Range
- In the TIA Portal project tree, expand
HMI tagsand double-click the tag table (default name:Default tag table). - Add a new tag or select the existing tag that drives the numeric input field, e.g.,
"RecipeNumber". - Set the data type to
Int(orDIntif the application requires values outside the Int range). - Open the Properties pane at the bottom of the editor.
- Switch to the Range section.
- Tick the Lower limit checkbox and enter the minimum acceptable value (e.g.,
1). - Tick the Upper limit checkbox and enter the maximum acceptable value (e.g.,
255). - Compile the HMI station and download to the panel.
3.2 Wiring the Out-of-Range Event
The Range property alone is silent; the panel rejects the value but gives no feedback. To make the rejection visible, wire the I/O field's Events tab:
- Select the I/O field widget on the screen.
- Open Properties > Events.
- Locate the
"Value out of range"event. - Add a system function or script:
-
Status text: select the
"Set"action on a status text element. Text:"Entry outside [1..255]. Re-enter." -
Auto-revert: add a second system function
SetValue("RecipeNumber", 0)to clear the invalid entry. -
Logging: on Comfort Panels, call
TraceorLoggingto record the violation for audit.
-
Status text: select the
- Compile and download.
3.3 HMI Tag Configuration Table
| Property | Value | Effect |
|---|---|---|
| Data type | Int (-32768 to 32767) | 16-bit signed integer |
| Lower limit | 1 | Entries below 1 are rejected |
| Upper limit | 255 | Entries above 255 are rejected |
| Acquisition mode | Cyclic continuous | PLC receives value on every change |
| Acquisition cycle | 100 ms | Default; reduce for fast response |
| Byte order | Little-endian | Match S7-1200 native ordering |
For more details on tag configuration in WinCC (TIA Portal), consult the TIA Portal help under Configuring tags > Configuring HMI tags > Range, available through Siemens Industry Online Support.
4. PLC Lookup Logic (Layer 2)
Layer 2 runs in the S7-1200 CPU and decides whether the entered value is in the valid set. The implementation choice depends on the size of the valid set, the frequency of changes, and the maintenance workflow.
4.1 SCL CASE Statement (5-20 Discrete Values)
The SCL CASE statement compiles to a fast branch table in the S7-1200 firmware. It is the cleanest solution for sparse sets where most values are not valid. Example with eight valid recipe numbers:
// FB_RecipeCheck - validates recipe number against allowed set
FUNCTION_BLOCK "FB_RecipeCheck"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
i_Entered : Int; // Recipe number from HMI
END_VAR
VAR_OUTPUT
o_Valid : Bool; // TRUE if value is in valid set
o_Code : Int; // 0 = valid, 1 = invalid
END_VAR
BEGIN
o_Valid := FALSE;
o_Code := 0;
CASE i_Entered OF
10, 25, 40, 55, 78, 102, 150, 200:
o_Valid := TRUE;
o_Code := 0;
ELSE
o_Valid := FALSE;
o_Code := 1;
END_CASE;
END_FUNCTION_BLOCK
Call this FB once per scan in OB1 (or in a cyclic interrupt OB if you need deterministic timing). Wire the output o_Valid to a status indicator on the HMI screen. The SCL CASE statement is documented in the STEP 7 (TIA Portal) programming reference available through Siemens Industry Online Support.
4.2 Range Clusters Inside CASE
When several consecutive numbers are all valid (e.g., 69..85 all acceptable), use the range syntax inside the CASE label. This avoids spelling out 17 individual labels.
CASE i_Entered OF
40: o_Valid := TRUE;
55: o_Valid := TRUE;
69..85: o_Valid := TRUE; // 17 contiguous values
100, 200: o_Valid := TRUE;
1000..1100: o_Valid := TRUE; // 101 contiguous values
ELSE
o_Valid := FALSE;
END_CASE;
The 69..85 form expands at compile time but produces a tighter, more readable block. The S7-1200 firmware compiles a CASE statement with N labels into a balanced binary search internally, so adding range labels does not increase execution time linearly.
4.3 Ladder Network (Small Sets, No SCL)
If the project is restricted to pure ladder (FBD/LAD) - for example, in a vendor-locked legacy environment - build a comparator network. For n valid values, you need n EQ comparators and an n-input OR word. Example for three valid values (10, 55, 200):
// Network 1 - ladder form
LD i_Entered
EQ 10 // TRUE if i_Entered = 10
OR(
LD i_Entered
EQ 55
OR(
LD i_Entered
EQ 200
)
)
ST o_Valid
For sets larger than ~8 values the ladder becomes unmaintainable. Each branch adds 3-4 ladder elements and the visual tree grows fast. Switch to SCL as soon as the set exceeds 6-8 values.
4.4 Array Lookup with Linear Search (Up to 30 Values)
For maintainable, data-driven validation, store the valid set in a sorted ARRAY and walk it. This is the recommended pattern when the list can change between project revisions without recompiling the logic - the array is loaded from a recipe DB or operator-edited list.
// FB_LookupValidator - 30-value integer membership test
FUNCTION_BLOCK "FB_LookupValidator"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
i_Entered : Int;
END_VAR
VAR_OUTPUT
o_Valid : Bool;
o_Position : Int; // 0 if not found, else 1..30
END_VAR
VAR CONST
// Sorted ascending; required for binary search
c_ValidList : ARRAY[1..30] OF Int :=
(4, 12, 25, 40, 55, 69, 72, 85, 90, 100,
110, 125, 140, 150, 178, 200, 205, 220, 240, 250,
255, 260, 275, 290, 300, 310, 325, 340, 355, 360);
END_VAR
VAR
n : Int;
END_VAR
BEGIN
o_Valid := FALSE;
o_Position := 0;
// Linear search - O(n), fine for n <= 30 on S7-1200
FOR n := 1 TO 30 DO
IF i_Entered = c_ValidList[n] THEN
o_Valid := TRUE;
o_Position := n;
RETURN; // exit early on first hit
END_IF;
END_FOR;
END_FUNCTION_BLOCK
Worst-case scan: 30 comparisons. At a 10 ms OB1 cycle on an S7-1214C, this consumes under 50 microseconds. For 30 values the linear search is always fast enough; do not add complexity you do not need. The RETURN statement is supported in SCL FB bodies; see the SCL manual.
4.5 Binary Search (50-256 Values, Sorted Array)
If the valid set grows past 50 entries, switch to a binary search to keep the worst case under log2(n) + 1 comparisons. The array must be sorted ascending.
// Binary search over sorted ARRAY (ascending)
FUNCTION_BLOCK "FB_BinarySearch"
VAR_INPUT
i_Target : Int;
END_VAR
VAR_OUTPUT
o_Found : Bool;
END_OUTPUT
VAR CONST
c_ValidList : ARRAY[1..30] OF Int :=
(4, 12, 25, 40, 55, 69, 72, 85, 90, 100,
110, 125, 140, 150, 178, 200, 205, 220, 240, 250,
255, 260, 275, 290, 300, 310, 325, 340, 355, 360);
END_VAR
VAR
lo : Int := 1;
hi : Int := 30;
mid : Int;
END_VAR
BEGIN
o_Found := FALSE;
WHILE lo <= hi DO
mid := (lo + hi) / 2; // integer division
IF c_ValidList[mid] = i_Target THEN
o_Found := TRUE;
RETURN;
ELSIF i_Target < c_ValidList[mid] THEN
hi := mid - 1;
ELSE
lo := mid + 1;
END_IF;
END_WHILE;
END_FUNCTION_BLOCK
For 100 values: max 7 comparisons. For 256 values: max 8 comparisons. The S7-1200 executes each comparison in roughly 1 microsecond, so the block stays under 10 microseconds even in the worst case. The WHILE loop with mid-point division is documented in the STEP 7 SCL reference manual.
4.6 SCL PEEK and POKE for Legacy Data Blocks
If the project predates TIA Portal V14 and uses absolute DBs, you can use PEEK and POKE for indirect access. The performance penalty is roughly 30% over a typed ARRAY, so prefer typed arrays for new code. The PEEK syntax in SCL is PEEK(area := 16#84, byteOffset := n) for reading a byte from DB2 at offset n.
4.7 Pattern Selection Guide
| Valid set size | Recommended pattern | Worst-case comparisons | Readability |
|---|---|---|---|
| 1-5 | CASE labels or single EQ | 1-5 | Excellent |
| 6-20 | CASE labels with ranges | 1-5 (compiled) | Good |
| 20-30 | Linear search over ARRAY | 30 | Good |
| 50-256 | Binary search over sorted ARRAY | 8-9 | Moderate |
| 256+ | Hash table or external DB lookup | 1-3 | Complex |
5. Operator Feedback (Layer 3)
Validation without feedback is invisible. Use a status tag and HMI animations to make the result obvious to the operator.
5.1 Status Tag Codes
Add an HMI tag "RecipeStatus" of type Int. Update it from the PLC after each entry. The code table is the contract between the PLC and the HMI:
| Code | Meaning | Color | Action |
|---|---|---|---|
| 0 | Value accepted | Green | Continue to next step |
| 1 | Below lower limit | Yellow | Re-enter |
| 2 | Above upper limit | Yellow | Re-enter |
| 3 | Not in valid list | Red | Re-enter |
| 4 | No entry yet | Gray | Wait |
| 5 | System busy | Blue | Wait |
5.2 HMI Animation Setup
- Select the I/O field that holds the entry.
- Open Properties > Animations.
- Add an Appearance animation: if
RecipeStatus = 0then background =green, ifRecipeStatus = 3then background =red, elsedefault. - Add a Visibility animation on a status text element: visible when
RecipeStatus <> 0. - Set the status text content to use a text list with multi-language support.
- Compile and download.
5.3 Audible Feedback (Comfort Panels)
Comfort Panels support PlaySound as a system function. Wire it to the RecipeStatus change event so the operator hears a click on accept and a buzz on reject. This is highly recommended for noisy plant floors. Comfort Panels accept .wav files up to 16-bit, 44.1 kHz, mono. The system function is documented in the WinCC (TIA Portal) Comfort Panels manual.
5.4 Logging the Validation Result
For audit or recipe-history requirements, log each validation event. On Comfort Panels, configure a Logging tag with the following columns:
| Column | Type | Source |
|---|---|---|
| Timestamp | DateTime | System time, polling 1 s |
| Operator | WString | Current user name from "CurrentUser" tag |
| Entered | Int | RecipeNumber tag at the moment of validation |
| Status | Int | RecipeStatus tag |
Trigger the log entry on the rising edge of the validation-done flag. On Basic Panels, log to a CSV file on a USB stick; on Comfort Panels, use the built-in Logging database.
6. Numeric Pad Configuration Best Practices
| Setting | Recommendation | Reason |
|---|---|---|
| Data type | Match the PLC tag exactly (Int, DInt, Real) | Avoids truncation and sign errors |
| Hidden input | Enable for passwords, disable otherwise | Operators mistype when masked |
| Decimal places | 0 for integer recipes, otherwise fixed | Prevents 4.00000001 style entries |
| Clear on focus | Enable | New value replaces the old, not appends |
| OK button event | Trigger PLC validation | Rejects on dismiss, not on every keystroke |
| Cancel button event | Revert to previous value | Operator can back out without change |
| Spinner increment | 1 for integers, 0.1 for decimals | Matches natural data granularity |
| Spinner min/max | Same as tag range | Spinner respects limits but does not enforce |
| Character count | Match data type width (5 for Int, 10 for DInt) | Prevents truncation in the widget |
| Process value | Output as default value on screen open | Operator sees current state |
7. Cycle Time and Performance
Each SCL comparison takes approximately 1 microsecond on an S7-1214C. A 30-element linear search therefore adds under 50 microseconds to the OB1 cycle. For S7-1200 with default 10 ms cycle, the overhead is below 0.5% and well within the recommended headroom.
Do not call the validator inside a fast cyclic interrupt (e.g., OB35 at 1 ms) without checking the cycle time. For deterministic execution, place the call in OB1 and use a "validation done" tag to confirm execution before allowing another entry.
| OB | Cycle | Validator location | Notes |
|---|---|---|---|
| OB1 (main) | 10-150 ms | Yes | Default choice |
| OB30 | 5 ms | Yes | Faster, check OB1 cycle in diagnostic manual |
| OB35 | 1 ms | Caution | Cycle time overflow risk with > 30 entries |
| OB40 (hardware interrupt) | Event | No | Keep fast, defer validation |
For S7-1200 cycle-time monitoring, the S7-1200 Diagnostics Manual documents the standard methods: S7-1200 Diagnostics Manual (DAsl_0211_en.pdf). The manual also describes how to read the cycle time on the CPU display or via the Web server.
7.1 Watchdog Safety Margin
The S7-1200 watchdog trips at 150 ms by default. A 30-element linear search adds 50 microseconds; even a 100-element binary search adds 10 microseconds. Both are safe. If you later add a 1000-element validation (with an external database lookup), re-check the watchdog by writing the cycle time to a tag and alarming on overage. The standard approach is to add a hardware interrupt OB that monitors the cycle time and raises a non-fatal diagnostic if the cycle exceeds 80% of the watchdog limit.
8. Recipe Data Management
When the valid list is more than a handful of values, store it in a recipe DB so the application can change the list without recompiling the PLC. Recipe management on the HMI also lets the operator extend the list at runtime.
8.1 Recipe DB Structure
Create a global DB with an ARRAY of valid values plus a count field:
DATA_BLOCK "DB_ValidRecipes"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR
i_Count : Int; // Number of valid values
a_Values : ARRAY[1..100] OF Int; // Sorted ascending
b_SortError : Bool; // Set by OB100 sort check
END_VAR
BEGIN
i_Count := 30;
a_Values[1] := 4;
a_Values[2] := 12;
a_Values[3] := 25;
a_Values[4] := 40;
a_Values[5] := 55;
a_Values[6] := 69;
a_Values[7] := 72;
a_Values[8] := 85;
a_Values[9] := 90;
a_Values[10] := 100;
a_Values[11] := 110;
a_Values[12] := 125;
a_Values[13] := 140;
a_Values[14] := 150;
a_Values[15] := 178;
a_Values[16] := 200;
a_Values[17] := 205;
a_Values[18] := 220;
a_Values[19] := 240;
a_Values[20] := 250;
a_Values[21] := 255;
a_Values[22] := 260;
a_Values[23] := 275;
a_Values[24] := 290;
a_Values[25] := 300;
a_Values[26] := 310;
a_Values[27] := 325;
a_Values[28] := 340;
a_Values[29] := 355;
a_Values[30] := 360;
END_DATA_BLOCK
8.2 Loading Recipes from CSV
For recipes that change frequently, import them from a CSV file generated by the engineering team. TIA Portal's recipe import is documented in the WinCC (TIA Portal) manual.
- Generate a CSV file with one recipe value per row.
- In TIA Portal, open Recipes under the HMI station.
- Define a new recipe with one element of type
Int. - Import the CSV to populate the recipe entries.
- In runtime, the operator selects a recipe on the panel and the PLC reads the value via the recipe data record tags.
8.3 Sort Verification at Startup
Binary search requires a sorted array. Add a one-time check in OB100 (warm restart) that walks the array and flags any out-of-order pair. On error, set a status bit the HMI can display.
// OB100 - Startup sort verification
FOR n := 1 TO "DB_ValidRecipes".i_Count - 1 DO
IF "DB_ValidRecipes".a_Values[n] > "DB_ValidRecipes".a_Values[n+1] THEN
"DB_ValidRecipes".b_SortError := TRUE;
"RecipeStatus" := 6; // Code 6 = recipe data corrupt
"RecipeNumber" := 0;
RETURN;
END_IF;
END_FOR;
"DB_ValidRecipes".b_SortError := FALSE;
8.4 Multi-Language Text Lists
For multi-language deployments, define a text list in TIA Portal with entries for each status code. The HMI runtime resolves the text based on the operator's selected language.
| Status code | English | German | Spanish |
|---|---|---|---|
| 0 | Accepted | Akzeptiert | Aceptado |
| 1 | Below limit | Untergrenze | Por debajo del límite |
| 2 | Above limit | Obergrenze | Por encima del límite |
| 3 | Not in list | Nicht in Liste | No está en la lista |
| 4 | No entry | Keine Eingabe | Sin entrada |
| 5 | System busy | System belegt | Sistema ocupado |
Configure the text list under HMI > Text and graphics lists > Text lists in TIA Portal, then reference the list in the status text element's text property.
9. Verification and Commissioning
Before releasing the panel to production, run a structured verification. The test plan below covers static, boundary, mid-range, and negative cases.
-
Static test: With the PLC in STOP, force the input tag to each of the 30 valid values. Confirm
o_Valid= TRUE for each. -
Boundary test: Force the tag to
valid_list[1] - 1,valid_list[30] + 1, and32767. Confirm reject. -
Mid-range test: Force a value clearly between two valid entries (e.g.,
11if10and12are valid). Confirm reject. -
Negative test: Force
-1and0if the valid set starts at4. Confirm reject. - HMI test: On the panel, enter each of the 30 values through the numeric pad. Confirm color change and status text update.
- Reset test: Press Cancel on the HMI. Confirm the tag is not overwritten by the validator.
- Cycle test: Trigger OB1 cycle time display in TIA Portal online > diagnostics. Confirm no cycle time warning.
- Power-cycle test: Power down and up the panel. Confirm the tag retains its last valid value (or is initialized as expected).
- Concurrent operator test: Have two operators enter values on the same screen. Confirm no race condition corrupts the tag.
- Spam test: Tap the OK button rapidly. Confirm the validator runs once per edge, not 10 times per second.
- Language test: Switch the panel language to German, Spanish, and French. Confirm the status text list resolves correctly.
- Recipe load test: Modify the recipe DB on the HMI, save, and re-validate. Confirm the new set is enforced.
10. Troubleshooting Matrix
| Symptom | Likely cause | Action |
|---|---|---|
| o_Valid always FALSE | Array not initialized in VAR CONST | Check the SCL editor for red squiggles; recompile the DB |
| o_Valid TRUE for invalid value | Comparison type mismatch (Int vs DInt) | Confirm tag data type matches the ARRAY element type |
| Validator runs but HMI does not update | HMI tag is not refreshed | Check acquisition mode: "Cyclic continuous" or "On change" |
| Numeric pad accepts 3-digit max but value is 4 digits | Number of characters in I/O field limited | Increase character count to match data type range |
| Cycle time warning in diagnostics | Validator called from wrong OB | Move call to OB1; see Diagnostics Manual |
| Entered value on HMI differs from PLC tag | Endian mismatch on HMI tag | Confirm "Byte order" matches the connected PLC; default is little-endian |
| Range limit ignored on Comfort Panel | "Configuration of limits" disabled in Properties > Range | Enable and re-download project |
| Validator returns TRUE during first scan | o_Valid not initialized | Set initial value in the FB header; reload blocks |
| Numeric pad doesn't open | Operator authorization level too low | Check user administration in TIA Portal > Users & Roles |
| Value rejected with no status text | Status text element hidden by another layer | Check the Z-order in the screen layout |
| Multiple I/O fields show same value | All bound to the same tag | Verify tag connection in I/O field properties |
| Validator runs but tag does not update | Tag is read-only in HMI | Check tag's "Access protection" setting |
| Binary search returns wrong index | Array not sorted ascending | Run sort verification in OB100; fix the data |
| Recipe change has no effect on validation | PLC not re-reading the recipe tags | Confirm recipe data record tags are in the PLC's process image |
| Status text shows raw code (e.g., "Status: 3") | Text list not assigned to the field | Wire the text list in the I/O field's text property |
11. Frequently Asked Questions
Does the Siemens numeric pad have built-in list validation?
No. The numeric pad is a text entry widget that accepts any value within the data type range. The only built-in controls are lower and upper limits, configured on the HMI tag's Range property. List validation must be implemented in PLC code.
Which SCL construct is best for membership checks?
For sparse sets up to 20 values, use CASE. For dense or data-driven sets up to 30 values, use a sorted ARRAY with linear search. For 50+ values, switch to binary search on a sorted array to keep comparisons under log2(n).
Can this be implemented in pure ladder without SCL?
Yes, with one EQ comparator per valid value and a multi-input OR. Above 8 values the network becomes unmaintainable. SCL with CASE or an array lookup is preferred for any non-trivial set.
Where do I configure the HMI tag's upper and lower limits?
Project tree > HMI tags > select tag > Properties > Range. Tick "Lower limit" and "Upper limit", enter the values, then recompile and download the HMI project. The I/O field Events tab wires the out-of-range event to a status text or system function.
How much scan time does the validator add?
A 30-element linear FOR loop on an S7-1214C adds under 50 microseconds. Binary search on a 100-element array is under 10 microseconds. Both are negligible against the 10-150 ms OB1 cycle.