← Articles
HMI/9 min read/ views

The HMI Accepted the Setpoint. The PLC Didn't.

Why setpoint entry fails on the acknowledgment path, splitting display limits from PLC hard limits, and the tests that catch silent rounding.

HMISCADATagsAlarmsProject Notes

The failure is on the way back, not on the way in

An operator raised Dryer Zone 2 from 62.0 °C to 68.5 °C. The popup accepted the number, closed, and the field showed 68.5. The loop was under recipe ownership at the time, so the PLC dropped the write on the floor. Nobody noticed until QC flagged moisture on a whole shift of product.

Nothing in that chain was a bug. The HMI validated the range correctly. The PLC protected itself correctly. What was missing was the return leg: the screen never read back what the controller actually accepted.

That is the pattern behind most setpoint problems I've been called in for. Projects spend their effort on the entry path — min/max fields, decimal masks, confirmation popups — and leave the acknowledgment path as "write the tag and close the dialog". Treat the whole thing as a transaction with a result code, and half of these failures stop existing.

One Min/Max pair is doing too many jobs

Most projects carry a single Min/Max per tag and reuse it for the trend axis, the bar graph, the entry validation, and sometimes the alarm limit. It works until someone widens the trend axis to see a startup transient and quietly widens what an operator can type.

Split the intent:

Limit typeExampleUsed by
Display range0 to 100 %Bar graph, gauge, default trend axis
Operator entry range20 to 80 %HMI input validation
PLC hard limit10 to 90 %Final clamp or reject logic
Alarm thresholdHigh at 85 %Alarm logic
Engineering safe rangeSet by process/equipment designCommissioning review and MOC

The operator entry range should be narrower than the PLC hard limit, not equal to it. The gap is what lets maintenance and commissioning run equipment outside normal bounds without loosening normal operation — and it means an out-of-range entry gets a clear HMI message instead of a silent controller clamp.

Where the numbers live matters as much as what they are. Hard-coding 20 and 80 into the faceplate is the fastest way to end up with an HMI that disagrees with the PLC after the next logic change. Read the entry limits from controller tags and let the popup fetch them on open. It costs a few extra reads per popup and removes a whole class of drift.

What the popup owes the operator

An empty numeric box with an OK button gives the operator nothing to check their own typing against. At minimum, show the object and tag name (Dryer Zone 2 Temperature SP, not TIC_2042_SP), the current PV, the current setpoint, the engineering unit, the decimal precision, and the operator entry range. If the loop can be owned by something else, show who owns it right now — that alone would have caught the dryer case above.

Units deserve their own paragraph, because 75 is the most dangerous value on any screen. It is a plausible temperature in °C and in °F, a plausible speed in Hz and in rpm, and a plausible percentage. Put the unit next to both the current and the requested value, never just in the header. ISA-101.01 is worth reading on this point — its guidance on consistent units and precision across faceplates exists because operators pattern-match on the number and skip the label.

Say explicitly whether the value applies on OK or is staged for a later download. Operators who expect immediate application will keep pressing OK on a staged field.

Validate twice, and mean it

HMI validation is usability. Controller validation is protection. Neither replaces the other, because the HMI is not the only writer — OPC UA clients, historian-side scripts, engineering tools, and recipe downloads all reach the same tag.

The HMI should reject before it writes: empty or non-numeric input, more decimals than the instrument resolves, values outside the operator entry range, writes attempted in the wrong equipment mode, and writes from a user without the role. IEC 62443-3-3 SR 2.1 makes the last one an authorization-enforcement requirement rather than a UI nicety, and SR 1.1 means the identity behind it has to be a real user, not a shared operator login on a taped-up sticky note.

The controller re-checks hard min/max, permissives, interlocks that may have changed while the popup sat open, rate-of-change limits, and ownership. Note the timing problem in that list: a popup open for ninety seconds is working from a snapshot. The interlock state that was true when the dialog rendered is not necessarily true when OK is pressed.

Data type is the quiet one. IEC 61131-3 gives you REAL, INT, DINT, and the HMI does not always know which it is talking to. Write 68.5 to an INT and you get 68 or 69 depending on the driver's rounding, with no error anywhere. Same story on Modbus holding registers carrying a scaled integer — the register wants 685 for 68.5, and a driver misconfigured by a factor of ten will happily accept the write. Check the actual data type of every critical setpoint tag during FAT, not the type you assume from the faceplate.

In-range values that still hurt the process

A jump from 40 °C to 90 °C can be entirely within limits and still crack a heater element or scrap a batch. Four patterns, roughly in the order I reach for them:

  1. Ramp in the controller. Accept the target, move the working setpoint at a configured rate. Best default for thermal and pressure loops — the operator gets what they asked for, the process gets it slowly.
  2. Reject large jumps. Block if the delta exceeds a configured threshold. Simple, but it annoys operators during startup when large moves are legitimate, so pair it with a mode exception.
  3. Require elevated confirmation. Large changes need supervisor role or maintenance mode. Good on equipment where a big move is rare and always deliberate.
  4. Stage and apply. Let the operator set several related values, review them, then download together. Necessary when setpoints interact — changing zone 2 without zone 3 is worse than changing neither.

On batch equipment, be explicit about which layer is being edited. IEC 61512 / ISA-88 separates the master recipe, the control recipe, and the running batch for a reason, and an HMI that blurs them produces the worst kind of surprise: a correct change applied to the wrong scope, discovered three batches later.

Confirmation text should name the risk

Apply new setpoint? prevents nothing. It trains operators to click Yes. Name the object, the direction, and the size:

Change Dryer Zone 2 Temperature SP from 62.0 °C to 68.5 °C?

And when the move is large enough to matter:

This changes Dryer Zone 2 Temperature SP by +18.0 °C. Confirm ramp target?

If one value drives several downstream calculations, say so in the dialog. A conveyor speed setpoint that also shifts gap calculation, reject timing, and downstream rate expectation should admit that on screen.

Audit events you can still read six months later

Setpoint changed is not an audit event. It tells you nothing about whether an operator typed the value, a recipe downloaded it, or the controller clamped it.

A useful record carries the timestamp from synchronized system time, the user and role and workstation, the display name and internal tag path, the previous and requested values with units, the result (accepted, rejected, clamped, or staged), the rejection reason if there was one, the source (HMI screen, recipe download, engineering tool, remote client), and batch/lot/order context where it exists.

The result field is the one people leave out and then need most. IEC 62443-3-3 SR 2.8 asks for auditable events covering access control and control-function use; in regulated plants 21 CFR Part 11 pushes the same requirement harder, with old and new values both expected. Logging the request without the outcome satisfies neither, and it is exactly the gap that turns the dryer investigation into a week of work.

What actually breaks at FAT

  • HMI accepts one decimal, PLC tag is INT, value rounds silently.
  • Screen shows rpm, controller expects Hz or percent.
  • Min/max hard-coded in the HMI, drifted from the PLC constants two revisions ago.
  • Operator can type in manual mode, PLC ignores the value in auto, screen gives no feedback.
  • Recipe download overwrites a manual setpoint with no event.
  • A rejected write leaves the requested value displayed, so the screen shows a number the process never had.
  • Redundant HMIs hold different cached limits after a partial update.
  • Alarm limits get revised, entry limits do not.

None of these live inside one component. They are interface contract problems between HMI, PLC, historian, and recipe management — which is why they survive unit testing on each side and then show up on the third day of commissioning.

Ten tests per critical setpoint class

  1. Enter the minimum allowed value; confirm acceptance.
  2. Enter the maximum allowed value; confirm acceptance.
  3. Enter one step below minimum; confirm a clear rejection message.
  4. Enter one step above maximum; confirm a clear rejection message.
  5. Enter excess decimals; confirm whether it rounds or rejects, and that the screen shows which.
  6. Attempt the write with an under-privileged role.
  7. Attempt the write in the wrong equipment mode.
  8. Force a controller-side rejection and check the HMI message — an OPC UA client should surface the returned status, Bad_OutOfRange for example, rather than a generic write failure.
  9. Confirm the historian holds both previous and new values.
  10. Confirm the audit event carries user, station, tag, value, unit, and result.

Trend the process value, working setpoint, target setpoint, and output together while you run these. The trend shows immediately whether a value was applied, ramped, clamped, or ignored — which the popup, by design, does not.

One thing worth checking after any HMI update on a redundant pair: open the same faceplate on both stations and compare the displayed entry limits. Cached limit tables are the failure that survives every test above, because each station passes on its own.