CTU — Counter-Up

Pin layout

DirectionNameTypeDescription
InputCUBOOLCount Up — increment CV on each rising edge
InputRBOOLReset — when TRUE, CV is forced to 0
InputPVINTPreset Value — Q fires when CV >= PV
OutputQBOOLTRUE when CV >= PV
OutputCVINTCurrent 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 CU rose from FALSE to TRUE since 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).