Signal an HMI alarm acknowledgment back to the PLC

9 min read · Published November 8, 2026

Most small panels' built-in alarm confirm never reaches the controller. Set up a request-and-echo handshake: the panel holds a request bit on until the PLC stamps the acknowledgment into the alarm record and echoes a response bit back. At a typical 500 ms panel write cycle the ack shows on screen within about a second.

The confirm button on a small panel's built-in alarm display marks the event inside the panel and stops there. The controller never learns that anyone saw the alarm. Build the acknowledgment into the controller instead. A user button on the panel sets a request bit and holds it on, the controller stamps an ack flag into that alarm's record and raises an echo bit, and the panel clears the request when the echo comes back. At a typical 500 ms panel write cycle the acknowledgment shows on screen within about a second, and it stays in the record after the alarm condition clears, which is exactly the state the built-in display loses.

Why the built-in confirm never reaches the controller

Two things are happening when an alarm message drops before anyone has acked it, and neither is a setting you can flip.

First, on many small panels the confirm button belongs to the panel's own alarm object. It marks the event acknowledged in the panel's history and has no controller tag behind it. Some platforms do document an acknowledgment tag that can point at a controller bit; where your panel's manual names one, use it and skip the rest of this article. Where it names none, the confirm you press never crosses the cable.

Second, the message line follows the live condition, so the message disappears the moment the input clears, confirm required or not. That behavior matches the standard. ISA-18.2, the process alarm management standard (published internationally as IEC 62682), treats the alarm condition and the operator acknowledgment as two separate states: an alarm can be back to normal and still unacknowledged. A record in the controller carries both states as fields, and that record is the fix.

The request-and-echo handshake

Three pieces of controller memory run the whole job:

  • One handshake register: the low bit is the request, which the panel writes; the next bit is the echo, which the controller writes.
  • One index register naming the record the request applies to. The panel writes it when the operator selects a line, or you fix it to the newest alarm if one button covers the panel.
  • The log block, eight registers per record, ack flag included.

The sequence:

  1. The operator presses Ack. The panel writes the request bit to 1 and keeps writing 1.
  2. The controller's scan sees request = 1 with the target record's ack flag still 0, writes that flag to 1, and raises the echo bit, all in one scan.
  3. The panel's next read brings the echo in, and the panel clears the request to 0.
  4. The controller sees request = 0 and clears the echo. The handshake is closed and ready for the next press.

Each side writes exactly one bit and never touches the other's. That ownership rule is why the handshake restarts cleanly after a power cycle: the panel comes back writing request = 0, the controller drops the echo within a scan, and no record is left half-written, because the ack flag goes in after the record's eight fields are already there.

Trigger the stamp from the scan, one rung watching the request bit; completing the response inside the scan instead of off an interrupt is the polled handshake pattern, and a poll-and-zero handshake walkthrough shows how it behaves on a small controller.

What you need

A panel pushbutton that can set one bit on press and clear that bit when a second bit reads on. Most panel editors give a button a set tag and a reset tag; if yours needs two lines of script instead, it is the same two writes.

A controller with a real-time clock for the stamps, spare registers for the handshake word and the index, and room for the log block.

A display object per record line, reading that record's eight registers so code, date, time and ack land on one row.

The panel side never sees the alarm logic. It sees two bits and a block of registers.

Build it in five steps

  1. Reserve the memory. One register for the handshake, one for the selected-record index, and the log block sized for the history you want. Write the ranges down and confirm nothing else in the program reads or writes them.
  2. Write the record on the alarm's rising edge. When an alarm bit turns on, move the alarm code and the six time fields from the controller's real-time clock into the record's first seven registers, write 0 to the ack field, then advance the index and wrap it at capacity. Fields go in before the index moves, so the panel never displays a half-filled line.
  3. Add the ack rung. When the request bit is 1 and the selected record's ack flag is still 0, write 1 to that flag and raise the echo bit in the same rung. The flag guard stops a second write if the request arrives again before the panel has cleared it.
  4. Add the close-down rung. Request bit at 0 clears the echo bit. Two rungs carry the whole handshake on the controller side.
  5. Configure the panel button and the lines. Set the request bit on press, reset it when the echo reads on, and map one display row per record: code, month, day, year, hour, minute, second, ack.

Hold the request until the echo returns

A momentary press is the failure mode to design out. The panel writes its tags on its update cycle, commonly every 100 to 500 ms on a small serial or Ethernet link, and slower when the link carries many tags. A tap that switches the bit on and off between two writes can reach the controller as nothing at all: no write ever carries the 1. Holding the request on until the echo closes that hole, because the first write after the press carries request = 1 no matter how short the tap was.

The controller sees it within one scan, a few milliseconds in a small program, and the panel brings the echo back on the next read. Finger to stamped record is one write cycle plus one scan; stamped record to visible ack is one more read cycle. At the slow end of the common range that is about a second, and at a 100 ms cycle about 0.2 s. What a momentary bit does on the controller side, scan by scan, is counted out in How many PLC scans an HMI momentary button bit stays on.

Give the missing echo a threshold: if the echo has not come back within 2 s, the request is landing nowhere or the button's reset tag is wrong. Check the handshake address first, then the button.

Eight registers per record fills one display line

Give every field its own 16-bit register:

Register Field
1 alarm code
2 month
3 day
4 year
5 hour
6 minute
7 second
8 ack flag

One record, one row: code, MM, DD, YY, HH, MM, SS, ACK, which fits a small panel's line with the text still readable. The ack flag updates in place, so a row flips from 0 to 1 the moment the handshake lands, and the row stays after the condition clears: cleared and unacknowledged, the two states ISA-18.2 keeps separate. If return-to-normal belongs in the history too, add a ninth register for the condition state and divide capacity by 9 instead of 8.

Stamp the six time fields from the controller's real-time clock and set the panel's clock from the controller, so every time the panel shows agrees with the log; Set an HMI clock from the PLC and read trend axes in time covers that sync.

Because the lines are your own objects, the cramped built-in history and its wrapped button legends go away with the rest of it. Where the block sits and how the write index wraps at the end is the storage half of the design, covered in Log PLC alarms to a circular event buffer with separate pointers.

Worked example: 771 registers, 8-register records, 500 ms write cycle

Inputs, and where each comes from:

  • Log block of 771 consecutive registers: assumed, a realistic spare range in a small controller.
  • Eight 16-bit registers per record: the layout above.
  • Write cycle of 500 ms: assumed at the slow end of the common 100 to 500 ms range for small-panel links; more tags on the link push a real link toward this end.
  • Scan of 10 ms: assumed, typical for a small program; bigger programs move it up by a few milliseconds at most on this kind of controller.

Rule in words: capacity in records is block registers divided by registers per record, rounded down. Press-to-visible-ack is one write cycle plus one scan plus one read cycle.

Arithmetic:

  • 771 ÷ 8 = 96.375, so 96 whole records fit. 96 × 8 = 768 registers used, and 771 − 768 = 3 left over: one for the index, one for the handshake register, one spare.
  • Press to visible ack: 0.5 s (the press waits for the next write) + 0.01 s (the scan that stamps and raises the echo) + 0.5 s (the read that shows the flipped ack) = 1.01 s, call it a second. At a 100 ms cycle the same path is 0.1 + 0.01 + 0.1 = 0.21 s.

Result: a 771-register block holds 96 alarm records at eight registers each, and the acknowledgment lands on screen in about a second at the assumed cycle.

Decision: a shift that can produce more than 96 alarm events between reviews needs a bigger block; add 8 registers per extra record, so 100 records take 800 registers, plus 3 more for the index and the handshake word. Hold the request until the echo, and treat no echo within 2 s as a fault: check the handshake address before anything else.

How to check it worked

Run the test on a spare alarm bit before the handshake guards anything real.

  1. Force an unused alarm bit on. The newest row shows the code and the time, ack at 0.
  2. Tap Ack and let go immediately. In the controller, the request bit must read 1 across at least one full write cycle with your finger already off the button: that is the hold working. The row's ack flips to 1 inside a second at the example's cycle, and the echo drops back to 0 after the request does.
  3. Clear the alarm condition while the ack is still 0. The live message drops, the row stays, and a press of Ack flips it to 1. That is the cleared-but-unacknowledged path the built-in display was missing.
  4. Push 97 events through and check the wrap: the top row now shows the newest event and the oldest record's registers have been reused.
  5. Cut panel power mid-press and reapply. The panel comes back writing request = 0, the controller drops the echo within a scan, and every row is intact, because records complete before the index moves.

When all five pass, the acknowledgment is a fact in controller memory: an ack flag in a record, in a log, readable by anything that reads the controller.

Recommendation: Run the request-and-echo handshake with the panel holding the request bit on until the echo returns, eight registers per record so one record fills one display row, and a block sized at worst-case events between reviews times 8, plus 3 registers for the index and the handshake word. Use the panel's documented acknowledgment tag first if its alarm viewer has one; build this handshake when it has none, or when you want the ack living in the controller's log where the rest of the program can act on it.

Questions

Can one button acknowledge every active alarm at once?

Yes. Give ack-all its own request bit in the same handshake register. When the controller sees it, set the ack flag to 1 in every record whose flag is still 0, then raise the echo. Some platforms document a controller acknowledgment tag for their built-in alarm viewer, which does the same job with no custom buttons; where that tag exists it is the first choice. Hold the ack-all request on until the echo returns, exactly like a per-alarm ack.

What happens if the panel loses power between request and echo?

The request lives in the panel's button state, so after a restart the panel writes it back as 0, and the controller drops the echo on the scan that sees the 0. Worst case the handshake ends half-done: a record whose ack flag is still 0. Nothing is corrupted, because the controller completes all eight fields of a record before advancing the index and raises the echo only after the flag is stored. Press Ack again.

Why stamp the time in the controller instead of on the panel?

The controller's real-time clock survives panel swaps and power cycles, and the log lives in controller memory. Stamps from the controller clock stay consistent even when a replacement panel powers up with the wrong time, which is common after a swap or a long shutdown. A log stamped from the panel clock can mix two clocks after one swap.

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