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 theJMPcondition.
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;
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:
- Pre-load the index and limit tags before the loop body.
- Place an
LBLinstruction as the first instruction of the loop body. - Execute the body rungs.
- Increment the index (ADD 1).
- Compare the index to the limit with
GRTorGEQ; if the index has not reached the limit,JMPback to theLBL.
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.
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
JMPloops, 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
GSVon theTASKobject to read theLastScanTimeattribute and trend it; alarm if it exceeds 70 % of the watchdog.
Verification and Commissioning
-
Static check: In the ST routine, right-click and select Verify Routine. The compiler reports unmatched
END_FOR,END_WHILE, andEND_REPEATstatements, plus any undeclared tags referenced inside the loop body. -
Cross-reference: confirm that the
i_Indextag is not written from any other routine; concurrent writes will corrupt the loop. Use Find > Cross Reference on the tag name. - 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.
-
Boundary test: run with
i_Limit = 0,i_Limit = 1, andi_Limit = 100000. The loop must terminate cleanly in all three cases without leaving theCT_Loop.ACC in a non-zero state. -
Watch the trend: add a trend on
i_Indexand run for >2× the expected loop duration. Confirm the tag returns to 0 (or to the final accumulator) and theb_Donebit asserts. -
Edge cases: force
i_Limit = 0while the loop is running; the routine must not execute the body and must still setb_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.