UT_EVENT_LOG — Event log: what happened, and when
UT_EVENT_LOG — Event log: what happened, and when
Keeps the last N events (trips, stops, end reasons) with their time, newest
first, so a technician can read "what happened overnight" on the HMI or over SCADA,
also for the hours the comms were down. Feed it the records' stopReason,
lastFault and trips, or any event pulse of your own. It can keep the log over a
power cut.
An event is codes, not words: its stop reason (UT_STOP), its fault (UT_FAULT)
and a code of your own (INT). The HMI or SCADA shows the words
(UT_STOP_TEXT and UT_STATUS_TEXT give them for
a simple display). You size the storage: the block uses the Buffer and Sources
arrays you declare.
Pins
| Pin | Type | Default | What to wire | |
|---|---|---|---|---|
| in | Code |
INT | 0 | A code of your own (0 = none) |
| in | Stop |
UT_STOP | UT_STOP_NONE | A stop reason, e.g. Pump1.stopReason |
| in | Fault |
UT_FAULT | UT_F_NONE | A fault, e.g. Pump1.lastFault |
| in | New |
BOOL | FALSE | Rising edge: log (Code, Stop, Fault) now (any event pulse) |
| in | Count |
UDINT | 0 | Optional counter, e.g. Pump1.trips: each change logs (Code, Stop, Fault) |
| in | Src |
INT | 1 | Source number: the element of Sources this call uses |
| in | Clock |
DT | unwired | Real-time clock for the time stamps (e.g. UT_SCHEDULE's Data.localTime); unwired = the controller clock (UTC) |
| out | Events |
INT | Events in the log | |
| out | NewEvent |
BOOL | On for the scan in which an event was logged (a beep, a report trigger) | |
| inout | Buffer |
ARRAY[*] OF UT_EVENT | The log, newest first: as many slots as you declare | |
| inout | Sources |
ARRAY[*] OF UT_EVENT_SRC | One element per source: what was last seen from it. The block writes it | |
| inout | Saved |
ARRAY[*] OF UT_EVENT | The kept copy: declare it RETAIN, the same size as Buffer. Not used when the log is not kept (pass any one-element array) |
|
| inout | Data |
UT_EVENT_LOG_DATA | Settings and status (below) |
Record UT_EVENT_LOG_DATA
| Field | Type | Default | Meaning |
|---|---|---|---|
retained |
BOOL | FALSE | Keep the log over a power cut (in Saved) |
saveEvery |
TIME | T#12h | Kept: copy the log to Saved at most this often (the first event after a quiet spell at once). T#0s = not kept |
logPowerUp |
BOOL | TRUE | Log a power-up event (source 0, no codes) at every power-up |
cmdClear |
BOOL | HMI: empty the log (and Saved, at once). Acts once, on its rising edge |
|
count |
INT | Status: as Events |
|
logged |
UDINT | Status: events logged since power-up | |
lost |
UDINT | Status: events pushed out of a full log since power-up | |
wrnConfig |
BOOL | Status: Buffer has no element, a negative saveEvery, or Saved smaller than Buffer while kept |
|
wrnSrc |
BOOL | Status: a call this scan had a Src outside Sources (that call is ignored) |
Slot UT_EVENT
| Field | Type | Meaning |
|---|---|---|
seq |
UDINT | Running number of the event (0 = an empty slot). Carries on over a power cut when the log is kept |
stamp |
DT | When it happened (Clock) |
src |
INT | The source (the Src of the call; 0 = the log itself: the power-up event) |
code |
INT | Your own code (the Code pin; 0 = none) |
stop |
UT_STOP | The stop reason (the Stop pin) |
fault |
UT_FAULT | The fault (the Fault pin) |
UT_EVENT_SRC (code, stop, fault, count, newPrev, seen) is the block's
memory of each source; don't write it.
How it works
- Call it once per source per scan, all calls on the same instance,
Buffer,
Sources,SavedandData, each with its ownSrc(as
UT_MSG_QUEUE). Give each call its own unconditional rung in
Ladder or FBD. The order of the calls is the order of events that come in the same
scan. - A call logs one event when, for its source:
Newhas a rising edge, orCodechanges to a value other than 0,Stopto a reason other than
UT_STOP_NONE, orFaultto a fault other thanUT_F_NONE, orCountchanges (a trip counter: every trip is logged, also the same one again).
- One of these in a call gives one event, with the call's
Code,StopandFault. - A pin a call leaves unwired never takes another call's value: the block sets its
pins back to their defaults after each call. - What a source shows at its first call after a power-up is its starting point,
not an event (as a command never acts on the first scan). The power-up event
(source 0, no codes) marks that moment. - Newest first: the first element of
Bufferis the newest event; a new one
moves the others down, and a full log drops the oldest (counted inlost). - Kept over a power cut (
retainedTRUE andsaveEveryabove 0):Savedgets
a copy of the log. The first event after a quiet spell (no copy forsaveEvery) is
copied at once, with any others of the same scan; later ones wait until
saveEveryhas passed since that copy, so a burst of events writes the
controller's storage once. The power-up event is copied at once and starts no
wait (one copy per power-up), so the first trip after a power cut is kept at once
too. At power-up the log is read back fromSaved, with a new power-up event on top,
and the running numbers carry on. With the default 12 h an event after the first
of a busy spell can be lost by a power cut within 12 h; a shortersaveEverykeeps
more but writes the storage more often (see
conventions). - Not kept (the default, or
saveEveryT#0s): the log starts empty at every
power-up (with the power-up event iflogPowerUp), andSavedis not touched. cmdClearempties the log and, when kept,Savedat once.- The block is called many times a scan;
NewEventstays on for the rest of the
scan in which an event came, andcmdClearand the copy act once per scan.
Using it
(* Saved is declared RETAIN, the same size as Log *)
Ev(Code := 0, Stop := Pump1.stopReason, Src := 1, Clock := Sched.Data.localTime,
Buffer := Log, Sources := EvSrc, Saved := LogSaved, Data := EvCfg);
Ev(Fault := Pump1.lastFault, Count := Pump1.trips, Src := 2, Clock := Sched.Data.localTime,
Buffer := Log, Sources := EvSrc, Saved := LogSaved, Data := EvCfg);
Ev(Stop := Valve1.stopReason, Src := 3, Clock := Sched.Data.localTime,
Buffer := Log, Sources := EvSrc, Saved := LogSaved, Data := EvCfg);
with Log : ARRAY[1..20] OF UT_EVENT; EvSrc : ARRAY[1..3] OF UT_EVENT_SRC; EvCfg : UT_EVENT_LOG_DATA := (retained := TRUE); and
VAR RETAIN LogSaved : ARRAY[1..20] OF UT_EVENT; END_VAR. Wire Code in at least
one call (0 when you have no code of your own): the editor's check wants a
block's first input assigned.