Skip to content

PiPLC Memory Regions

PiPLC uses word-based (32-bit) memory organized into seven regions, matching traditional PLC conventions.

Region Summary

Region Address Format Data Type Size Description
Input I:word/bit BOOL 8 words × 32 bits Physical inputs
Output O:word/bit BOOL 8 words × 32 bits Physical outputs
Internal B:word/bit BOOL 64 words × 32 bits Internal relays
Integer N:word INT32 256 words Integer storage
Timer T:word TimerData 64 timers Timer accumulators and status
Counter C:word CounterData 64 counters Counter accumulators and status
Interval V:word IntervalData Dynamic Interval timer persistent state

Address Formats

Bit Addresses (I:, O:, B:)

Format: REGION:word/bit

  • I:0/0 — Input word 0, bit 0
  • O:1/3 — Output word 1, bit 3
  • B:5/15 — Internal bit word 5, bit 15

Word and bit numbers are zero-indexed. Bit range is 0–31.

Integer Addresses (N:)

Format: N:word

  • N:0 — Integer word 0
  • N:255 — Integer word 255

Values are 32-bit signed integers (range: −2,147,483,648 to 2,147,483,647).

Timer Addresses (T:)

Format: T:word or T:word.subelement

  • T:0 — Timer 0 (full structure)
  • T:0.PRE — Timer 0 preset value
  • T:0.ACC — Timer 0 accumulated value
  • T:0.DN — Timer 0 done bit
  • T:0.TT — Timer 0 timer timing bit
  • T:0.EN — Timer 0 enable bit

Counter Addresses (C:)

Format: C:word or C:word.subelement

  • C:0 — Counter 0 (full structure)
  • C:0.PRE — Counter 0 preset value
  • C:0.ACC — Counter 0 accumulated value
  • C:0.DN — Counter 0 done bit
  • C:0.OV — Counter 0 overflow bit
  • C:0.UN — Counter 0 underflow bit
  • C:0.CU — Counter 0 count up enable
  • C:0.CD — Counter 0 count down enable

Interval Addresses (V:)

Format: V:word

  • V:0 — Interval 0 (full structure)
  • V:1 — Interval 1

Used exclusively by the INTERVAL instruction for persistent timing state. The size is dynamic — slots are allocated as needed by the program.

Timer Data Structure

Each timer occupies one slot in the T: region and tracks the following fields:

Field Type Description
PRE int16 Preset value (milliseconds)
ACC int16 Accumulated value (milliseconds)
EN bit Enable — TRUE when rung is TRUE
TT bit Timer Timing — TRUE while accumulating
DN bit Done — TRUE when ACC >= PRE

Counter Data Structure

Each counter occupies one slot in the C: region:

Field Type Description
PRE int16 Preset value (target count)
ACC int16 Accumulated value (current count)
DN bit Done — TRUE when ACC >= PRE (CTU) or ACC <= 0 (CTD)
OV bit Overflow — CTU wrapped from MAX to MIN
UN bit Underflow — CTD wrapped from MIN to MAX
CU bit Count Up enable
CD bit Count Down enable

Interval Data Structure

Each interval occupies one slot in the V: region and tracks persistent timing state:

Field Type Description
days int32 Days component of configured interval
hours int32 Hours component of configured interval
minutes int32 Minutes component of configured interval
startTimeMs int64 Unix timestamp (ms) when interval started counting
lastTriggerMs int64 Unix timestamp (ms) of last trigger (0 = never)
triggered bit One-shot flag — TRUE for one scan when interval elapses

Memory Access in Ladder Logic

  • Input instructions (XIC, XIO) read from any bit region (I:, O:, B:)
  • Output instructions (OTE, OTL, OTU) write to any bit region (I:, O:, B:)
  • Timer instructions (TON, TOF, RTO) use the T: region
  • Counter instructions (CTU, CTD) use the C: region
  • Math/Compare instructions use the N: region
  • RES instruction resets T: or C: addresses
  • Interval instruction (INTERVAL) uses the V: region
  • Scheduling instructions (SCHD, WSCH) and date comparisons (DATE<, DATE<=, DATE=, DATE>=, DATE>) use the system clock, not PLC memory

Bit Forcing

Any bit address (I:, O:, B:) can be forced to a specific value for debugging. Forced bits override the normal scan cycle value. A force bitmap tracks which addresses are currently forced. Forces can be set/cleared via the simulation panel or the WebSocket protocol.

Implementation

Memory is managed by the MemoryManager class (src/runtime/MemoryManager.h), which provides thread-safe access via QReadWriteLock. The scan cycle acquires a write lock; memory reads from UI or snapshot generation acquire read locks.

See Also