CTU — Counter-Up
Pin layout
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | CU | BOOL | Count Up — increment CV on each rising edge |
| Input | R | BOOL | Reset — when TRUE, CV is forced to 0 |
| Input | PV | INT | Preset Value — Q fires when CV >= PV |
| Output | Q | BOOL | TRUE when CV >= PV |
| Output | CV | INT | Current Value — the running count |
Syntax
VAR
ctrPulse : CTU;
END_VAR
ctrPulse(CU := xPulse,
R := xReset,
PV := 10);
IF ctrPulse.Q THEN ... END_IF;
iCurrent := ctrPulse.CV;
Semantics
Per Annex F.6.1, evaluated on each call:
- If
R = TRUE:CV := 0. (Reset has priority.) - Else if
CUrose fromFALSEtoTRUEsince the last call:CV := CV + 1(saturates at INT max). Q := (CV >= PV).
CU triggers on the rising edge. A CU that stays
continuously TRUE produces exactly one increment (on the
first call after the rise). To count cyclic events you need a
real edge — either from hardware (button presses) or from an
R_TRIG / TON-feedback pattern in software.
IEC reference
IEC 61131-3 third edition (2013), Annex F.6.1.
matiec conformance
Implemented per the standard. The “CU stays TRUE → no
increments” semantic is per-spec, not a bug — but it’s a
common LLM trap (see llm_signals).