📋 Scenario
You've been handed this code by a contractor who has left the project. The conveyor runs fine for 3-4 cycles, then freezes — motor stays on, indexing timer never resets. There are 2 bugs. Find both.
🐛 Click the line(s) containing the bug(s). Multiple bugs may exist.
1
(* Conveyor index sequence *)
2
CASE state OF
3
4
0: (* IDLE *)
5
IF cycle_start THEN
6
state := 1;
7
END_IF;
8
9
1: (* WAIT FOR PART *)
10
IF Part_Sensor OR timeout_flag THEN
11
state := 2;
12
END_IF;
13
timeout_timer(IN := TRUE, PT := T#5s);
14
timeout_flag := timeout_timer.Q;
15
16
2: (* RUN CONVEYOR *)
17
Motor_FWD := TRUE;
18
index_timer(IN := Motor_FWD, PT := T#2s);
19
IF index_timer.Q THEN
20
Motor_FWD := FALSE;
21
state := 3;
22
END_IF;
23
24
3: (* CONFIRM POSITION *)
25
IF Pos_Sensor AND NOT fault OR e_stop THEN
26
state := 0;
27
END_IF;
28
29
END_CASE;
✓ Solution & Explanation
Root cause:
two_bugs
Steps
- Bug 1 — Line 17: index_timer(IN := Motor_FWD ...) — when Motor_FWD goes FALSE on the same scan, IN=FALSE resets the timer immediately next cycle. But worse: timer.Q triggers Motor_FWD:=FALSE, then next scan IN=FALSE resets .Q, so IF index_timer.Q is never TRUE for a full scan → deadlock. Fix: use a separate latch or set IN:=TRUE unconditionally in state 2 and reset on exit.
- Bug 2 — Line 23: IF Pos_Sensor AND NOT fault OR e_stop — due to AND precedence this reads as: IF (Pos_Sensor AND (NOT fault)) OR e_stop. This means an E-Stop alone transitions to IDLE (state 0) without fault handling. Fix: IF (Pos_Sensor AND (NOT fault)) OR (e_stop) is the same but intent was probably IF Pos_Sensor AND (NOT fault OR e_stop) — needs parentheses per intent.
Bug 1 creates the deadlock: the timer IN pin is tied to Motor_FWD. When the timer fires, Motor_FWD goes FALSE on the same scan. Next scan, IN=FALSE resets the timer. So .Q is only TRUE for one scan — which is fine IF the IF block executes. But race: same scan Motor_FWD:=FALSE and state:=3 happen, but if any jitter causes the timer to not have a TRUE .Q pulse, it deadlocks in state 2. Bug 2 is a logic error that allows E-Stop to silently return to IDLE rather than entering a fault/reset state.