Skip to content

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:

    [I:0/0]---(O:0/0)

When I:0/0 is TRUE, output O:0/0 energizes.


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

    [I:0/0]--[TON T:0 PRE:5000]

    [T:0/DN]---(O:0/0)


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

    [I:0/0]--[TOF T:0 PRE:10000]

    [T:0/DN]---(O:0/0)


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

    [I:0/0]--[RTO T:0 PRE:3600000]   ; 1 hour total

    [I:0/1]--[RES T:0]               ; Reset button


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

    [condition]--[ADD N:0 N:1 N:2]

Result: N:2 = N:0 + N:1

SUB - Subtract

Formula: Dest = SourceA - SourceB

    [condition]--[SUB N:0 N:1 N:2]

Result: N:2 = N:0 - N:1

MUL - Multiply

Formula: Dest = SourceA × SourceB

    [condition]--[MUL N:0 N:1 N:2]

Result: N:2 = N:0 × N:1

DIV - Divide

Formula: Dest = SourceA ÷ SourceB (integer division)

    [condition]--[DIV N:0 N:1 N:2]

Result: N:2 = N:0 ÷ N:1 (truncated)
Division by zero: Dest unchanged

MOD - Modulo

Formula: Dest = SourceA % SourceB

    [condition]--[MOD N:0 N:1 N:2]

Result: N:2 = N:0 % N:1 (remainder)
Division by zero: Dest unchanged

NEG - Negate (Unary)

Formula: Dest = -Source

    [condition]--[NEG N:0 N:1]

Result: N:1 = -N:0

ABS - Absolute Value (Unary)

Formula: Dest = |Source|

    [condition]--[ABS N:0 N:1]

Result: N:1 = |N:0|

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%

    [condition]--[SCL N:0 N:1 InMin:0 InMax:4095 OutMin:0 OutMax: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
    [condition]--[MOV N:0 N:1]

Result: N:1 = N:0

Example: Copy a sensor reading to a working register

    [I:0/0]--[MOV N:5 N:10]

When I:0/0 is TRUE, copy value of N:5 into N:10.


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

    [EQU N:0 N:1]---(O:0/0)

Output energizes when N:0 equals N:1.

NEQ - Not Equal

Condition: SourceA != SourceB

    [NEQ N:0 N:1]---(O:0/0)

Output energizes when N:0 does not equal N:1.

LES - Less Than

Condition: SourceA < SourceB

    [LES N:0 N:1]---(O:0/0)

Output energizes when N:0 is less than N:1.

LEQ - Less Than or Equal

Condition: SourceA <= SourceB

    [LEQ N:0 N:1]---(O:0/0)

Output energizes when N:0 is less than or equal to N:1.

GRT - Greater Than

Condition: SourceA > SourceB

    [GRT N:0 N:1]---(O:0/0)

Output energizes when N:0 is greater than N:1.

GEQ - Greater Than or Equal

Condition: SourceA >= SourceB

    [GEQ N:0 N:1]---(O:0/0)

Output energizes when N:0 is greater than or equal to N:1.

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

    [condition]--[BOR N:0 N:1 N:2]

Result: N:2 = N:0 | N:1
Each bit is 1 if either source bit is 1.

BXOR - Bitwise XOR

Formula: Dest = SourceA ^ SourceB

    [condition]--[BXOR N:0 N:1 N:2]

Result: N:2 = N:0 ^ N:1
Each bit is 1 if source bits are different.

BNOT - Bitwise NOT (Unary)

Formula: Dest = ~Source

    [condition]--[BNOT N:0 N:1]

Result: N:1 = ~N:0
Each bit is inverted (one's complement).

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

    [SCHD 2025-06-15T08:00]---(O:0/0)

Output energizes for one scan at 8:00 AM on June 15, 2025.

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

    [WSCH Mon,Wed,Fri 18:00]---(O:0/0)

Output energizes for one scan at 6:00 PM on Mon/Wed/Fri.

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< 2025-12-31]---(O:0/0)

Output energizes when today is before December 31, 2025.

DATE<= - Date Less Than or Equal

Condition: Current date <= Target date

    [DATE<= 2025-12-31]---(O:0/0)

Output energizes when today is on or before December 31, 2025.

DATE= - Date Equal

Condition: Current date == Target date

    [DATE= 2025-12-25]---(O:0/0)

Output energizes only on December 25, 2025.

DATE>= - Date Greater Than or Equal

Condition: Current date >= Target date

    [DATE>= 2025-01-01]---(O:0/0)

Output energizes from January 1, 2025 onward.

DATE> - Date Greater Than

Condition: Current date > Target date

    [DATE> 2025-06-30]---(O:0/0)

Output energizes after June 30, 2025.

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

    [INTERVAL V:0 0d 0h 15m]---(O:0/0)

Output energizes for one scan every 15 minutes.

Example: Run a maintenance check every 2 days

    [INTERVAL V:1 2d 0h 0m]---(O:0/1)

Output energizes for one scan every 48 hours.

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