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 0O:1/3— Output word 1, bit 3B: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 0N: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 valueT:0.ACC— Timer 0 accumulated valueT:0.DN— Timer 0 done bitT:0.TT— Timer 0 timer timing bitT: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 valueC:0.ACC— Counter 0 accumulated valueC:0.DN— Counter 0 done bitC:0.OV— Counter 0 overflow bitC:0.UN— Counter 0 underflow bitC:0.CU— Counter 0 count up enableC: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¶
- Instruction Reference — How instructions interact with memory
- Architecture Overview — System architecture
- Protocol Specification — Binary memory snapshot format