HMI alarms write a record when a tag changes, so a steady bool logs one line per trip and nothing in between. To log one record every 60 seconds, generate a pulse per interval with a self-resetting PLC timer, alarm on the pulse's ON edge, and embed the bit's live state in the alarm message text. Encode the bit as a 0/1 register when the deliverable is a graph.
An HMI bit alarm has exactly two events to offer: a line when the bit turns on and a line when it turns off. While the bit holds steady, the tag produces no new value, the alarm has nothing to write, and the log sits still. That is why an alarm log looks empty next to a trend graph drawing the same bit minute by minute: the graph redraws the level, the alarm records the edges.
To get one timestamped record every 60 seconds, manufacture the event yourself. A self-resetting 60-second timer in the PLC emits a short pulse once per cycle, the HMI alarm watches that pulse and fires on its ON edge, and the bag monitor's live state rides in the alarm message text. For a graph, encode the bit as a number and trend the number. The sections below give the logic, the alarm settings, the arithmetic and the tests.
Why a bit alarm goes quiet between changes
Alarm engines in HMI software evaluate a tag against an alarm condition and write a record when the condition turns true. A bool tag has exactly two transitions to offer, so a bit alarm fires once when the bit turns on and once when it turns off. Vendors' alarm and event guides describe alarms the same way: an alarm is an event raised by a condition on a tag, not a sampler that wakes up on its own schedule. The empty stretches in your log are the documented behavior working as intended, and the missing lines have to be manufactured as tag changes.
A trend graph looks richer only because the pen redraws the stored level at its own scan rate, and pens have redraw limits of their own; if yours stalls at a fast sample rate, that is the subject of why an HMI trend graph will not update every half second. The one-shot behavior is the same edge trigger that fires an HMI event once when a PLC alarm bit turns on and then waits for the next edge. The alarm database will not wake up on a schedule to sample a steady bit, so the schedule has to arrive as a changing tag from the PLC.
Symptoms and what each points to
- One line per trip and one per clear, nothing between. The alarm is on the bag monitor bit itself and the bit is steady; no periodic trigger exists in the chain yet.
- Two records per minute, about half a minute apart. The trigger is a clock comparison such as 'seconds below 30', which is on for 30 s and off for 30 s and crosses twice per minute.
- Records missing at random minutes. The trigger pulse is shorter than the HMI's poll interval, so the HMI reads the tag just before it sets and just after it clears and never sees the ON state.
- Two records per cycle, one on the pulse rising and one on it falling. The alarm condition watches both transitions; set it to the ON transition only.
- Graph line flat at one value all shift. The mapped register never changes; watch the register in the PLC monitor while you force the bit on and off, and check both branches of the mapping logic.
Build the 60-second trigger in the PLC
The trigger is a self-resetting cycle timer plus a pulse stretch. Names, types and initial values in the block below are illustrative; use your PLC's own timer instructions and syntax:
(* Types: line_running, bag_ok, sample_pulse are BOOL, FALSE at power-up.
cycle_timer and pulse_hold are on-delay timers. *)
cycle_timer(IN := line_running, PT := T#60s); (* 60 s cycle *)
IF cycle_timer.done THEN
sample_pulse := TRUE; (* rising edge fires the alarm *)
cycle_timer.reset := TRUE; (* restart now, cadence stays 60 s *)
END_IF;
pulse_hold(IN := sample_pulse, PT := T#2s); (* stretch the pulse to 2 s *)
IF pulse_hold.done THEN
sample_pulse := FALSE; (* fall is ignored by an ON-edge alarm *)
END_IF;
Set the preset in the timer's own time base: 60 s is 60000 on a millisecond timer and 60 on a timer that counts seconds. A time base read wrong turns the 60-second plan into a 60-millisecond one, the same conversion trap covered in convert HMI minutes to PLC timer units.
Make the pulse wider than the HMI's poll interval. HMI polls commonly run between 100 ms and 1 s, and an alarm can only react to a value the HMI has actually read. A pulse one PLC scan long, a few milliseconds, can set and clear between two polls, and that minute never reaches the file. Two seconds covers it: a pulse wider than one poll interval must be sampled by at least one poll, whatever the phase between the two clocks.
Point the alarm at sample_pulse, not at bag_ok. Set its condition to the ON transition, the rising-edge or 'bit on' condition your HMI's alarm setup offers. An any-change condition also fires on the fall and doubles the file to 120 records an hour. Put the live state in the alarm message text the way you would print any tag value into a message string, so a line reads bag monitor = RUN or bag monitor = OFF; the history stamps each record with the date and time.
The records collect in the alarm history, the same timestamped store that can record job completion time with an alarm history. Aim that history at a file destination in the HMI's logging setup, then open the file and look at it; the alarm banner on the screen and the stored log are different things.
| Deliverable | Build this | What you get |
|---|---|---|
| Fault record only | Keep the alarm on bag_ok, both edges | One line per trip and per clear |
| One record per 60 s in a file | 60 s cycle timer, 2 s pulse, ON-edge alarm on the pulse, state in the message text | 60 records per hour, 1440 per day |
| A graph of the state | Map bag_ok to a 0/1 register and trend the register | A step trace on screen, no file |
| Graph and file | Build both chains, test each destination | Trace plus file |
Recommendation: keep the existing alarm on bag_ok for genuine trips, and add the PLC-built trigger when the file must show one line per interval: the 60 s self-resetting cycle timer that restarts the moment the pulse sets, the 2 s pulse stretch, an ON-transition alarm on sample_pulse with the live state in the message text, and the history pointed at the file. Map the bit to a 0/1 register and trend it when the deliverable is a graph; build both chains when you need the trace and the file.
Map the bit to a number for a graph trace
A trend pen draws a number, so give it one. Write the mapping in the PLC and trend the result:
// trend_value : INT, 0 at power-up
IF bag_ok THEN trend_value := 1 ELSE trend_value := 0 END_IF
Pick values that sit inside the pen's scale: 0 and 1 on an auto-scaled axis, 0 and 100 if the pen reads percent. This is the same one-bit, two-values mapping that shows two text states on an HMI from one PLC bit, with numbers in place of text. You can also build it in the HMI with two event entries, one writing 1 to an internal tag when bag_ok turns on and one writing 0 when it turns off, then trend that internal tag. The PLC register version is easier to watch in PLC monitor mode, and it sidesteps the screen-change resets described in why a real time graph clears when you change HMI screens.
The trace answers where the state sat and when it stepped. The alarm file answers the requirement of one timestamped line per interval. Keep the two deliverables straight when the request comes back as 'a graph that logs'.
Example: one 10-hour shift, 600 records
Scenario: the collector runs one 10-hour shift, the bag monitor never trips, and the file must carry one record every 60 s.
Records per shift: 10 h × 3600 s/h = 36000 s, and 36000 s ÷ 60 s per record = 600 records. Each record is a timestamp plus the state text, call it 40 characters: 600 × 40 = 24000 characters, about 24 kB per shift. A three-shift day writes 1800 records, 1800 × 40 = 72000 characters, 72 kB, and a month of single shifts lands at 600 × 30 = 18000 records, roughly 720 kB. Storage is trivial; the value of the arithmetic is the end-of-shift check it gives you: the file should hold exactly 600 lines.
Now the arithmetic of the clock comparison. 'Seconds below 30' is on for 30 s and off for 30 s, so it crosses twice a minute and an any-change alarm writes 2 records/min = 120 records/h, double the 60 records/h the interval asks for. With the alarm set to the ON edge the comparison does produce one record per minute, but only on a controller whose program can read the real-time clock's seconds register, and every record is pinned to the clock's wrap. The self-resetting timer needs no clock and its cadence is yours: set the preset to 300 s and the same chain writes 36000 ÷ 300 = 120 records per shift.
Pulse width inside the same example: a 2 s pulse against a 1 s poll means every pulse covers at least one poll moment, so no interval is missed. Shrink the pulse to one scan, say 10 ms, and a 1 s poll can straddle it; that minute never reaches the file, and the shift ends with 599 lines where the arithmetic predicts 600.
Checks before you trust the file
- Run five minutes with the bit untouched: 300 s ÷ 60 s = 5 records expected. Fewer than 5 means a missed pulse; widen the pulse to 4 s and re-run.
- Open the file at its destination, not the alarm banner. Every line needs a date-time stamp and the state text.
- Force bag_ok off and on between two records: the next line must carry the new state. If the state text never follows the bit, the message string is bound to the wrong tag.
- Read two successive timestamps: they sit 60 s apart. A steady 62 s spacing means the cycle timer restarts only after the pulse ends; move the reset to the moment the pulse sets. A 120 s gap is a missed pulse.
- Count the lines at shift end against the arithmetic: 600 records for a 10-hour shift at 60 s.
One safety point: this file is a record, and the bag monitor's trip action must stay in the PLC where it alarms or stops the collector directly; never route a protective response through the HMI log.
Questions
Can I set the HMI alarm itself to re-fire every 60 seconds on a steady value?
Most HMI alarm engines evaluate a tag when its value changes, so a repeat or re-arm setting, where the HMI offers one, still needs a changed value to react to. The pattern that works on any HMI keeps the tag changing: write the pulse from the PLC and let the alarm fire on each rising edge. If your HMI does offer a repeat interval on bit alarms, time it with a stopwatch before trusting it, because the alarm's repeat behavior and the poll rate are separate settings.
My PLC has no real-time clock seconds register. What do I use instead?
You do not need one. A self-resetting 60-second cycle uses only an on-delay timer, which every PLC has. A real-time clock comparison such as 'seconds below 30' is the weaker option here: it toggles twice a minute, it depends on the seconds register being readable from the program, and it pins every record to the clock's wrap. The timer version pins the cadence to a preset you choose, and changing that preset changes the interval.
How do the records get out of the HMI as a CSV file?
Point the alarm history at a file or logging destination in the HMI's configuration instead of leaving it only on the alarm banner, and export from the HMI's file or logging menu. Most HMIs write one row per record with a timestamp and the message text, which carries the state you embedded. Check the file after the first hour: one row per 60 seconds with a state column that follows the bit means the whole chain works.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.