[BUG] v8.1.5 AB Logix driver - Tags that are written and reset by PLC in 1 scan remain


I’m using the Logix driver to talk to a firmware 32 AB logix PLC (L82ES/B)

When I try to write to tags via bindings that the PLC sees then immediately resets (for example a manual mode command which is used by the PLC to change the mode of a device and then immediately reset the command), the value of the command tag stays high and does not get updated to the reset value.

  1. Ignition write tag to True via bidirectional tag binding on component
  2. PLC sees True, does stuff with it, then resets True tag back to False within a single PLC scan
  3. Ignition tag remains as True indefinitely effectively disabling the tag from being written to again via a binding.

Writing to a tag that is also written to by the PLC is inherently a race condition.

  1. The tag is false.
  2. You write true. True is written to the PLC. Ignition tag value is now true.
  3. The PLC writes false.
  4. Ignition driver polls, sees the value is still false, nothing is reported to the OPC client.

You can work around this by putting tags written to by 2 sources into an OPC polled mode tag group or you can rewrite your PLC logic so that each entity writes to its own tag.

This race condition happens with any compliant OPC server where subscriptions are value/quality only. It’s easily observable even with the built in Siemens 1500 OPC server for example.

edit from the future: Ignition 8.1.10 has a new OPC UA tag group property called “Include Timestamp-Only Changes”. When enabled the OPC UA items are created with a filter that requests value/quality/timestamp changes, not just value/quality. When used with the Ignition OPC UA server the race condition no longer exists. With other servers your mileage may vary.

Hmm, I see the issue… I just played around with the tag group settings and changed the settings for read after write and optimistic writes and seem to have alleviated the issue for now:


Previously I had read after write set true and optimistic writes off. As you say, the read after writing would have been too slow to pick up that the value actually did go high and just read 0, unchanged. Turning this off and enabling optimistic writes with a timeout of 1s gives it the time it needs to assume it’s high and then timeout and read again 1s later to see that it’s actually been reset.

Thanks for the insight into the actual issue though! I’ll add some info around this to our company Ignition tips

I’ve been harping on this for years, Nick. I can’t believe you’ve missed them:


@nminchin @pturmel

This race condition came up in an OPC WG meeting today and it got me taking a look at how Ignition behaves again… and I’m either going crazy or the tag write behavior has changed, because it looks like we do not set the tag value after a write to an OPC tag, it just passes through and only updates if/when a value comes back from the subscription. Same whether I write from script, tag browser, or bi-di binding. This looks like the correct behavior…

It is the correct behavior. You taught me this some years ago. Nick @bmeyers doesn’t like it.

1 Like

Right, it’s the correct behavior for a UI that is updated by OPC subscription, but it makes the race condition I’ve been copy/pasting around for the last year incorrect.

You write true. True is written to the PLC. Ignition tag value is now true.

The bold part doesn’t happen.

Unless. Unless you use read-after-write, and the read catches the written value before the PLC resets it. Read-after-write in subscribed mode is dangerous.

But now I’m confused why it seemed like this race condition was happening often-ish. Is everybody using read-after-write for handshakes?

It is a real race without read-after-write.

Read-after-write shortens the interval, but if the logic is primed to clear instantly, it still won’t help.

That’s a different scenario. I’m not talking about missing some transient value because polling is polling and that’s reality, I’m talking about a scenario I thought some people were seeing where the value in Ignition no longer matches the value in the PLC. Which can absolutely happen with read-after-write, it’s just a variation of the above:

  1. tag is false
  2. you write true, true is written to the PLC
  3. read-after-write sees true in the PLC, now the Ignition tag value is true
  4. PLC logic resets the bit to false
  5. next OPC sample/poll happens, sees false, reports no change since last poll that also saw false

edit: except now I’m making the same assumption about the read-after-write implementation I was about write, and that turned out to be wrong, so off I go to check and see if that actually updates the tag value or not…

What happens when 3 & 4 are swapped? PLC resets to false before read-after-write? No change report? (Which is what I suspect happens with many users.) And keeping in mind that many writes’ status codes are ignored…

I just confirmed the value acquired by read-after-write is applied to the tag, as long as it has a newer timestamp.

So if 3 and 4 are swapped everything works out in your favor, your tag has the correct value. But if you catch the written value before the PLC resets it then you’re left with the wrong value in your Ignition tag until it changes again, if ever.

Ah-ha, I found my original post where I described the race condition, and in that version it was explicitly about read-after-write:

If Ignition isn’t the only thing that will write to a given tag then I’d recommend not using the “Read after write” setting because there’s a somewhat dangerous race condition and it’s more likely to occur when using slow scan classes / subscriptions.

Imagine, if you will, a boolean tag in a 30 second scan class.

  1. driver polls value=false, next poll in 30s
  2. user writes value=true to tag, read-after-write confirms value=true, ignition tag now set to true
  3. some seconds later, before the next poll, an external source (script, PLC logic, whatever) sets the value to false again
  4. driver eventually polls again, reads value=false, no change since last poll, so no data change is sent to client

The tag is now false in the PLC but true in Ignition.

from Indirect Tag Delay - #9 by Kevin.Herron

I somehow telephoned my own race condition description into something inaccurate since then.

You’ve lost me. I would have thought it would play out like this:
0. driver polls value=false, next poll in 30s

  1. user writes value=true to tag, read-after-write confirms value=true, ignition tag now set to true
  2. some seconds later, before the next poll, an external source (script, PLC logic, whatever) sets the value to false again
  3. driver eventually polls again, reads value=true, change from last poll, so data change is sent to client

change in (3). Why would (3) in your version read as false if read-after-write specifically read the value in as true?

The polling/sampling occurring in the driver (or any other OPC server) is divorced from everything else. It has no idea about the read that occurred and even if it did it’s not allowed to report values for the subscription faster than the requested sampling interval.

Hmm, ok.
I just dug up my notes and these are the settings that I told myself to use:

Setting Value
Read After Write false
Optimistic Writes true
Optimistic Write Timeout (MS) 1000 (or similar)

Optimistic writes with a short timeout will mean that tags that are written to in Ignition that are reset by the PLC won’t* become stale (*that i’ve seen)

Oh wait, I could have just scrolled up to see those :slight_smile: They’re more spelled out here I guess

Optimistic Writes enabled will cause the Ignition tag to immediately update with the value of the write, then wait up to the timeout for that value to come in via the subscription, rolling back if it doesn’t happen.

Without it enabled the Ignition tag retains its original value until a new one comes in from the subscription, if ever.

What this fixes though is tag writes to such tags not appearing in the audit log. I was finding that some tag writes just weren’t appearing at all in the audit log and it was due to a combination of the PLC immediately writing the tag back to false and using read-after-write. Optimistic writes holds it at true for the timeout period which give the audit log a chance to see it and record it, at least that’s how it seems to be working.
At least I think that was the issue I was having with it… (it was a year ago) I would have thought that the write itself would issue the audit to log though

That’s what I’d expect also.

Optimistic Writes was conceived entirely to supplement the case where you have multiple derived tags writing to a complex source tag, like a structured value from OPC brought into Ignition as JSON/Document, where each write needs to see the previous one immediately because it’s basically a read-modify-write.

I still disagree with how this is done but I have accepted @pturmel on using counters going forward.

Some confusion comes from verbiage saying the developer “writes to a tag” and then the tag is sent via OPC to a PLC. But it sounds like you are saying I am writing directly to the OPC server while in parallel reading values via OPC.