PiPLC Instruction Reference¶
Complete reference for all ladder logic instructions supported by PiPLC.
Overview¶
Instructions are the building blocks of ladder logic programs. They fall into two categories:
- Input instructions: Control rung power flow (contacts, comparisons)
- Output instructions: Execute when rung is TRUE (coils, timers, counters, math)
Memory Regions¶
| Region | Format | Description | Data Type |
|---|---|---|---|
| I: | I:W/B | Physical inputs | Bit |
| O: | O:W/B | Physical outputs | Bit |
| B: | B:W/B | Internal bits | Bit |
| N: | N:W | Integers | 32-bit signed |
| T: | T:W | Timers | TimerData structure |
| C: | C:W | Counters | CounterData structure |
Where W = word number, B = bit number (0-15).
Contact Instructions (Inputs)¶
XIC - Examine If Closed¶
Symbol: --[ ]--
Examines a bit address. Passes power when the bit is TRUE (1).
| Property | Value |
|---|---|
| Type | Input |
| Address | Bit (I:, O:, B:) |
| Rung Output | TRUE if bit = 1 |
Example:
XIO - Examine If Open¶
Symbol: --[/]--
Examines a bit address. Passes power when the bit is FALSE (0).
| Property | Value |
|---|---|
| Type | Input |
| Address | Bit (I:, O:, B:) |
| Rung Output | TRUE if bit = 0 |
Example:
[/I:0/1]---(O:0/0)
When I:0/1 is FALSE, output O:0/0 energizes.
Use for normally-closed contacts like stop buttons.
Coil Instructions (Outputs)¶
OTE - Output Energize¶
Symbol: ---( )---
Standard output coil. Follows rung power state.
| Property | Value |
|---|---|
| Type | Output |
| Address | Bit (I:, O:, B:) |
| Rung TRUE | Sets bit to 1 |
| Rung FALSE | Sets bit to 0 |
OTL - Output Latch¶
Symbol: ---(L)---
Latching output. Sets bit when rung is TRUE, retains state when FALSE.
| Property | Value |
|---|---|
| Type | Output |
| Address | Bit (I:, O:, B:) |
| Rung TRUE | Sets bit to 1 |
| Rung FALSE | No change (retains state) |
Use Case: Set a bit that stays on until explicitly cleared with OTU.
OTU - Output Unlatch¶
Symbol: ---(U)---
Unlatching output. Clears bit when rung is TRUE, retains state when FALSE.
| Property | Value |
|---|---|
| Type | Output |
| Address | Bit (I:, O:, B:) |
| Rung TRUE | Sets bit to 0 |
| Rung FALSE | No change (retains state) |
Use Case: Clear a latched bit.
Timer Instructions¶
Timers use the T: memory region and manage timing operations.
Timer Memory Structure¶
| Field | Description |
|---|---|
| PRE | Preset value (milliseconds) |
| ACC | Accumulated value (milliseconds) |
| EN | Enable bit (TRUE when rung is TRUE) |
| TT | Timer Timing (TRUE while timing) |
| DN | Done bit (TRUE when ACC >= PRE) |
TON - Timer On-Delay¶
Symbol: --[TON]--
Starts timing when rung becomes TRUE. Done when accumulated time reaches preset.
| Property | Value |
|---|---|
| Type | Output |
| Address | Timer (T:x) |
| Preset | Time in milliseconds |
Behavior: - Rung TRUE: EN=1, TT=1, ACC accumulates - ACC >= PRE: DN=1, TT=0 - Rung FALSE: Reset (EN=0, TT=0, DN=0, ACC=0)
Timing Diagram:
Rung: ____/‾‾‾‾‾‾‾‾‾‾‾‾‾‾\____
EN: ____/‾‾‾‾‾‾‾‾‾‾‾‾‾‾\____
TT: ____/‾‾‾‾‾‾‾‾\_______
DN: ___________/‾‾‾‾‾‾\____
|<-- PRE -->|
Example: Turn on a light 5 seconds after button press
TOF - Timer Off-Delay¶
Symbol: --[TOF]--
Output goes TRUE immediately when rung is TRUE. Times when rung goes FALSE.
| Property | Value |
|---|---|
| Type | Output |
| Address | Timer (T:x) |
| Preset | Time in milliseconds |
Behavior: - Rung TRUE: DN=1 immediately, EN=1 - Rung FALSE: TT=1, ACC accumulates - ACC >= PRE: DN=0, TT=0 - Rung TRUE while timing: Reset (ACC=0, TT=0)
Timing Diagram:
Rung: ____/‾‾‾‾\________________
EN: ____/‾‾‾‾\________________
TT: _________/‾‾‾‾‾‾‾‾\_______
DN: ____/‾‾‾‾‾‾‾‾‾‾‾‾‾\_______
|<-- PRE -->|
Example: Keep pump running 10 seconds after pressure switch opens
RTO - Retentive Timer On¶
Symbol: --[RTO]--
Like TON, but accumulated value is retained when rung goes FALSE.
| Property | Value |
|---|---|
| Type | Output |
| Address | Timer (T:x) |
| Preset | Time in milliseconds |
Behavior: - Rung TRUE: EN=1, TT=1, ACC accumulates - ACC >= PRE: DN=1, TT=0 - Rung FALSE: EN=0, TT=0 (ACC retained, DN retained) - Requires RES instruction to reset
Example: Track total run time across multiple cycles
Counter Instructions¶
Counters use the C: memory region and count events.
Counter Memory Structure¶
| Field | Description |
|---|---|
| PRE | Preset value (target count) |
| ACC | Accumulated value (current count) |
| DN | Done bit |
| OV | Overflow bit (CTU) |
| UN | Underflow bit (CTD) |
| CU | Count Up enable |
| CD | Count Down enable |
CTU - Count Up¶
Symbol: --[CTU]--
Increments count on each rising edge (FALSE→TRUE transition).
| Property | Value |
|---|---|
| Type | Output |
| Address | Counter (C:x) |
| Preset | Target count |
Behavior: - Rising edge: ACC = ACC + 1 - ACC >= PRE: DN = 1 - Continues counting past PRE - Overflow: OV = 1 (wraps from MAX to MIN) - Requires RES to reset
Example: Count 10 parts then signal batch complete
[I:0/0]--[CTU C:0 PRE:10] ; Part sensor
[C:0/DN]---(O:0/0) ; Batch complete light
[I:0/1]--[RES C:0] ; Reset button
CTD - Count Down¶
Symbol: --[CTD]--
Decrements count on each rising edge.
| Property | Value |
|---|---|
| Type | Output |
| Address | Counter (C:x) |
| Preset | Initial count |
Behavior: - Rising edge: ACC = ACC - 1 - ACC <= 0: DN = 1 - Continues counting below 0 - Underflow: UN = 1 (wraps from MIN to MAX) - Requires RES to reset
RES - Reset¶
Symbol: --[RES]--
Resets timer or counter to initial state.
| Property | Value |
|---|---|
| Type | Output |
| Address | Timer (T:x) or Counter (C:x) |
Effect on Timer: - ACC = 0 - EN = 0, TT = 0, DN = 0
Effect on Counter: - ACC = 0 - DN = 0, OV = 0, UN = 0
Math Instructions¶
Math instructions perform arithmetic operations on integer values. They execute only when rung power is TRUE.
Common Properties¶
| Property | Value |
|---|---|
| Type | Output |
| Source Address | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, C:x.ACC/PRE, or constant |
| Destination Address | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, or C:x.ACC/PRE |
Overflow Handling¶
- Results exceeding 32-bit range saturate to INT32_MIN or INT32_MAX
- Division by zero leaves destination unchanged
ADD - Add¶
Formula: Dest = SourceA + SourceB
SUB - Subtract¶
Formula: Dest = SourceA - SourceB
MUL - Multiply¶
Formula: Dest = SourceA × SourceB
DIV - Divide¶
Formula: Dest = SourceA ÷ SourceB (integer division)
MOD - Modulo¶
Formula: Dest = SourceA % SourceB
NEG - Negate (Unary)¶
Formula: Dest = -Source
ABS - Absolute Value (Unary)¶
Formula: Dest = |Source|
SCL - Scale¶
Formula: Dest = (Source - InMin) × (OutMax - OutMin) ÷ (InMax - InMin) + OutMin
Scales a value from one range to another. Useful for analog I/O scaling.
| Parameter | Description |
|---|---|
| Source | Input value address |
| Dest | Output value address |
| InMin | Input range minimum |
| InMax | Input range maximum |
| OutMin | Output range minimum |
| OutMax | Output range maximum |
Example: Scale 0-4095 ADC reading to 0-100%
Data Transfer Instructions¶
MOV - Move¶
Formula: Dest = Source
Copies a 32-bit integer value from source to destination. Executes only when rung power is TRUE.
| Property | Value |
|---|---|
| Type | Output |
| Source | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, C:x.ACC/PRE, or constant |
| Destination | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, or C:x.ACC/PRE |
Example: Copy a sensor reading to a working register
Comparison Instructions¶
Comparison instructions control rung power based on comparing two values. They act as INPUT elements.
Common Properties¶
| Property | Value |
|---|---|
| Type | Input |
| Source Address | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, C:x.ACC/PRE, or constant |
| Rung Output | TRUE if comparison is true |
EQU - Equal¶
Condition: SourceA == SourceB
NEQ - Not Equal¶
Condition: SourceA != SourceB
LES - Less Than¶
Condition: SourceA < SourceB
LEQ - Less Than or Equal¶
Condition: SourceA <= SourceB
GRT - Greater Than¶
Condition: SourceA > SourceB
GEQ - Greater Than or Equal¶
Condition: SourceA >= SourceB
Bitwise Instructions¶
Bitwise instructions perform logical operations on integer values bit-by-bit. They execute only when rung power is TRUE.
Common Properties¶
| Property | Value |
|---|---|
| Type | Output |
| Source Address | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, C:x.ACC/PRE, or constant |
| Destination Address | N:x, I:x, O:x, B:x (word), T:x.ACC/PRE, or C:x.ACC/PRE |
BAND - Bitwise AND¶
Formula: Dest = SourceA & SourceB
[condition]--[BAND N:0 N:1 N:2]
Result: N:2 = N:0 & N:1
Each bit is 1 only if both source bits are 1.
BOR - Bitwise OR¶
Formula: Dest = SourceA | SourceB
BXOR - Bitwise XOR¶
Formula: Dest = SourceA ^ SourceB
BNOT - Bitwise NOT (Unary)¶
Formula: Dest = ~Source
N2B - Integer to Bit (Unary)¶
Formula: Dest = (1 << Source) if Source is 0..31, else Dest = 0
[condition]--[N2B N:0 N:1]
Result: N:1 = (1 << N:0) when N:0 is between 0 and 31.
If N:0 < 0 or N:0 > 31, N:1 = 0 (out of range).
If N:0 = 0, N:1 = 1 (bit 0 on).
If N:0 = 1, N:1 = 2 (bit 1 on).
If N:0 = 5, N:1 = 32 (bit 5 on).
BSL - Bit Shift Left¶
Formula: Dest = (A << B) | IN, OV = MSB of A before shift
Operands: - Source A: value to shift (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE, or constant) - Source B: number of positions (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE, or constant) - Destination: result (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE) - Control: B:x word — bit 0 = IN (input entry bit), bit 1 = OV (overflow/shifted-out MSB)
[condition]--[BSL A:N:0 B:N:1 D:N:2 C:B:3]
Result: N:2 = (N:0 << N:1) | B:3/0
B:3/1 = MSB of N:0 before shift
If N:1 < 0 or N:1 > 31: N:2 = 0, B:3/1 = 0
The IN bit (B:x/0) is shifted into bit 0 of the result. Set it with OTE B:3/0. The OV bit (B:x/1) captures the most significant bit of A before the shift. Read it with XIC B:3/1.
BSR - Bit Shift Right¶
Formula: Dest = ((unsigned)A >> B) | (IN << 31), OV = LSB of A before shift
Operands: - Source A: value to shift (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE, or constant) - Source B: number of positions (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE, or constant) - Destination: result (N:, I:, O:, B: word, T:x.ACC/PRE, C:x.ACC/PRE) - Control: B:x word — bit 0 = IN (input entry bit), bit 1 = OV (overflow/shifted-out LSB)
[condition]--[BSR A:N:0 B:N:1 D:N:2 C:B:3]
Result: N:2 = ((unsigned)N:0 >> N:1) | (B:3/0 << 31)
B:3/1 = LSB of N:0 before shift
If N:1 < 0 or N:1 > 31: N:2 = 0, B:3/1 = 0
The IN bit (B:x/0) is shifted into bit 31 of the result. Set it with OTE B:3/0. The OV bit (B:x/1) captures the least significant bit of A before the shift. Read it with XIC B:3/1.
Scheduling Instructions¶
Scheduling instructions are INPUT elements that trigger based on date, time, or periodic intervals. They do not use PLC memory addresses — they compare against the system clock.
SCHD - Scheduled Input¶
Symbol: --[SCHD]--
Triggers TRUE for exactly one scan when the system date/time matches the configured target. Uses minute precision (seconds are ignored).
| Property | Value |
|---|---|
| Type | Input |
| Address | None (uses system clock) |
| Parameter | Target date/time (minute precision) |
| Rung Output | TRUE for one scan when date/time matches |
Behavior: - Compares QDateTime::currentDateTime() with configured target (both truncated to minutes) - Returns TRUE only on the first scan where they match (one-shot) - Returns FALSE on all subsequent scans, even if still within the matching minute
Example: Turn on an alarm at a specific date/time
Use Cases: Daily/weekly scheduled tasks, maintenance reminders, timed event triggers.
WSCH - Weekly Scheduled Input¶
Symbol: --[WSCH]--
Triggers TRUE for exactly one scan when the current day-of-week and time match the configuration. Supports selecting multiple days.
| Property | Value |
|---|---|
| Type | Input |
| Address | None (uses system clock) |
| Parameters | Enabled days bitmask (Sun–Sat), scheduled time |
| Rung Output | TRUE for one scan when day and time match |
Day Bitmask:
| Bit | Day |
|---|---|
| 0 | Sunday |
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Saturday |
Behavior: - Checks if the current day of week has its bit set in the enabled days mask - Compares current time (minute precision) with scheduled time - Returns TRUE only on the first scan where both match (one-shot) - Returns FALSE on all subsequent scans
Example: Activate a pump every Monday, Wednesday, and Friday at 6:00 PM
Use Cases: Weekly maintenance schedules, recurring tasks, weekend/weekday operations.
Date Comparison Instructions¶
Date comparison instructions are INPUT elements that compare the system's current date (QDate::currentDate()) against a user-configured target date. They use date-only comparison (time is ignored).
Unlike SCHD, WSCH, and INTERVAL (which are one-shot), date comparisons evaluate continuously — they pass power on every scan where the condition is true.
Common Properties¶
| Property | Value |
|---|---|
| Type | Input |
| Address | None (uses system clock) |
| Parameter | Target date |
| Rung Output | TRUE on every scan where comparison holds |
DATE< - Date Less Than¶
Condition: Current date < Target date
DATE<= - Date Less Than or Equal¶
Condition: Current date <= Target date
DATE= - Date Equal¶
Condition: Current date == Target date
DATE>= - Date Greater Than or Equal¶
Condition: Current date >= Target date
DATE> - Date Greater Than¶
Condition: Current date > Target date
Use Cases: Seasonal operations, license/warranty expiration checks, scheduled maintenance windows.
Interval Instruction¶
INTERVAL - Timed Interval¶
Symbol: --[INTERVAL]--
Triggers TRUE for exactly one scan at periodic intervals specified in days, hours, and minutes. Uses the V: (Interval) memory region for persistent state that survives PLC restarts.
| Property | Value |
|---|---|
| Type | Input |
| Address | V:x (Interval memory region) |
| Parameters | Days (0–365), Hours (0–23), Minutes (0–59) |
| Rung Output | TRUE for one scan when interval elapses |
Interval Memory Structure (V:):
| Field | Description |
|---|---|
| days | Days component of the configured interval |
| hours | Hours component of the configured interval |
| minutes | Minutes component of the configured interval |
| startTimeMs | Unix timestamp (ms) when interval started counting |
| lastTriggerMs | Unix timestamp (ms) of last trigger (0 = never triggered) |
| triggered | One-shot flag (TRUE for one scan) |
Behavior: - On first scan: initializes the start time reference and returns FALSE - Calculates elapsed time since last trigger (or start time if never triggered) - When elapsed time >= configured interval: triggers TRUE for one scan, records trigger time - Resets one-shot flag on the next scan
Example: Log data every 15 minutes
Example: Run a maintenance check every 2 days
Use Cases: Log rotation, backup schedules, periodic sampling, maintenance reminders.
Quick Reference Table¶
Input Instructions¶
| Instruction | Description | Passes Power When |
|---|---|---|
| XIC | Examine If Closed | Bit = 1 |
| XIO | Examine If Open | Bit = 0 |
| EQU | Equal | A == B |
| NEQ | Not Equal | A != B |
| LES | Less Than | A < B |
| LEQ | Less Than or Equal | A <= B |
| GRT | Greater Than | A > B |
| GEQ | Greater Than or Equal | A >= B |
| SCHD | Scheduled Input | Date/time matches target (one-shot) |
| WSCH | Weekly Scheduled Input | Day and time match (one-shot) |
| DATE< | Date Less Than | Current date < target |
| DATE<= | Date Less Than or Equal | Current date <= target |
| DATE= | Date Equal | Current date == target |
| DATE>= | Date Greater Than or Equal | Current date >= target |
| DATE> | Date Greater Than | Current date > target |
| INTERVAL | Timed Interval | Interval elapsed (one-shot) |
Output Instructions¶
| Instruction | Description | Action When TRUE |
|---|---|---|
| OTE | Output Energize | Set bit, clear when FALSE |
| OTL | Output Latch | Set bit, retain when FALSE |
| OTU | Output Unlatch | Clear bit, retain when FALSE |
| TON | Timer On-Delay | Accumulate time |
| TOF | Timer Off-Delay | DN immediate, time on FALSE |
| RTO | Retentive Timer | Accumulate, retain on FALSE |
| CTU | Count Up | Increment on edge |
| CTD | Count Down | Decrement on edge |
| RES | Reset | Clear timer/counter |
| ADD | Add | Dest = A + B |
| SUB | Subtract | Dest = A - B |
| MUL | Multiply | Dest = A × B |
| DIV | Divide | Dest = A ÷ B |
| MOD | Modulo | Dest = A % B |
| NEG | Negate | Dest = -A |
| ABS | Absolute | Dest = |
| SCL | Scale | Linear interpolation |
| MOV | Move | Dest = Source |
| BAND | Bitwise AND | Dest = A & B |
| BOR | Bitwise OR | Dest = A |
| BXOR | Bitwise XOR | Dest = A ^ B |
| BNOT | Bitwise NOT | Dest = ~A |
| N2B | Integer to Bit | Dest = (1 << A) |
| BSL | Bit Shift Left | Dest = (A << B) | IN |
| BSR | Bit Shift Right | Dest = (A >> B) | (IN << 31) |
See Also¶
- DECORATORS.md - Contact decorators for timing and edge detection
- Schema Documentation - XML file format reference
- Examples - Sample ladder programs