Maintain a counter and independent timed finite-state machine for each detector–light pair, while sharing the interrupt scan and timer infrastructure. Blocking for one channel's flash would unnecessarily delay every other channel.
eye_handler():
    for i in all_channels:
        if EYE_DETECTED[i] != 0:
            EYE_DETECTED[i] = 0
            pending[i] = pending[i] + 1

main_event_loop():
    initialise each LIGHT[i] = 0
    initialise pending[i] = 0, state[i] = IDLE
    enable detector interrupts
    forever:
        now = monotonic_timer_snapshot()
        for i in all_channels:
            service_channel(i, now)
        arrange the next wake-up for new work or the earliest deadline
service_channel is the three-state sequencer from (a), with its own started[i] and an interrupt-safe try_take_event(i). Shared interrupt demultiplexing uses separate if tests, not an else if chain: simultaneous pending detectors must all be acknowledged and counted. If a new detector becomes pending during the scan, the controller must retrigger while a flag remains set or the handler must rescan appropriately; the exact interrupt controller semantics must be checked rather than assuming a single scan can never miss an edge.
One hardware timer can schedule the earliest active channel deadline. On its expiry, service every due channel and rearm for the next deadline; a periodic tick with adequate resolution is a simpler alternative. Detectors and the timer can then interleave without serial one-second waits. The handler/main-program counter accesses need the same short critical section protection as in (a). Keep timing state in one execution context, or protect it too if both a timer handler and the main program modify it.
The loop invariants are per channel: the pending count equals recorded but unstarted events, ON means that channel's light is on, and GAP prevents a new flash until one second after its preceding light-off transition. Different channels may flash simultaneously. The event latch rearming limitation, finite backlog capacity and timer-resolution qualifications apply independently to each channel. These cannot be solved by replacing several event counters with one global Boolean variable.