Show a past day's production on an HMI from a PLC table

7 min read · Published November 13, 2026

A live panel can enter a date and show a result; the records themselves live in the PLC. Save one date-and-total pair per production day in retentive PLC memory, and an indexed table lookup returns any stored day's total from a date typed on the panel. A 31-record window covers a month of production days in about 64 registers.

A panel can enter a date and show a number; the dated history has to live in the PLC. Save one date-and-total pair for each production day in retentive PLC memory, let the operator type a date on the HMI, and let the PLC find that date in its table and publish the total stored beside it. A 31-record table answers any date in the last month of production days and fits in about 64 retentive registers. This article sets out the date encoding, the capture at a fixed day boundary, the indexed scan that finds the record, and the checks to run before you trust the first query.

Where the history lives

A live counter answers one question: how many units have passed so far. A finished day's record exists only if something saved it, so the PLC builds it once per boundary and keeps it in its own memory. The panel keeps two jobs: enter a date, show the answer.

Plan the layout before writing code. Two parallel arrays hold the table: one key register and one total register per record, one record per position, the same one-record-per-position pattern as storing PLC timing presets in one indexed data table. Thirty-one records cover a full month of production days; when record 32 arrives it overwrites the oldest, and anyone who needs older numbers exports them first. The housekeeping for that window is a write pointer and a previous-boundary reading, 64 retentive registers in all.

What you need

  • A PLC with retentive data registers and indexed or pointer addressing into its data table. An indexed load instruction of this kind names a V-memory source address and offsets it by the value in the first stack location; any PLC with the same kind of pointer indexing runs this same design.
  • Numeric entry objects on the panel that write day, month and year into PLC registers when the operator presses Enter.
  • A correct PLC real-time clock, because every record's key comes from it. After a long shutdown, set the PLC clock from the operator panel and spot-check it against the wall calendar.
  • The production counter itself, and one defined boundary for the production day.

Turn the date into one number

Store each date as a single unsigned 16-bit key:

key = (year - 2000) × 372 + (month - 1) × 31 + day

The 372 is twelve month-slots of 31 days. The packing gives every date a unique number, needs no leap-year or month-length logic, and keeps dates in order, which is all a table search needs. The largest unsigned 16-bit value is 65,535, and 31 December 2175 lands at key 65,472, so one register holds the scheme for every date through 2175. Because 1 January 2000 gives key 1, a stored key of 0 marks an empty slot.

Validate the entry before searching: day 1 to 31, month 1 to 12, and an entry key no larger than today's key, which rejects future dates because the packing is ordered.

Steps from an empty table to a working lookup

  1. Fix the boundary. Choose the moment a production day ends and use it for every record. A 6:00 a.m. boundary at shift change keeps the night shift's output on the day that produced it. Midnight works too; pick one boundary and stay with it.
  2. Snapshot the counter at the boundary. On one scan, copy the cumulative counter into a retentive register. The finished day's total is this reading minus the previous boundary's reading, the same discipline as saving the previous count before a PLC counter reset. Load the register with the current reading at commissioning so the first stored total is a full day.
  3. Fire the write once. Trigger steps 2 and 4 from a rising edge, for example the clock reading 6:00 a.m. together with a captured-today flag that clears a minute later. A condition that stays true would rewrite the same record all morning.
  4. Write the pair and advance the pointer. Store the key, computed from the PLC clock with the formula above, and the total into slot W_ptr. Add 1 to W_ptr and return it to 0 when it reaches 31; the slot it points to after the wrap holds the oldest record. Check W_ptr is 0 to 30 before every write.
  5. Build the entry path. Three numeric entry objects write day (1 to 31), month (1 to 12) and year into three entry registers on Enter only, exactly the mechanism that moves an HMI numeric entry into PLC memory on Enter. Give the lookup its own registers, separate from anything the machine's output logic acts on.
  6. Search on Enter. The PLC computes the entry key, clears the found flag, then walks slots 0 to 30. At each slot it reads the stored key by offsetting the key array's base address with the slot number and compares it with the entry key. On a match it reads the total at the same slot in the total array into the result register and sets found = 1.
  7. Publish result and status. The panel shows the result register only when found = 1, and shows a 'no record for this date' message when found = 0. The flag clears at every new entry, so an old number never sits where a new answer belongs.
  8. Make it survive power cuts. Keys, totals, write pointer and the boundary reading all go in retentive registers, and you confirm in your PLC's documentation how your model holds them through a power failure, whether by battery or non-volatile memory, because register contents that depend on a weak or missing battery can be lost on an outage. After any outage, run the checks below before trusting the totals.

Example: one month of records on a molding line

The line turns out about 2,400 units a day and the boundary is 6:00 a.m. The table was commissioned on 13 February 2026 and holds 30 records by 15 March: slots 0 to 15 hold 13 to 28 February (keys 9,716 to 9,731), slots 16 to 29 hold 1 to 14 March (keys 9,735 to 9,748). The write pointer sits at 30.

At the 15 March boundary the cumulative counter reads 1,208,442 and the previous-boundary register holds 1,206,042:

day total = 1,208,442 - 1,206,042 = 2,400 units

The key for 15 March 2026 is (2026 - 2000) × 372 + (3 - 1) × 31 + 15 = 9,672 + 62 + 15 = 9,749. The pair (9,749, 2,400) goes into slot 30 and the pointer wraps to 0. The table is now full.

The operator asks for 15 March 2026. The PLC computes 9,749, matches slot 30, and publishes 2,400 with found = 1. Decision: the panel shows 2,400 units for that date.

The operator asks for 1 February 2026. The key is 9,672 + 31 + 1 = 9,704, and no slot holds 9,704, so found stays 0. Decision: the panel shows the no-record message and no number, because a missing day and a real zero-unit day are told apart by the flag.

The next boundary, 16 March, has key 9,750 and writes into slot 0, replacing 13 February at key 9,716, the oldest of the 31 records. Decision: no one archives that record by hand; the table rolls to the next slot on its own.

Recommendation: run a 31-record table in retentive registers, capture once per day at one fixed boundary on a one-shot edge, encode dates with the ×372 key, and clear the found flag at every new entry. Keep the panel to entry and display. If a single day's count can outgrow a 16-bit register, store totals as 32-bit values across two registers and step two registers per record through the total array.

Check it before the crew relies on it

  • Enter two dates you know are in the table and confirm each returns its own total, never the other's.
  • Enter a date with no record and confirm the no-record message appears and the previous total has left the screen.
  • Check one boundary by hand: read the counter at 6:00 a.m., subtract the stored boundary reading, and compare the result with the total in the table.
  • Cut power under your site's approved procedure, restore it, and confirm the keys, totals, pointer and boundary reading all survived; then query the last record captured before the outage.
  • Confirm the wrap once: with the table full, the next capture lands on the oldest key in the table.

When a returned number looks wrong

  • Yesterday's total appears for today's date: the found flag was not cleared before the search, or the panel displays the result register without checking the flag.
  • A zero appears for a date with no record: the display ignores the status flag, so a real zero-unit day and a missing day look the same.
  • One day's total is implausible: the boundary snapshot landed after a counter reset or fired twice in one day; compare the two boundary readings around that day and check the one-shot edge condition.
  • Late-month dates miss while early-month dates hit: a month term in the key formula is off by one slot; check the ×372 and ×31 terms against the example's keys, 9,716 for 13 February and 9,735 for 1 March.

When the crew also needs the live count

The table answers the historian's question; the running count during a shift is a different job, shown straight from a PLC counter value where operators can see it. For a bigger crew-facing board, our shop-floor screens play slides from a memory card or content from your own Android app; they are not HMIs and take no PLC link, so an app or a refreshed slide carries the number to them.

Questions

How many registers does a 31-record production table need?

31 key registers, 31 total registers, one write pointer and one previous-boundary reading: 64 retentive registers in the simplest layout. Each extra record costs one key and one total, so a 62-record window uses 124 array registers with the same two housekeeping registers. Size the window to the longest stretch anyone actually asks about.

What if a single day's production can pass 65,535 units?

65,535 is the largest unsigned 16-bit value, so store each total as a 32-bit unsigned value across two registers, good to 4,294,967,295. Keep the keys in single registers and step two registers per record through the total array. The boundary subtraction works unchanged on the wider value.

Can the HMI panel store the date-and-total records instead?

This design puts them in the PLC because the PLC already owns the counter, the clock and the search. A panel-side copy would need retention that survives power cuts and project downloads, a search of its own to run the lookup, and a second table kept in step with the PLC. One table in one place avoids all three.

Which registers must survive a power cut?

All four storage parts: the 31 keys, the 31 totals, the write pointer and the previous-boundary counter reading. A lost pointer sends the next 31 writes over the oldest records again; a lost boundary reading makes the first total after startup wrong; a lost key leaves a total sitting in the table that no date can find.

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