A cyclic timer-driven industrial warning beacon system implemented in Ladder Logic (LD) using OpenPLC Editor, featuring dual-mode flash rate control via chained TON timer blocks
This project implements a configurable flashing warning beacon using IEC 61131-3 Ladder Logic (LD), designed and simulated in the OpenPLC Editor environment. The core timing mechanism relies on two chained TON (Timer On-Delay) function blocks to generate a continuous, non-blocking pulse cycle with independently configurable ON and OFF durations. The system supports two operational modes: a standard periodic flash for general machine status indication, and an accelerated alarm flash mode that increases pulse frequency to communicate elevated fault urgency. Internal state management is handled via a dedicated boolean flag, FLASH_STATE, which coordinates timer reset sequencing to maintain cycle integrity without race conditions.
Industrial environments require reliable, unambiguous visual signaling to communicate machine states to operators on the floor. A static indicator is insufficient for time-critical fault conditions, as it fails to attract attention amid busy surroundings. The challenge was to implement a beacon control system that could produce a continuous, self-sustaining flash cycle using only on-delay timers — without relying on external pulse generators or hardware-specific function blocks — while also supporting a dynamically switchable alarm mode that increases urgency signaling without requiring a program halt or re-upload to the PLC.
FLASH_STATE is TRUE and SYSTEM_ENABLE is assertedFLASH_STATEFLASH_STATE and restarts the ON phase
The pulse generation logic is built around a two-stage timer chain. When SYSTEM_ENABLE is asserted and FLASH_STATE is FALSE, TIMER_OFF begins accumulating. On its done output, FLASH_STATE is set TRUE, which simultaneously de-energises TIMER_OFF (resetting it) and enables TIMER_ON. When TIMER_ON completes, FLASH_STATE is cleared, returning the system to the OFF phase and completing one full cycle. This handoff pattern ensures that only one timer is active at any given scan, eliminating state overlap. The ALARM_MODE input is evaluated before each timer enable rung to conditionally substitute a shorter preset value, allowing the flash rate to increase without interrupting the current cycle.
VAR_INPUT
SYSTEM_ENABLE : BOOL := FALSE;
ALARM_MODE : BOOL := FALSE;
END_VAR
VAR_OUTPUT
WARNING_BEACON : BOOL := FALSE;
END_VAR
VAR
TIMER_ON : TON;
TIMER_OFF : TON;
FLASH_STATE : BOOL := FALSE;
TIMER_ON_DONE : BOOL := FALSE;
TIMER_OFF_DONE : BOOL := FALSE;
TIMER_PRESET : TIME := T#2s;
END_VAR
Functional verification was carried out using the integrated OpenPLC soft PLC simulator with the built-in variable watch and debugger. Each scan cycle was monitored in real time to confirm correct timer accumulation, done-bit assertion timing, and state flag transitions. The following conditions were explicitly validated:
SYSTEM_ENABLE correctly initiates the OFF phase and begins the first timer accumulation cycleWARNING_BEACON output coil energises and de-energises in strict synchronisation with FLASH_STATE transitionsFLASH_STATE toggles cleanly between TRUE and FALSE with no spurious intermediate states observed across extended simulation runsALARM_MODE mid-cycle correctly applies the reduced preset value on the next timer enable, increasing flash frequency without stalling the cycleSYSTEM_ENABLE halts all timer activity and forces WARNING_BEACON to de-energise within a single scan
The primary engineering challenge was designing a self-resetting timer loop that avoids simultaneous timer activation within a single scan cycle. In Ladder Logic, TON blocks begin accumulating immediately when their enable coil is TRUE; without careful state sequencing, both timers could activate concurrently, producing undefined flash behaviour. This was resolved by using FLASH_STATE as a mutual exclusion flag — each timer's enable rung is conditioned on the inverse state of the other, ensuring only one timer accumulates at any given time.
A secondary challenge was implementing alarm mode preset switching without introducing transient glitches. Because TON timers retain their elapsed value when their enable drops momentarily, any brief de-assertion during a preset swap would cause an incorrect accumulated time on resumption. This was addressed by evaluating the ALARM_MODE input prior to each timer enable evaluation within the same scan, so the preset is applied consistently without interrupting the active timer.