Implementing For/While Loops in RSLogix 5000 Ladder Logic

Mark Townsend10 min read
Allen-BradleyHMI ProgrammingTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Implementing For/While Loops in RSLogix 5000 Ladder Logic

RSLogix 5000 (now part of Studio 5000 Logix Designer) does not expose FOR or WHILE instructions as native ladder rungs. The IEC 61131-3 grammar is still available — it just lives behind the Structured Text (ST) routine type. When the application demands that loops stay inside the ladder editor, you implement the same iteration semantics with CTU counters, indexed comparisons, or a JMP/LBL pair. This reference covers all four paths, the watchdog constraints that govern them, and the verification steps that prove the loop terminates correctly.

Loop Constructs and the IEC 61131-3 Model

The IEC 61131-3 third edition (2013) standardises three iteration statements for textual languages:

  • FOR ... DO ... END_FOR — bounded iteration over a counter.
  • WHILE ... DO ... END_WHILE — pre-tested conditional iteration.
  • REPEAT ... UNTIL ... END_REPEAT — post-tested conditional iteration.

These statements were designed for ST, not for graphical ladder. The Logix Designer environment honours the standard by allowing them only inside RoutineType := StructuredText routines. Ladder routines cycle continuously through the scan, so a "loop" in ladder is really a single scan that decides whether to execute a body of rungs — the iteration counter is held in a tag, and the body re-runs on subsequent scans until the terminating condition is met.

Vendor contrast: some platforms (for example the AutomationDirect Do-more series) implement WHILE as a native ladder instruction that wraps a block of rungs. Logix Designer routes the same construct through ST; pick the platform whose editor matches the team's skill set.

Why Ladder Logic Has No Native FOR/WHILE

Ladder is a scan-cyclic language. A program is solved top-to-bottom once per task scan, and the scan time is bounded by a watchdog. A blocking FOR with an unbounded bound would consume the entire watchdog, fault the controller, and trip a major fault (Type 1, Code 71 — Watchdog Timeout on a 1756/1769 processor). To keep scans deterministic, ladder exposes only:

  • JMP / LBL — forward and backward jumps that must be within the same routine.
  • CTU, CTD, RES — counters that store iteration state across scans.
  • GRT, GEQ, LES, LEQ, EQU, NEQ — compare instructions that drive the JMP condition.

The combination of these primitives gives the same iteration behaviour as ST loops, distributed across multiple scans.

Prerequisites

  • Studio 5000 Logix Designer version 21 or later (ST has been present since RSLogix 5000 v11, but v21+ matches current support and downloads the latest 1756-RM006 revision). Earlier RSLogix 5000 v15-v20 also support ST with the same syntax.
  • A ControlLogix (1756), CompactLogix (5069 or 5380), or SoftLogix processor with a routine type of Structured Text available in the routine creation dialog.
  • Knowledge of the controller's watchdog time (Controller Properties → Major Faults → Watchdog = 500 ms default on a 1756-L8x; the typical System Overhead Time Slice is 20 % of the watchdog, leaving ~400 ms of user time).
  • The Logix5000 Controllers Structured Text Programming Manual (publication 1756-RM006) for syntax reference — Appendix B is the canonical ST grammar that the Logix Designer compiler enforces.

Method 1 — Structured Text (FOR, WHILE, REPEAT UNTIL)

Create a new routine of type Structured Text and call it from ladder with a JSR instruction. The three loop forms are:

FOR ... DO ... END_FOR

FOR count := initial_value TO final_value [BY increment] DO
    <statement>;
    IF bool_expression THEN
        EXIT;
    END_IF;
END_FOR;

Example: sum the integers 1 to 100 and write the result to a tag.

iSum := 0;
FOR i := 1 TO 100 BY 1 DO
    iSum := iSum + i;
END_FOR;
nResult := iSum;

WHILE ... DO ... END_WHILE

WHILE bool_expression1 DO
    <statement>;
    IF bool_expression2 THEN
        EXIT;
    END_IF;
END_WHILE;

Example: drain a FIFO until empty or a maximum-iteration watchdog trips.

iCount := 0;
WHILE (FIFO.EMPTY = 0) AND (iCount < 10000) DO
    FIFO.Remove(bData);
    iCount := iCount + 1;
END_WHILE;

REPEAT ... UNTIL ... END_REPEAT

REPEAT
    <statement>;
    IF bool_expression2 THEN
        EXIT;
    END_IF;
UNTIL bool_expression1
END_REPEAT;
Constraint: The Logix Designer compiler enforces an iteration-count cap of 10,000 iterations per FOR/WHILE/REPEAT call. Exceed it and the routine faults with structured-text execution error Type 4 / Code 20. If your loop must do more, break the body into multiple ST routine calls from ladder, or move the iteration into a periodic task that spreads work across scans.

Method 2 — Counter-Based Ladder Equivalent of a FOR Loop

This is the ladder-native approach that maps directly onto a C-style for(i=0; i<N; i++). The body executes on the scan that increments the counter from N-1 to N, and is suppressed on every other scan.

Tags

Tag Type Scope Use
i_Index DINT Controller Loop counter, 0 to N-1
i_Limit DINT Controller Number of iterations (N)
b_Run BOOL Controller One-shot start request
b_Done BOOL Controller Loop complete
CT_Loop COUNTER Controller Counter instance

Rung 1 — Start / Reset

[XIC b_Run] [XIO CT_Loop.DN] ---(RES CT_Loop)
[CTU CT_Loop,Preset i_Limit,Accum 0]

Rung 2 — Body execution (runs while !DN)

[XIO CT_Loop.DN] ---[body rungs]---

Rung 3 — Done flag

[XIC CT_Loop.DN] ---(OTE b_Done)---

To advance the counter by 1 per scan, the CTU must be enabled every scan until DN is true. A common pattern is to enable the CTU rung with the b_Run bit latched by the DN bit, and unlatch the run bit on DN to freeze the loop.

Method 3 — JMP/LBL Loop with Index Comparison

This is the classic RSLogix 5 / RSLogix 500 technique that works in any ladder-only project. The structure is:

  1. Pre-load the index and limit tags before the loop body.
  2. Place an LBL instruction as the first instruction of the loop body.
  3. Execute the body rungs.
  4. Increment the index (ADD 1).
  5. Compare the index to the limit with GRT or GEQ; if the index has not reached the limit, JMP back to the LBL.

Example: scan an array of 50 DINTs and write the maximum to nMaxVal

(* Rung 1 — initialise *)
[XIC b_Run] [XIO b_Busy] ---(MOV 0 nMaxVal)
                          ---(MOV 0 i_Index)
                          ---(OTL b_Busy)
                          ---(OTU b_Run)

(* Rung 2 — label / start of body *)
LBL: [LBL Label01]

(* Rung 3 — body: compare array[i] with running max *)
[XIO b_Done] [GRT array[i_Index] nMaxVal] ---(MOV array[i_Index] nMaxVal)

(* Rung 4 — increment + test *)
[ADD i_Index 1 i_Index]
[GRT i_Index 49] ---(JMP Label01)
[OTU b_Busy] [OTE b_Done]

Critical rule: the JMP instruction in ladder skips the remainder of the routine if the rung is true — it does not loop unconditionally. The compare-and-jump pair is what drives the iteration. If the compare condition is wrong, the loop exits on the first scan instead of iterating.

Scan-time impact: the body executes exactly once per scan because the JMP jumps over the increment-and-test on the final scan only. A 50-element scan completes in 50 scans plus the initialise scan. If your application needs the result within one watchdog period, use ST instead.

Method 4 — State Machine in a Periodic Task

For long iteration counts (>1,000) or loops that must cooperate with I/O, split the work across a periodic task scheduled at 10–50 ms. The task body is a CASE statement on an i_State tag:

CASE i_State OF
0:  (* init *)        i_Index := 0; i_State := 10;
10: (* body *)        DoWork(i_Index); i_Index := i_Index + 1;
    IF i_Index >= i_Limit THEN i_State := 20; END_IF;
20: (* done *)        b_Done := 1; i_State := 0;
END_CASE;

This pattern keeps the per-task scan well under the watchdog and gives the rest of the controller time to handle I/O updates between iterations. Schedule the periodic task under Controller Properties → Task Properties → Period, with priority 5 (lower than the continuous task).

Watchdog Timer Management

The Controller Properties dialog exposes a Watchdog value (default 500 ms for ControlLogix 1756-L8x, 100 ms for some CompactLogix 5380 models). The actual available user time is Watchdog − System Overhead Time Slice, where the slice is set in the Advanced tab (default 20 % of the watchdog, 100 ms). If a single scan exceeds this, the processor logs a major fault:

Major Fault Code Meaning Likely Cause
Type 1, Code 71 Watchdog timeout — user task scan exceeded limit Blocking FOR/WHILE with large N
Type 4, Code 20 ST routine iteration limit exceeded FOR/WHILE/REPEAT ran >10,000 iterations
Type 4, Code 21 ST execution stack overflow Deeply nested FOR/WHILE

Mitigations:

  • Add an explicit iteration counter to the ST loop condition: WHILE (FIFO.EMPTY = 0) AND (i_Iter < 10000) DO.
  • For ladder JMP loops, confirm in the routine properties that the estimated scan time is <80 % of the watchdog.
  • Set the controller's System Overhead Time Slice to a value that lets housekeeping run between iterations (10–20 % is typical for loop-heavy code).
  • Use GSV on the TASK object to read the LastScanTime attribute and trend it; alarm if it exceeds 70 % of the watchdog.

Verification and Commissioning

  1. Static check: In the ST routine, right-click and select Verify Routine. The compiler reports unmatched END_FOR, END_WHILE, and END_REPEAT statements, plus any undeclared tags referenced inside the loop body.
  2. Cross-reference: confirm that the i_Index tag is not written from any other routine; concurrent writes will corrupt the loop. Use Find > Cross Reference on the tag name.
  3. Watchdog stress test: in Controller Properties → Major Faults, temporarily set the watchdog to 100 ms and run the loop. If it faults with Type 1/Code 71, refactor to a periodic task.
  4. Boundary test: run with i_Limit = 0, i_Limit = 1, and i_Limit = 100000. The loop must terminate cleanly in all three cases without leaving the CT_Loop.ACC in a non-zero state.
  5. Watch the trend: add a trend on i_Index and run for >2× the expected loop duration. Confirm the tag returns to 0 (or to the final accumulator) and the b_Done bit asserts.
  6. Edge cases: force i_Limit = 0 while the loop is running; the routine must not execute the body and must still set b_Done. For ST WHILE loops, verify the body never executes when the condition is false on entry.

Method Comparison Matrix

Method Editor Iterations per scan Watchdog risk Best for
ST FOR/WHILE Structured Text Up to 10,000 per call Medium Array scans, math, string ops
ST REPEAT Structured Text Up to 10,000 per call Medium Body must run at least once
Counter + DN Ladder 1 Low Long iterations cooperating with I/O
JMP / LBL Ladder 1 Low Legacy ladder-only projects, RSLogix 500 migration
Periodic task state machine ST or ladder 1 per task period Very low Loops that must coexist with high-speed I/O

Does RSLogix 5000 / Studio 5000 support FOR and WHILE loops in ladder?

No. The ladder editor exposes only JMP/LBL, counters, and compares. FOR, WHILE, and REPEAT UNTIL are available only inside a Structured Text routine. The reference grammar is in the Logix5000 Controllers Structured Text Programming Manual (publication 1756-RM006), Appendix B.

What is the maximum iteration count for an ST FOR loop?

The Logix Designer compiler limits a single FOR/WHILE/REPEAT call to 10,000 iterations. Exceeding it raises a major fault (Type 4, Code 20). Break large iterations into multiple JSR calls or move the work to a periodic task.

How do I stop a FOR loop early in RSLogix 5000 ST?

Use the EXIT statement inside an IF...THEN construct, for example: IF bAbort THEN EXIT; END_IF;. EXIT is the only supported way to break out of an ST loop in Logix Designer; a GOTO or BREAK does not exist in this dialect.

What fault code indicates a watchdog timeout from a runaway ladder loop?

A blocking loop that exceeds the configured Watchdog value (default 500 ms) produces a major fault Type 1, Code 71 on a 1756 controller. To recover, increase the watchdog, lower the iteration count per scan, or move the work to a periodic task with a 10–50 ms period.

Can I call an ST routine that contains a FOR loop from ladder?

Yes. Add a JSR instruction that names the ST routine. Each JSR call advances the loop by up to 10,000 iterations before returning control to the calling ladder routine. To run more iterations, chain multiple JSR calls in sequence or schedule the ST routine in a periodic task.

Back to blog