Learn PLCs free
Programming Examples13 min read2,424 words

PLC Counter Programming: CTU, CTD, and CTUD with Examples

PLC counter programming explained — count-up (CTU), count-down (CTD), and up/down (CTUD) counters, accumulator and preset, reset logic, and ladder examples.

PPI
PLC Programming IO Editorial Team
Sourced guidance with documented review and correction standards

PLC counter programming is one of the first skills every automation technician must master. Counters track how many times an event has occurred — a part passes a sensor, a robot completes a cycle, a valve opens — and they trigger actions once that count reaches a target value. Without counters, building a batch process, a parts-per-box packer, or a production shift report in ladder logic would require clunky workarounds.

This tutorial covers the three standard counter types (CTU, CTD, CTUD), explains each parameter in plain language, and walks through real ladder examples for Allen-Bradley and IEC 61131-3/Siemens platforms. By the end you will be able to wire up a count-up counter for a conveyor line, add a reset rung, cascade counters for large totals, and know exactly when to use a counter versus a timer.

What Is a Counter in a PLC?

A PLC counter is a software instruction that increments or decrements an integer value each time its count input transitions from false to true (a rising edge). The counter stores that running total in an accumulator register (CV — current value). When the accumulator reaches the preset value (PV), the counter sets a status bit that your program can use to trigger the next step.

Counters are event-driven, not time-driven. Every count event is a discrete signal transition — a proximity sensor pulsing as a bottle passes, a push-button press, or the rising edge of another rung's coil. If you need to react to elapsed time rather than discrete events, reach for a timer instead (see Counters vs Timers below).

Counters are defined in IEC 61131-3, the international standard that governs PLC programming languages. Every conforming platform — Allen-Bradley, Siemens, Schneider, Beckhoff, CODESYS — implements at minimum CTU and CTD. The naming and tag structure differ slightly by vendor, but the logic is identical.

PLC Counter Types CTU CTD CTUD comparison — count up, count down, up/down Side-by-side comparison of the three PLC counter types: CTU increments toward preset, CTD decrements toward zero, CTUD does both with QU and QD outputs. CTU — Count Up Accumulates toward PV ACC = 16 / PV = 25 CU input (rising edge) ACC increments +1 Done bit (DN/Q) Sets when ACC ≥ PV Reset (RES/R) Clears ACC to 0 CTD — Count Down Decrements toward zero ACC = 6 / PV = 25 CD input (rising edge) ACC decrements −1 Done bit (DN/QD) Sets when ACC ≤ 0 Load (LD) Reloads ACC from PV CTUD — Up/Down Both CU and CD inputs ACC = 12 / PV = 25 CU → increment CD → decrement QU — done up bit Sets when ACC ≥ PV QD — done down bit Sets when ACC ≤ 0 R=reset LD=reload
PLC counter types compared: CTU counts up to a preset, CTD counts down from a preset, CTUD does both with dual status bits.

The Three Counter Types

CTU — Count-Up Counter

CTU increments the accumulator by 1 on every rising edge of the CU (count-up) input. When the accumulator equals or exceeds the preset, the done bit (Q or DN) energises and stays energised until a reset clears the accumulator.

Use CTU whenever you are counting events toward a target: parts produced, cycles completed, or items queued.

CTD — Count-Down Counter

CTD decrements the accumulator by 1 on every rising edge of the CD (count-down) input. The done bit energises when the accumulator reaches zero (or falls to or below zero depending on platform). A load (LD) input loads the preset value into the accumulator so you always start from the correct batch size.

Use CTD when you are issuing a fixed quantity and need to know when stock is exhausted: dispensing tablets into a bottle, metering pellets into a bag, or managing a kanban bin level.

CTUD — Up/Down Counter

CTUD combines both functions in a single instruction. It has separate CU and CD inputs, a single accumulator, and two status bits: QU (done-up, ACC >= PV) and QD (done-down, ACC <= 0). A single R (reset) input clears the accumulator; an LD input reloads it from PV.

Use CTUD when the same physical quantity can increase or decrease: tracking how many parts are currently inside a machine enclosure (parts enter via one sensor, exit via another), or monitoring how many AGVs are docked versus in service.


Counter Parameters: PV, CV, and the Done Bit

Every counter instruction — regardless of vendor — exposes three core parameters and at least one status bit.

Preset Value (PV) The target count. When the accumulator reaches this value the done bit activates. PV is typically a 16-bit signed integer on older Allen-Bradley platforms (range −32,768 to +32,767) and a 32-bit integer on modern platforms and IEC controllers. Set PV to match your batch size or the cycle count you want to detect.

Accumulator / Current Value (CV or ACC) The running total maintained by the counter. Your program can read CV at any time — useful for displaying production counts on an HMI or for triggering an intermediate alarm before the final count. You can also write to CV in special cases (pre-loading a partial count after a line restart), though this should be done carefully with a one-shot to avoid unintended counts. See our guide on one-shot instructions for the right technique.

Done Bit (DN / Q / QU) The Boolean output that energises when ACC >= PV (CTU/CTUD) or ACC <= 0 (CTD/CTUD QD). Use this bit as the enabling condition for the next process step. On Allen-Bradley, the done bit is addressed as C5:0/DN. On IEC platforms the output is a BOOL variable you name yourself.

Overflow / Underflow Allen-Bradley RSLogix 500 sets a separate overflow (OV) or underflow (UN) bit if the accumulator exceeds the 16-bit integer limit. IEC platforms typically saturate at the integer boundary. Always size PV within the safe range for your platform.


How a CTU Works: Part Counting on a Conveyor

The most common counter application is counting parts on a conveyor belt using a photoelectric sensor. Here is how to build it in ladder logic.

Scenario: A proximity sensor (I:0/0) pulses each time a part passes. After 25 parts, energise a signal light (O:0/0) to alert the operator that a full box is ready.

Allen-Bradley (RSLogix 500) Ladder

| Rung 0 — Count each part                                          |
|                                                                    |
|  I:0/0          C5:0                                              |
|  ---[Prox]-----|CTU  |                                            |
|                |Count Up                                          |
|                |Counter  C5:0                                     |
|                |Preset   25                                        |
|                |Accum    0  |---                                   |

| Rung 1 — Light on when box is full                                |
|                                                                    |
|  C5:0/DN                   O:0/0                                  |
|  ---[ DN ]----------------(  )---                                 |

| Rung 2 — Operator resets after removing full box                  |
|                                                                    |
|  I:0/2          C5:0                                              |
|  ---[Reset PB]--|RES |---                                         |

How it executes:

  1. Each time the proximity sensor (I:0/0) transitions false→true, the CTU instruction fires and increments C5:0.ACC by 1.
  2. When C5:0.ACC reaches 25, C5:0/DN turns on, energising the signal light on Rung 1.
  3. The operator removes the box and presses the reset pushbutton (I:0/2). The RES instruction clears C5:0.ACC to 0 and de-energises the done bit. The cycle restarts.

Important detail: CTU latches. Once DN is set it stays set even if new parts keep arriving (the accumulator keeps incrementing past 25 in most platforms). The done bit will not de-energise until you reset the counter. If you need to stop the line the moment the count reaches 25, use the DN bit to disable the conveyor output directly.

CTU count-up counter conveyor part-counting sequence — accumulator reaching preset Horizontal flow showing how a CTU counter accumulates from zero to the preset value as parts pass a proximity sensor, then sets the done bit to trigger a downstream action. PROXIMITY SENSOR Part passes beam → 0→1 rising edge CTU COUNTER ACC increments ACC 13/PV 20 Preset = 25 DN = 0 (not yet) C5:0.ACC / CV ACC=PV DN sets DN BIT ON Signal light energised C5:0/DN = 1 RES fires RESET (RES) Operator presses reset pushbutton ACC cleared to 0 DN bit cleared Cycle restarts ① Detect ② Count ③ Trigger ④ Reset
CTU counter part-counting cycle: sensor rising edge increments the accumulator; when ACC reaches PV the done bit energises the signal; reset clears ACC and restarts.

IEC 61131-3 / CODESYS / Siemens (TIA Portal) Function Block

On Siemens S7 with TIA Portal you use the IEC-standard CTU function block (available from the IEC_Counter library, or as SFB0 in S7-300/400 classic):

// Variable declarations
myCounter : CTU;
partSensor : BOOL;   (* I0.0 *)
resetPB    : BOOL;   (* I0.2 *)
boxFull    : BOOL;   (* Q0.0 *)

// Call in OB1 network
myCounter(
    CU := partSensor,
    R  := resetPB,
    PV := 25,
    Q  => boxFull,
    CV => currentCount
);

The IEC CTU block is a function block with a persistent instance (myCounter). The R input replaces the separate RES rung — when resetPB is TRUE the accumulator clears immediately within the same scan. Q maps directly to boxFull; CV gives you the live count for HMI display.

Allen-Bradley vs Siemens naming at a glance:

Parameter AB RSLogix 500 AB Studio 5000 Siemens / IEC
Count input EN (rung condition) CU CU
Preset PV (Preset) PRE PV
Accumulator ACC ACC CV
Done bit C5:x/DN .DN Q (or QU)
Reset RES instruction .RES input R input

In Studio 5000 (ControlLogix/CompactLogix), counters are tag-based. You declare a tag of type COUNTER and access its members as MyCounter.ACC, MyCounter.PRE, MyCounter.DN.


Reset Logic (RES)

The reset instruction is not optional — every counter rung needs a defined reset condition. Without one, your counter will reach its preset and stay latched until a power cycle clears memory (and on retentive counters, not even then).

Three common reset strategies:

1. Manual operator reset — a pushbutton or HMI command, as shown in the conveyor example above. Best for batch operations where a human confirms the batch is complete.

2. Automatic reset on done bit — use the DN bit itself (with a one-shot, so you only reset for one scan) to clear the counter and restart the cycle immediately. This creates a repeating counter that auto-reloads.

| Rung 2 — Auto-reset when done (one-shot prevents re-triggering)  |
|                                                                    |
|  C5:0/DN        ONS           C5:0                               |
|  ---[ DN ]---[One-Shot]-------|RES |---                          |

3. Reset at machine start — use the first scan bit (S:1/15 in RSLogix 500, or a startup routine in Studio 5000) to clear all counters at program initialisation. This guarantees counters begin at zero after a controller restart rather than resuming stale values.


High-Speed Counters

Standard software counters rely on the PLC scan cycle. If events arrive faster than the scan rate — typically faster than 1,000 pulses per second — the PLC will miss transitions and under-count.

For high-frequency signals (encoder feedback, flow meter pulses, high-speed proximity sensors) you need a high-speed counter (HSC) module or the built-in HSC function available on many compact PLCs. High-speed counters use hardware interrupt logic that counts in the background, independent of the scan cycle, and can handle rates from 10 kHz up to several MHz.

Configuration is vendor-specific: Allen-Bradley MicroLogix 1100 has built-in HSC inputs addressed via HSC; ControlLogix uses a dedicated 1756-HSC module. Siemens S7-1200/1500 supports high-speed counting via technology objects (TO_CountingFast). For most batch-counting and cycle-counting applications on a standard conveyor (< 100 parts/min), a standard software counter is entirely sufficient. Reserve HSC hardware for encoder-based positioning or high-speed flow measurement, and consider pairing it with analog input scaling when converting raw counts to engineering units.


Counters vs Timers

A common source of confusion for new PLC programmers is knowing when to reach for a counter versus a timer.

Counter (CTU/CTD/CTUD) Timer (TON/TOF/RTO)
Driven by Discrete event transitions (rising edges) Elapsed time (milliseconds/seconds)
Accumulates Integer event count Time duration
Done when ACC reaches PV (a count) ACC reaches PV (a time)
Typical use Parts counted, cycles completed Delay before action, timed output pulse
Reset RES instruction / R input De-energise input (TON/TOF) or RES (RTO)

A practical rule: if the question is "how many times did this happen?" use a counter. If the question is "how long has this been happening?" use a timer. Many real applications use both together — for example, a timer generates a regular pulse (one shot per second) that a counter accumulates into minutes of runtime, which is a simple alternative to a retentive timer for maintenance tracking. See PLC programming examples for more combined timer/counter patterns.

PLC counter vs timer comparison — event-driven counting versus time-elapsed accumulation Side-by-side comparison of CTU counter and TON timer showing that counters accumulate discrete event transitions while timers accumulate elapsed milliseconds. CTU COUNTER "How many times did this happen?" input ACC +1 each edge +1 +1 +1 +1 Driven by: discrete event transitions TON TIMER "How long has this been active?" input ACC ms DN Driven by: elapsed milliseconds
Counter vs timer: a CTU steps its accumulator once per rising-edge event; a TON ramps its accumulator continuously while enabled. Use counters for "how many," timers for "how long."

Counter Examples

Example 1: Batch Count — 12 Parts Per Box

Scenario: A packaging line places 12 bottles per cardboard box. A photoelectric sensor on the chute (I:1/3) pulses once per bottle. At 12 bottles, a diverter gate (O:1/4) actuates to push the full box onto the exit conveyor. An automatic sensor (I:1/5) detects the empty box arriving to reset the counter.

| Rung 0 — Count bottles                                            |
|                                                                    |
|  I:1/3          C5:1                                              |
|  ---[PE Sensor]-|CTU  |                                           |
|                 |Count Up                                          |
|                 |Counter  C5:1                                     |
|                 |Preset   12                                        |
|                 |Accum    0  |---                                   |

| Rung 1 — Actuate diverter when full box detected                  |
|                                                                    |
|  C5:1/DN                   O:1/4                                  |
|  ---[ DN ]----------------(  )---                                 |

| Rung 2 — Reset when empty box arrives at station                  |
|                                                                    |
|  I:1/5          C5:1                                              |
|  ---[Empty Box]-|RES |---                                         |

Notice that the diverter stays energised as long as DN is set, which gives the full box time to clear before the next empty arrives. Tune your conveyor spacing so the empty box sensor fires reliably after the full box has moved clear.

Cascaded PLC counters units and thousands for high-volume shift production tracking Two CTU counters in cascade: C5:2 counts individual parts to 1000, then its done bit increments C5:3 the thousands counter, enabling shift totals beyond a single 16-bit integer range. PART SENSOR I:0/0 rising edge C5:2 — UNITS Preset = 1000 ACC = 718 DN fires at 1000 ↓ ONS → RES self ACC resets to 0 DN ONS C5:3 — THOUSANDS Preset = 999 ACC = 3 +1 per 1000 parts ACC.3 × 1000 = 3,000 this shift SHIFT TOTAL 3,718 parts (C5:3×1000) + C5:2.ACC Cascaded Counter Architecture — High-Volume Shift Tracking
Cascaded CTU counters for shift production tracking: C5:2 counts individual parts to 1,000, then triggers C5:3 (thousands counter). Total = (C5:3.ACC × 1000) + C5:2.ACC.

Example 2: Shift Production Tracker (Cascaded Counters)

Scenario: Track total parts produced during an 8-hour shift. A single 16-bit counter maxes out at 32,767 — more than enough for most lines — but as an exercise in cascaded counters, here is how you track into the thousands using two counters:

| Rung 0 — Units counter (0 to 999)                                |
|                                                                    |
|  I:0/0          C5:2                                              |
|  ---[Part Sen]--|CTU  |                                           |
|                 |Preset   1000                                     |
|                 |Accum    0   |---                                  |

| Rung 1 — When units reach 1000, increment thousands counter       |
|  and reset units counter                                           |
|                                                                    |
|  C5:2/DN        ONS           C5:3                               |
|  ---[ DN ]---[One-Shot]-------|CTU  |                             |
|                               |Preset   999                        |
|                               |Accum    0   |---                   |

|  C5:2/DN        ONS           C5:2                               |
|  ---[ DN ]---[One-Shot]-------|RES |---                           |

| Rung 2 — Shift total = (C5:3.ACC * 1000) + C5:2.ACC             |
|           — compute in a MOV/ADD rung or on HMI                   |

C5:2 counts individual parts; when it reaches 1,000 it increments C5:3 (the thousands counter) and resets itself. Total production = (C5:3.ACC × 1000) + C5:2.ACC. Reset both counters at shift start using your initialisation routine.

For a simpler alternative on modern PLCs with 32-bit integer counters (Studio 5000, Siemens S7-1200, CODESYS), just use a single CTU with PV set to a high value or use an integer accumulator tag directly — no cascading needed.


Frequently Asked Questions

What is a counter in a PLC?

A PLC counter is a software instruction that tracks discrete event transitions. Each time its count input goes from false to true (a rising edge), the counter increments or decrements an integer accumulator. When the accumulator reaches the preset value, a status bit energises and your program can trigger the next step — stopping a conveyor, closing a valve, or alarming an operator. Counters are event-driven; they count how many times something happened, not how long it took.

What is the difference between CTU and CTD?

CTU (count-up) starts its accumulator at 0 and increments toward a preset value; the done bit activates when accumulator >= preset. CTD (count-down) starts its accumulator at the preset value and decrements toward 0; the done bit activates when accumulator <= 0. CTU is ideal for counting items toward a target (bottles into a box). CTD is ideal for issuing a fixed quantity and detecting when it is exhausted (tablets dispensed from a hopper). CTUD combines both in one instruction with separate CU and CD inputs.

How do you reset a PLC counter?

On Allen-Bradley RSLogix 500 and RSLogix 5, a separate RES (reset) instruction placed on its own rung resets the target counter's accumulator to 0 and clears the done bit. The RES rung energises for one scan whenever its input condition is true. On Allen-Bradley Studio 5000 (ControlLogix), write 0 to the .ACC member or use a conditional move. On IEC 61131-3 platforms (Siemens TIA Portal, CODESYS, Beckhoff TwinCAT), the counter function block has a built-in R (reset) Boolean input — when R is TRUE the accumulator clears within that scan. Always ensure the reset condition fires for exactly one scan when using auto-reset; use a one-shot instruction to prevent the counter from clearing every scan as long as the reset condition is held.

What is the difference between a counter and a timer?

Both counters and timers maintain an accumulator that counts toward a preset, but what they count is different. A timer accumulates time (milliseconds or seconds) — it answers "how long has this been true?" A counter accumulates events (rising edge transitions) — it answers "how many times has this happened?" Use a timer for delays, durations, and timed outputs. Use a counter for parts totals, cycle counts, and batch quantities. In ladder logic they look similar — both have an EN/CU input, a preset, an accumulator, and a done bit — but their physical meaning and reset behavior differ. For a deeper look at both instruction types together, see the ladder logic tutorial.


Next Steps

You now have everything you need to implement CTU, CTD, and CTUD counters in a real PLC program:

  • Use CTU to count parts, cycles, or events toward a target
  • Use CTD to issue a fixed quantity and detect exhaustion
  • Use CTUD when the same value must count both up and down
  • Always pair counters with a defined reset strategy (manual, auto one-shot, or initialisation routine)
  • Switch to high-speed counter hardware for signals faster than ~500 Hz
  • Combine counters with timers for runtime tracking and timed batch cycles

For more hands-on practice, the PLC programming examples guide includes additional counter-based applications alongside motor control, sequencer, and safety interlock patterns. If you are new to ladder logic itself, start with the ladder logic tutorial and the PLC programming languages overview before building counter rungs.

#plccounter#CTU#CTD#CTUD#ladderlogic#counterprogramming
Share this article:

Related Articles