Intermediate
PLC String Handling in Structured Text: Parsing, Formatting & Communication
Learn to manipulate strings in Structured Text — from basic concatenation to barcode parsing, HMI message formatting, and serial protocol handling.
Why String Handling Matters in PLCs
Modern PLCs do far more than control motors and valves. They parse barcode data, format HMI display messages, communicate with serial devices, build log entries, and exchange data with MES/SCADA systems. All of this requires robust string handling.
String Basics in Structured Text
VAR
// Fixed-length strings
ProductName : STRING[40] := 'Widget-A';
Message : STRING[80] := '';
// String length
NameLen : INT;
END_VARNameLen := LEN(ProductName); // Returns 8
IEC 61131-3 String Functions
| Function | Description | Example |
|---|---|---|
| LEN(s) | Length of string | LEN('Hello') → 5 |
| LEFT(s, n) | First n characters | LEFT('Hello', 3) → 'Hel' |
| RIGHT(s, n) | Last n characters | RIGHT('Hello', 3) → 'llo' |
| MID(s, n, p) | n chars from position p | MID('Hello', 2, 3) → 'll' |
| CONCAT(s1, s2) | Join two strings | CONCAT('Hi', ' World') → 'Hi World' |
| FIND(s1, s2) | Find s2 in s1 (0=not found) | FIND('Hello', 'llo') → 3 |
| INSERT(s1, s2, p) | Insert s2 into s1 at p | INSERT('Helo', 'l', 3) → 'Hello' |
| DELETE(s, n, p) | Delete n chars from p | DELETE('Hello', 2, 2) → 'Hlo' |
| REPLACE(s1, s2, n, p) | Replace n chars at p with s2 | REPLACE('Hello', 'a', 1, 5) → 'Hella' |
Building HMI Display Messages
PROGRAM HMIMessages
VAR
Temperature : REAL := 72.5;
BatchCount : INT := 1547;
MachineName : STRING[20] := 'Press-01';
StatusLine : STRING[80] := '';
TempStr : STRING[10];
CountStr : STRING[10];
END_VAR// Convert numbers to strings
TempStr := REAL_TO_STRING(Temperature);
CountStr := INT_TO_STRING(BatchCount);
// Build display message
StatusLine := CONCAT(MachineName, ' | Temp: ');
StatusLine := CONCAT(StatusLine, TempStr);
StatusLine := CONCAT(StatusLine, '°C | Count: ');
StatusLine := CONCAT(StatusLine, CountStr);
// Result: "Press-01 | Temp: 72.5°C | Count: 1547"
Parsing Barcode Data
Barcodes often encode multiple fields separated by delimiters:
PROGRAM BarcodeParser
VAR
RawBarcode : STRING[80] := 'PN:12345;LOT:A2024-001;QTY:50;EXP:2026-12';
PartNumber : STRING[20] := '';
LotCode : STRING[20] := '';
Quantity : INT := 0;
ExpiryDate : STRING[20] := '';
SearchPos : INT;
FieldStart : INT;
FieldEnd : INT;
TempStr : STRING[80];
QtyStr : STRING[10];
END_VAR// Extract Part Number (after "PN:")
SearchPos := FIND(RawBarcode, 'PN:');
IF SearchPos > 0 THEN
TempStr := MID(RawBarcode, 80, SearchPos + 3);
FieldEnd := FIND(TempStr, ';');
IF FieldEnd > 0 THEN
PartNumber := LEFT(TempStr, FieldEnd - 1);
END_IF;
END_IF;
// Extract Lot Code (after "LOT:")
SearchPos := FIND(RawBarcode, 'LOT:');
IF SearchPos > 0 THEN
TempStr := MID(RawBarcode, 80, SearchPos + 4);
FieldEnd := FIND(TempStr, ';');
IF FieldEnd > 0 THEN
LotCode := LEFT(TempStr, FieldEnd - 1);
END_IF;
END_IF;
// Extract Quantity (after "QTY:")
SearchPos := FIND(RawBarcode, 'QTY:');
IF SearchPos > 0 THEN
TempStr := MID(RawBarcode, 80, SearchPos + 4);
FieldEnd := FIND(TempStr, ';');
IF FieldEnd > 0 THEN
QtyStr := LEFT(TempStr, FieldEnd - 1);
ELSE
QtyStr := TempStr;
END_IF;
Quantity := STRING_TO_INT(QtyStr);
END_IF;
Serial Protocol Message Building
Many industrial devices use ASCII-based serial protocols:
PROGRAM SerialProtocol
VAR
DeviceAddr : INT := 1;
Command : STRING[10] := 'RD';
Register : INT := 4000;
TxMessage : STRING[80] := '';
Checksum : INT := 0;
i : INT;
CharCode : INT;
AddrStr : STRING[5];
RegStr : STRING[10];
END_VAR// Build message: STX + Address + Command + Register + ETX + Checksum
AddrStr := INT_TO_STRING(DeviceAddr);
RegStr := INT_TO_STRING(Register);
TxMessage := '$02'; // STX character
TxMessage := CONCAT(TxMessage, AddrStr);
TxMessage := CONCAT(TxMessage, Command);
TxMessage := CONCAT(TxMessage, RegStr);
TxMessage := CONCAT(TxMessage, '$03'); // ETX character
// Calculate simple checksum (XOR of all bytes)
Checksum := 0;
FOR i := 1 TO LEN(TxMessage) DO
// XOR each character's ASCII value
Checksum := Checksum XOR ORD(MID(TxMessage, 1, i));
END_FOR;
TxMessage := CONCAT(TxMessage, INT_TO_STRING(Checksum));
CSV Log Entry Builder
PROGRAM CSVLogger
VAR
Timestamp : STRING[20] := '2026-03-04 14:30:00';
EventCode : INT := 101;
EventDesc : STRING[40] := 'Batch Complete';
Value1 : REAL := 98.7;
Value2 : REAL := 45.2;
CSVLine : STRING[200] := '';
END_VAR// Build CSV: Timestamp,Code,Description,Value1,Value2
CSVLine := Timestamp;
CSVLine := CONCAT(CSVLine, ',');
CSVLine := CONCAT(CSVLine, INT_TO_STRING(EventCode));
CSVLine := CONCAT(CSVLine, ',');
CSVLine := CONCAT(CSVLine, EventDesc);
CSVLine := CONCAT(CSVLine, ',');
CSVLine := CONCAT(CSVLine, REAL_TO_STRING(Value1));
CSVLine := CONCAT(CSVLine, ',');
CSVLine := CONCAT(CSVLine, REAL_TO_STRING(Value2));
// Result: "2026-03-04 14:30:00,101,Batch Complete,98.7,45.2"
String Comparison and Validation
PROGRAM InputValidation
VAR
UserInput : STRING[40] := '';
IsValid : BOOL := FALSE;
ErrorMsg : STRING[80] := '';
InputLen : INT;
END_VARInputLen := LEN(UserInput);
// Check minimum length
IF InputLen < 3 THEN
IsValid := FALSE;
ErrorMsg := 'Input too short (min 3 characters)';
// Check for forbidden characters
ELSIF FIND(UserInput, ';') > 0 OR FIND(UserInput, '$27') > 0 THEN
IsValid := FALSE;
ErrorMsg := 'Invalid characters detected';
// Check prefix
ELSIF LEFT(UserInput, 2) <> 'PN' THEN
IsValid := FALSE;
ErrorMsg := 'Must start with PN prefix';
ELSE
IsValid := TRUE;
ErrorMsg := '';
END_IF;
Best Practices for PLC String Handling
STRING[80] not just STRING to control memory usageLEN(s) > 0 before processingPractice string parsing in our online ST editor and explore the barcode parsing lesson for a real-world walkthrough.