Delayed write commit timer for HMI switch presses

7 min read · Published November 6, 2026

A plain touch panel switch writes its value to the PLC the instant it is pressed, so an accidental tap commands the machine. Map the switch to a request register, restart an on-delay timer on every change, and copy the request to the command register only when the timer completes. A 3 second window lets the operator undo a slip; use 2 to 5 seconds depending on the station.

You tap a position on the panel, the machine reacts before you have lifted your finger, and there is no way back. That is how a plain switch object works: it writes its value to the mapped PLC address the moment the touch is recognized, and the machine logic sees it on the next scan. The panel has no waiting state, so the delay has to be built where the value lands. Map the switch to a request register instead of the command register, restart an on-delay timer on every change of the request, and copy request to command only when the timer completes. With a 3 second window the operator can undo a slip before anything starts or stops; 2 to 5 seconds fits most stations. This page shows the logic, the window length, the operator indicator, and the bench checks.

What the symptoms point to

All of these come from one root: the write reaches the machine at touch time.

  • The equipment starts within a second of a tap the operator meant to miss. The switch maps straight to the command register, so nothing stands between the touch and the output.
  • A selector run quickly across several positions commands each one. Every intermediate value lands in the command register in order, and every rung that reads it acts.
  • Pressing again to take the change back accomplishes nothing. The first value already commanded the machine; the second press is just another write.
  • A second panel at the far end of the line writes the same command word, and the two operators' values interleave. Neither of them gets a window.

Check for a delay setting in the panel software first

Some design packages can hold a switch's write for you. One vendor's manual documents it: on the [Switch Common] tab, tick [Delay Feature], choose [OFF Delay] as the [Delay Action] and [Constant] for [Define Time], and enter the time; that manual page covers delaying a switch's OFF write, and its worked example sets 3 seconds. If your own software's manual shows a page like that for your switch objects, set the time there and you are done. If the switch object offers no such page, the delay moves into the PLC, and the rest of this page is the build.

The request register pattern

Give the panel its own register and make the PLC the only writer of the command value.

  • HMI_Req: INT, initial 0. The switch object maps here, and nothing else.
  • Cmd: INT, initial 0. Every machine rung reads this. Only the commit line writes it.
  • Commit_Delay: TIME, start at T#3S.
  • Commit_TMR: an on-delay timer of the TON kind your platform provides. It accumulates while its input is true and resets to zero when the input goes false, which is exactly the restart behavior the pattern needs.
  • Pending: BOOL, initial FALSE. The panel indicator maps here.

One rung owns Cmd. When a panel and the PLC logic both write one register, you get the kind of fight behind an HMI timer preset that resets to zero in the PLC. Keep one writer and it cannot happen here.

(* Illustrative names and initial values; rename to your own standard. *)
(* HMI_Req : INT := 0;   Cmd : INT := 0;   Last_Req : INT := 0;        *)
(* ReReq : BOOL := FALSE;   Pending : BOOL := FALSE;                   *)
(* Commit_Delay : TIME := T#3S;   Commit_TMR : TON;                    *)

ReReq := (HMI_Req <> Last_Req);        (* a new press pulses one scan *)
Last_Req := HMI_Req;

Commit_TMR(IN := (HMI_Req <> Cmd) AND NOT ReReq, PT := Commit_Delay);

IF Commit_TMR.Q THEN
    Cmd := HMI_Req;                    (* the only write to Cmd *)
END_IF

Pending := (HMI_Req <> Cmd);

Three behaviors fall out of those lines:

  • Undo. The operator taps back to the value already in Cmd inside the window, the comparison HMI_Req <> Cmd goes false, the timer resets with its accumulated time discarded, and nothing is written. Pending clears.
  • Restart on change. A second press to a new value pulses ReReq for one scan, the timer's input drops for that scan, and the window starts over from zero. A repeat press of the same value produces no change, so it neither restarts the window nor extends it.
  • One commit. The timer completes, Cmd takes HMI_Req, the comparison goes false, and the timer stands down until the next request. An intermediate position reaches the machine logic only if it outlives the full window.

How long the window should be

Start at T#3S and adjust from the station. Three seconds covers the common slip: the operator sees the wrong highlight, decides, and taps back. Under T#2S the window is gone before the slip is even noticed; past T#5S operators begin to assume the panel is dead and press twice, which defeats the point. Stretch toward T#5S when the panel is shared between operators or mounted away from the machine it drives, because the operator may have to walk over to see the result. Tighten to T#2S for a single station within arm's reach.

Show the operator the value is waiting

An unapplied value the panel does not display is a trap, because the operator believes the change took. Map a lamp or a colored border to Pending so the requested-but-not-committed state is visible, and on a selector switch, highlight the requested position and mark the committed position so the two can be told apart from across the panel. If your panel can display a time value from a PLC tag, map the timer's ET output, which counts up in milliseconds toward the preset, and the countdown itself shows on the screen; the mapping is the same one used to show an HMI timer counting from a PLC current value.

Example: three taps and one commit

A packaging line mode selector has four positions, 0 to 3, written to HMI_Req. Cmd holds 1 and the line runs in mode 1. Commit_Delay is T#3S.

  • t = 0.0 s: the operator taps position 3. HMI_Req changes from 1 to 3, ReReq pulses, and the timer begins to accumulate toward 3.0 s.
  • t = 0.8 s: the operator changes course and taps position 2. HMI_Req goes from 3 to 2, the window restarts from 0.0 s, and the 0.8 s already accumulated is discarded.
  • t = 1.6 s: the operator settles on position 3. HMI_Req goes from 2 to 3, and the window restarts again.
  • t = 1.6 s + 3.0 s = 4.6 s: the timer completes, Commit_TMR.Q goes true, and Cmd takes the value 3 in a single write.

The machine logic saw one change, from 1 to 3, at 4.6 s after the first tap. Position 2 never reached it, even though the switch passed through it, because no value except the last one survived a full 3.0 s window. The undo case behaves the other way around: tap position 3 at t = 0.0 s and tap back to 1 at t = 2.0 s, the comparison goes false, the accumulated 2.0 s is discarded, Cmd stays at 1, and Pending clears with nothing written.

What a pending request does across a power cycle

Decide the startup behavior on purpose. If HMI_Req and Cmd are both non-retentive, a CPU restart initializes both to 0 and nothing commits until the next press. The trap is a retentive request register: the CPU comes back, sees a mismatch against Cmd, starts the window, and commits an old request with nobody standing there. Either adopt the panel state on the first scan with Cmd := HMI_Req, or clear HMI_Req in the startup routine and make the operator press again. A stored operator request that survives a CPU restart is its own subject; clearing a stored operator request after a CPU restart walks through one case end to end.

Check it on the bench before it drives anything

  • Tap to a new position, confirm Pending lights, then tap back inside the window. Cmd must be unchanged and Pending must clear.
  • Hold a new position past the window and watch the ET display climb to the preset. Cmd changes once, at the window time, and Pending clears.
  • Tap three positions within about 2 seconds. Only the last value may appear in Cmd.
  • Restart the CPU while a request is pending and confirm the startup behavior you chose is the one that happens, with no unattended commit.

Recommendation and the decision for each case

Recommendation: build the two-register commit in the PLC for every switch that starts or stops equipment: the switch mapped to HMI_Req, one TON at T#3S restarting on every change, a single write to Cmd, and a Pending lamp on the panel. Keep every stop and emergency function off this path entirely; those belong to their hardwired safety circuits, and a convenience delay carries no safety function.

The decision by case: if your design software documents a delay on the switch object, set it there and skip the logic. If it does not, run the pattern above at T#3S for one operator within reach of the machine, or T#5S for a shared or remote panel. For a momentary pushbutton, use the panel's own delay setting or a set-dominant bit pair, because the press-release cycle fights the window. And if the screen in question only displays status for people to read, this is the wrong tool altogether; the factory status display or operator HMI choice comes first.

Questions

Does panel software ever offer this delay as a setting?

Some design packages do, and their manuals document it. One places it on the switch's [Switch Common] tab: tick the [Delay Feature] check box, choose [OFF Delay] as the [Delay Action], pick [Constant] for [Define Time], and the manual's worked example sets 3 seconds. If your own manual shows that page, the object holds its write for you. Where the setting is absent, build the request register pattern in the PLC.

Does this work for a momentary pushbutton, not a selector?

A momentary button writes one value on press and the other on release, so a tap shorter than the window undoes itself: the release restores the old value inside the window, the timer resets, and the command never lands. Hold it longer than the window and the pressed value commits, then the release starts a second window that commits the released value. For pushbuttons, use a set-dominant pair of bits or the panel's own delay setting; the pattern as written fits maintained selectors and value switches.

Two operators, two panels, one machine: does the pattern still hold?

Yes. With one shared request register the last press wins, and every press restarts the window, so the commit reflects the newest request. That usually suits a shared station. If the panels must be told apart, give each its own request word and its own pending flag, and let the logic decide which request reaches the machine. Note that with one shared register, one operator reverting inside the window undoes the other operator's press too.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote