Selecting Ignition readValues for Deterministic PLC Data

Daniel Price7 min read
Best PracticesOPC / OPC UAOther Manufacturer
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Ignition receives the PLC trigger through its subscribed tag path, but the payload may still be represented by older values in the tag cache. Follow the packet: the trigger starts the transaction, a direct OPC read retrieves the held payload, the database stores it, and an acknowledgement releases the PLC to publish the next payload.

Which read approach fits this transaction?

Approach Reads from Path input Deterministic after trigger? Best use
system.tag.readBlocking() Latest values delivered to the Ignition tag system Ignition tag paths No. Payload values may have entered the cache before the trigger change. Reading cached tag state when transaction ordering is not required
system.opc.readValues() OPC items through the configured OPC connection OPC Item Paths Yes, when the PLC writes the complete payload before changing the trigger and holds it until acknowledgement Reading a transaction payload after detecting its trigger

Use system.opc.readValues() for the two payload registers. It initiates the payload read after the gateway has observed the trigger instead of returning whatever values happen to be in the tag cache. The method accepts OPC Item Paths, not Ignition tag paths. Payload tags are therefore optional if those values serve only this database transaction.

The direct read provides ordering, but not magic atomicity. The PLC must finish writing both registers before publishing the trigger, then leave both registers unchanged until Ignition acknowledges that trigger. If the PLC changes either register while the read is in progress, no client-side choice can guarantee a coherent pair.

Where does the data path start and stop?

Start at layer one. A stable physical link and functioning PLC-to-OPC connection must exist before script logic can distinguish a stale cache value from a failed read. Check connection state and item quality first; a database row created from bad-quality values is not a successful transaction.

Hop Data or request Failure to look for
PLC memory PLC writes both payload registers, then changes the trigger Trigger changes before the payload is complete, or payload changes before acknowledgement
Physical network and OPC connection Subscription carries the trigger; the direct read carries the payload request and response Disconnected link, delayed response, or bad item quality
Ignition gateway Gateway event detects the trigger and calls system.opc.readValues() Wrong OPC Item Paths, blocked execution, or unchecked read results
Database operation Named query stores the trigger identity and payload Database failure followed by a premature acknowledgement
Acknowledgement path Ignition echoes the completed trigger value to the PLC Asynchronous or early write releases the next payload

No address, port, or timeout value is universal here. Read the configured OPC connection, device diagnostics, and item configuration for those installation-specific fields. Changing protocol settings before checking item quality and connection state obscures the first failed hop.

Why can a blocking tag read return the wrong payload?

system.tag.readBlocking() blocks the script until Ignition returns tag-system results; it does not make a new request to the PLC. Subscription updates for the trigger and payload travel independently through acquisition and tag processing. The trigger event can therefore execute while one or both payload tags still contain values delivered during an earlier acquisition.

The word “blocking” describes script execution, not the origin or freshness of the data. Blocking a cache read cannot impose PLC transaction order. A direct OPC read changes the ordering: the gateway observes the trigger first and then sends the payload request.

A latched Boolean trigger also carries no transaction identity beyond its current state. Prefer an incrementing integer or microsecond timestamp as the trigger and copy the same value into a paired acknowledgement tag after the database operation succeeds. The PLC compares trigger and acknowledgement: equality permits the next payload, while inequality means the current payload remains owned by Ignition.

Which event scope should run the transaction?

Event location Blocking-work behavior Recommendation
Tag value-changed script Runs in a built-in pool with only three threads by default; a stalled OPC or database call can occupy a shared worker Do not place this blocking transaction here
Gateway tag change event Provides the appropriate gateway scope for OPC access, database work, and acknowledgement handling Use this event for the trigger

system.opc.readValues() can stall a thread for a substantial time while the OPC request completes or fails. Combining it with a database call makes a tag value-changed script especially unsuitable. A gateway tag change event keeps this transaction out of the small shared tag-event pool.

Filter initialization and unchanged values according to the gateway event’s supplied context. Treat a repeated trigger identity as a retry, not automatically as a new record. Storing the trigger identity with the payload gives the database operation a transaction key and makes retry behavior explicit.

How should the handshake procedure run?

  1. In the PLC, write both payload registers completely.
  2. Publish a new incrementing integer or microsecond timestamp in the trigger tag.
  3. Hold the payload and trigger unchanged while trigger and acknowledgement differ.
  4. In the gateway tag change event, detect the new trigger and build the list of payload OPC Item Paths.
  5. Call system.opc.readValues(itemPaths=itemPaths). Reject the transaction if any required item has bad quality or the read fails.
  6. Map the returned values and trigger identity into the database parameters, then execute the project named query.
  7. Only after database success, echo the trigger identity to the paired PLC acknowledgement tag.
  8. Have the PLC wait for trigger and acknowledgement to match before writing another payload.
values = system.opc.readValues(itemPaths=itemPaths)
# Check every required result before storing the payload.
# Run the database transaction.
# Echo the completed trigger value only after database success.

Either system.opc.writeValues() or system.tag.writeBlocking() can perform the acknowledgement. Choose by path type: OPC Item Paths for the OPC write, or an Ignition tag path for the tag write. Use a blocking acknowledgement in this sequence; system.tag.writeAsync() can let the script finish without confirming that the acknowledgement operation completed.

Do not wipe the payload registers merely to indicate completion. Clearing them consumes bandwidth and creates another state transition that the PLC and gateway must coordinate. Echoing the trigger value identifies exactly which payload completed and leaves the payload available for diagnosis until the PLC starts the next transaction.

How do you verify the complete path?

  1. Run a controlled transaction with a known trigger identity and two distinguishable register values.
  2. Confirm the gateway observes the new trigger before it starts the direct OPC read.
  3. Confirm both returned OPC items have acceptable quality and match the PLC’s held payload.
  4. Confirm the database contains one row with the same trigger identity and both expected values.
  5. Confirm the acknowledgement changes only after database success and equals the trigger.
  6. Force an OPC read or database failure during a controlled test. Verify that no acknowledgement is sent and that the PLC continues holding the payload.
  7. Repeat with consecutive transactions and verify that each trigger identity maps to one coherent payload and one acknowledgement.

If validation fails, follow the packet from the first missing transition. A missing trigger points to the PLC, subscription, or physical connection. A received trigger followed by bad read quality points to the OPC item path or device connection. Correct OPC values with no database row point to parameter mapping or the named query. A valid row with no matching acknowledgement points to the configured write path.

FAQ

Can I use system.tag.readBlocking after the PLC trigger?

You can call it, but it reads the Ignition tag cache and may return payload values acquired before the trigger. Use system.opc.readValues() when the payload must be requested after the trigger event.

Does system.opc.readValues accept Ignition tag paths?

No. It accepts a list of OPC Item Paths. Ignition payload tags are unnecessary when the values are read only for this transaction.

Can I run the direct OPC read in a tag value-changed script?

Do not run this blocking transaction there. Tag value-changed scripts use a built-in pool with only three threads by default, and a stalled OPC or database call can occupy one of them.

Does the PLC need to clear the payload after every read?

No. Use an incrementing integer or microsecond timestamp trigger and echo the completed value to an acknowledgement tag. The PLC may publish the next payload when trigger and acknowledgement match.

How do I verify the PLC payload was stored correctly?

Check that the direct OPC results have acceptable quality, the database row contains the same trigger identity and both held register values, and the acknowledgement changes only after database success. Confirm the PLC does not publish the next payload until acknowledgement equals trigger.

Back to blog