exercises · South Africa
Pedestrian Crossing PLC Program: Requests and Timers
Build a pedestrian crossing PLC program with request memory, timed phases and boundary tests, with ladder guidance and course questions for SA learners.

This pedestrian crossing PLC program is a disconnected request-handling exercise. A virtual button stores one pending request, a minimum Green interval delays service, and timed Amber and Walk phases complete it. The important detail is when the programme consumes the request: this version consumes it when leaving Green, so later presses during Amber or Walk can request one additional cycle.
The output names make the example easy to follow, but the exercise is not a design for an actual crossing. It supplies no physical signals, clearance calculation, accessibility system, traffic assessment or validated safety function. The ten-, three- and eight-second durations are fictional learning parameters, not recommended timings for people or vehicles.
For South African learners studying PLC timers, latches and ladder sequencing, the exercise connects three skills: detect an event, remember work that is waiting, and decide when that work can begin. You should be able to explain all three from a trace rather than relying on a changing animation.
Define the request policy before writing logic
Use RequestButton true to mean the supplied virtual button is held. A request event is an observed false-to-true transition. Pending is a Boolean saying that at least one accepted request is waiting for a future service cycle. It is not a count of people or a count of every press.
Several accepted presses while Pending is already true merge into the same waiting request. They do not shorten any phase or add several queued cycles. Once that pending request is consumed, a later edge can create another waiting request.
The service cycle becomes committed when Green changes to Amber. At that transition, clear Pending. A subsequent edge in Amber belongs to the next cycle, so it sets Pending again. Entering Walk must not clear that new request.
This distinction fixes an easy-to-miss bug. If you set Pending whenever the button rises but clear it on entering Walk, a press during Amber can be accepted and then erased before the next cycle. That programme would contradict a requirement to remember Amber-phase presses.
Another policy could merge all presses up to Walk into the current service. That is a different valid learning specification, but its expected results must say so. Here the dividing point is explicitly the Green-to-Amber transition.
| Button event occurs while the previous state is… | Result in this model |
|---|---|
| Green before the minimum interval | Store Pending and wait |
| Green with the minimum interval complete | Store and consume the request, entering Amber |
| Amber | Store one request for the following cycle |
| Walk | Store one request for the following cycle |
| Disabled or the first enabling evaluation | Ignore the event and keep Pending clear |
Separate the states from the virtual outputs
Use Disabled, Green, Amber and Walk as the allowed states. Enabled is a supplied Boolean controlling whether the exercise runs. PhaseStartedAt is the supplied timestamp at entry into the current active state. Use nondecreasing whole-number milliseconds for the worked examples.
| Resulting state | TrafficGreen | TrafficAmber | TrafficRed | WalkGreen | WalkRed |
|---|---|---|---|---|---|
| Disabled | False | False | False | False | False |
| Green | True | False | False | False | True |
| Amber | False | True | False | False | True |
| Walk | False | False | True | True | False |
Decode all five outputs from the same final state after processing the transition. Each output has one writer in this model. Enabled false gates every output false, including WalkRed; do not define that output merely as “not Walk” without considering Disabled.
The table excludes a simultaneous virtual TrafficGreen and WalkGreen. This is a property of the stated output equations. It is not evidence that real signal heads operate correctly, that no other task writes their outputs or that an actual route is clear.
Start with the traffic-light sequencing exercise if timed states are new to you. The ladder logic basics guide explains the underlying Boolean conditions before you combine them with request memory.

Define startup and interruption explicitly
Initialise State to Disabled, Pending false and PhaseStartedAt empty. Initialise PreviousButton to the current RequestButton value. A button already held when the exercise starts is therefore not treated as a newly observed press.
At every evaluation, calculate RequestEdge from the raw RequestButton and PreviousButton. At the end of every evaluation, update PreviousButton to the current button value, even while disabled. That history must keep describing what was actually observed.
Enabled false has highest priority. It selects Disabled, clears Pending and the timestamp, and makes every output false. This version deliberately discards unfinished service and queued work after interruption. It does not claim that people or objects outside a physical system disappear when a Boolean changes.
The first enabled evaluation from Disabled selects Green, clears Pending and starts its timestamp. It ignores any request edge on that particular evaluation. Once Green is established, a newly observed release-and-press sequence can create a request. A button held throughout enabling cannot silently add one.
If an unexpected state value is supplied while enabled, report InvalidStateDetected for that evaluation, select Disabled and clear the pending work. If Enabled remains true, the following evaluation performs the normal enabling transition into Green. This is a deterministic learning recovery rule, not a physical fault-recovery design.
Use the conveyor restart exercise to compare another explicit interruption policy. Do not assume that every application should retain or discard requests in the same way; the relevant skill is specifying and testing the chosen behaviour.
Process the request before selecting a timed transition
For an ordinary enabled evaluation that begins in Green, Amber or Walk, first calculate the candidate pending value as Pending OR RequestEdge. Then apply the transition rule for the state that existed at the start of the evaluation.
In Green, stay there until both the minimum interval of 10000 ms has elapsed and the candidate pending value is true. When both are true, enter Amber, set PhaseStartedAt to the current time and clear Pending. That clear consumes the work just selected for service.
In Amber, retain the candidate pending value. At 3000 ms or later from Amber entry, change to Walk and record a new phase timestamp. Do not clear Pending at that transition: it can represent another request accepted after the current service was committed.
In Walk, also retain the candidate pending value. At 8000 ms or later from Walk entry, change to Green and record the current timestamp. The new Green phase must then receive its own minimum interval before a waiting request can start another Amber phase.
Process only one state transition per evaluation. Returning from Walk to Green does not immediately process Green again, even if Pending is true. The new timestamp also prevents elapsed time from the old Walk phase being mistaken for time spent in Green.
Structured-text-style pseudocode
This is language-neutral pseudocode using structured-text-style decisions. State names, the empty timestamp and the supplied clock are abstract model elements. Translate them into supported types and facilities in the actual programming environment before attempting native execution.
RequestEdge := RequestButton AND NOT PreviousButton;
InvalidStateDetected := FALSE;
OldState := State;
IF NOT Enabled THEN
State := Disabled;
Pending := FALSE;
PhaseStartedAt := EMPTY;
ELSIF OldState = Disabled THEN
State := Green;
Pending := FALSE;
PhaseStartedAt := CurrentTimeMs;
ELSIF OldState NOT IN {Green, Amber, Walk} THEN
State := Disabled;
Pending := FALSE;
PhaseStartedAt := EMPTY;
InvalidStateDetected := TRUE;
ELSE
Pending := Pending OR RequestEdge;
CASE OldState OF
Green:
IF Pending AND CurrentTimeMs - PhaseStartedAt >= 10000 THEN
State := Amber;
PhaseStartedAt := CurrentTimeMs;
Pending := FALSE;
END_IF;
Amber:
IF CurrentTimeMs - PhaseStartedAt >= 3000 THEN
State := Walk;
PhaseStartedAt := CurrentTimeMs;
END_IF;
Walk:
IF CurrentTimeMs - PhaseStartedAt >= 8000 THEN
State := Green;
PhaseStartedAt := CurrentTimeMs;
END_IF;
END_CASE;
END_IF;
PreviousButton := RequestButton;
After this decision, assign the five outputs from the state table, with Enabled as an additional condition. A valid active state must have a valid associated phase timestamp. Manually changing one without the other does not represent a normal programme transition.
The CODESYS R_TRIG documentation describes detection of a rising Boolean edge. This page separately defines initial history and when an event is accepted; those application rules should not be inferred from an instruction name alone.
If using native TON blocks instead of supplied timestamps, inspect their invocation and reset behaviour. Schneider Electric’s TON documentation describes the relationship between input, elapsed time and output. A native implementation needs its own trace before you claim it matches this model.

Trace a request during Amber through the next cycle
Start a fresh run with Enabled true, RequestButton false and the initial state Disabled. Times below are supplied observations. They demonstrate request ownership as well as timing.
| Time ms | Button | State after evaluation | Pending | What changed |
|---|---|---|---|---|
| 0 | 0 | Green | False | Start the first minimum interval |
| 2000 | 1 | Green | True | Accept the first request |
| 2100 | 0 | Green | True | Releasing does not erase it |
| 9999 | 0 | Green | True | Minimum interval is incomplete |
| 10000 | 0 | Amber | False | Commit service and consume request |
| 11000 | 1 | Amber | True | Store a new request for later |
| 11100 | 0 | Amber | True | Retain the waiting request |
| 13000 | 0 | Walk | True | Begin Walk without erasing it |
| 14000 | 1 | Walk | True | Another press merges into waiting work |
| 14100 | 0 | Walk | True | Retain one pending request |
| 21000 | 0 | Green | True | Start a fresh minimum interval |
| 30999 | 0 | Green | True | Do not serve the next request early |
| 31000 | 0 | Amber | False | Consume the one waiting request |
| 34000 | 0 | Walk | False | No further request is waiting |
| 42000 | 0 | Green | False | Return to Green |
| 52000 | 0 | Green | False | Elapsed minimum alone does not start service |
The second press at 11000 survives entry into Walk at 13000. The extra press at 14000 does not create a third queued cycle because the pending storage has capacity for one merged request. At 52000 the programme remains Green despite its completed minimum interval, because there is no pending work.
If you deliberately add Pending := FALSE to the Amber-to-Walk transition, the row at 13000 becomes wrong. That single change is enough to expose the original lost-request defect. Use the trace to demonstrate the failure and its correction in your own environment.
Give simultaneous events a defined result
A fresh press exactly when Green becomes eligible can be consumed on that same evaluation. The request is accepted before the Green transition condition is tested. Pending ends false and State becomes Amber; that press belongs to the service just committed.
A fresh press exactly when Amber expires remains pending for the following cycle. The state becomes Walk, but the request is not cleared. A fresh press exactly when Walk expires likewise remains pending while the state becomes Green and starts a new minimum interval.
Repeated presses before the first Green-to-Amber transition merge into the first request. Repeated presses after that transition can merge into one additional request. Therefore the meaning of “twenty presses” depends on when the edges occur; the total number alone does not determine the number of service cycles.
A held button is different again. If it rises once at 2000 and stays true through the entire first service, no additional edges occur during Amber or Walk. After the first service the programme returns to Green with no pending request and waits. Holding it does not create a request on every evaluation.

Measure waiting time from the correct origin
For an ordinary request during Green, the remaining minimum wait in this model is the greater of zero and 10000 ms minus time already spent in Green. This expresses eligibility, not a guarantee that the next evaluation happens at the exact threshold.
A request at 2000 after Green began at zero has 8000 ms of the minimum interval remaining. A request at 15000 during an uninterrupted Green phase is already eligible and can enter Amber at that evaluation. The model does not restart the minimum timer for every press.
A queued request when Walk ends must wait through the next Green interval. In the worked trace, the request stored at 11000 starts its service at 31000: a 20000 ms observed wait to Amber. Its Walk phase begins at 34000. State which event you mean when reporting a waiting time.
Late evaluations can lengthen these observations. If Green becomes Amber at 10200 instead of 10000, the new Amber timestamp is 10200. An evaluation at 13000 is then too early for the 3000 ms Amber interval; a later evaluation at 13200 can enter Walk.
Do not describe this timing model as proving pedestrian capacity, acceptable crossing delay or adequate walking time. It has no physical distance, walking-speed assessment, traffic flow or accessibility evidence. It teaches the relationship between event acceptance, eligibility and phase entry.
Translate to ladder without losing the queue policy
Keep raw edge detection separate from request acceptance. Calculate the button edge every evaluation and update its history during Disabled as well as active phases. Gating the edge detector’s input with Enabled can make a held button appear newly pressed when Enabled changes.
Use an intermediate pending value if it makes the rung order clearer. Set CandidatePending from the previous Pending and the current accepted edge. Select the next state from the old state. Clear the candidate only when Green-to-Amber commits a service, or when the higher-priority startup, disable or invalid-state branches clear work.
Commit the final Pending value once. Separate set and reset coils scattered across unrelated rungs can conceal which write wins when an edge and a transition occur together. The three simultaneous-event cases above should remain the same after translation.
Decode outputs after committing the state. The scan-cycle explanation can help you inspect execution order, while the bottle-counting lesson offers another example of raw edges and a bounded memory value.

Build a test record that explains the programme
Include a no-request run, an early Green request, a late Green request, a held-button run and the complete Amber-request trace. Test presses at all three transition boundaries. Test disabling with Pending true and during each active phase; all work is cleared under this contract.
Test startup with the button already held. Then release it, observe that release, and press again after Green is established. Compare those two input histories. A correctly ignored startup level and an accepted later edge should not be described as inconsistent behaviour.
Record the raw button, previous button, calculated edge, previous state, resulting state, pending flag and phase origin. Preserve the expected results before running the case. Add observed values afterwards so a portfolio reviewer can see which behaviours you predicted and which you actually verified.
If a test fails, identify the first evaluation where the result diverges. For example, an Amber-phase request disappearing precisely at Walk entry points to the consume/reset policy. That observation is more useful than saying “the button sometimes does not work”, and it avoids guessing a physical root cause from a software trace.
South African training and learner questions
When comparing PLC courses in Pinetown, Durban, Johannesburg, Pretoria or an online programme, ask whether learners inspect pending requests and timer states themselves. A location name or a demonstration video does not establish that a course teaches event handling or lets you test edge cases.
Ask a provider to explain what happens to a request during Amber and to demonstrate the answer in the software used on the course. Ask whether the exercise uses a supplied clock or native timers, and whether ladder and structured-text examples are both checked against the same event trace.
Use the online PLC training guide for delivery questions and the engineering-student guide for portfolio planning. Describe this work as a virtual request-service model. A completion record does not make it an installed crossing project, a professional approval or a registered qualification.
Why not clear Pending when Walk begins?
Under this page’s policy, the current service was committed when Green changed to Amber. A new pending value during Amber belongs to the next service. Clearing it at Walk entry loses that work. If your specification chooses a different commitment point, rewrite the expected trace accordingly.
Does pressing repeatedly make the sequence faster?
No phase duration is changed by a press in this model. Several edges while a request is already pending merge into one waiting item. Presses after that item is consumed can create another pending item, so event timing still matters.
Can I add an all-red or flashing phase?
You can add virtual states as a separate learning extension with an explicit output table and request policy. Define when timing begins and whether requests during the new phase merge or remain pending. This page gives no physical clearance duration or accessibility design recommendation.
Can one pending bit represent several pedestrians?
It represents that some work is waiting, not how many people or presses exist. A numerical queue would need capacity, overflow handling and a decision about what one queue item means. Do not interpret a Boolean as a measured pedestrian count.

Continue with sequence and execution-order practice
Inspect the traffic-light scenario preview in PLC Simulation Software for a related sequence-learning entry point. It is not a claim that this exact request-handling exercise is supplied or graded on a particular plan.
For the order in which conditions and outputs are evaluated, review the product’s scan-cycle highlighting feature. Compare its documented behaviour with your chosen implementation rather than assuming all simulators share one execution model.
Return to the PLC programming examples collection when you can explain where a request is stored, which transition consumes it, and why a later press survives the current service. Those ideas transfer to many request-driven learning problems beyond this particular set of virtual indicators.