We have had a very specific occasional issue with a "double handshake" with a PLC, and I am trying to understand the underlying architecture of the way the tag provider works. Here is the way the "double handshake" was configured:
PLC turns on DataRequest tag, and this tag is the trigger for a Gateway Tag Change Script.
Ignition completes a query, returns data to the PLC and turns on a DataAvailable tag using system.tag.writeBlocking.
The PLC turns on a DataReceived_Ack tag, and this tag is the trigger for a second Gateway Tag Change Script.
Ignition turns offDataAvailable using system.tag.writeBlocking.
The PLC turns off DataRequest and DataReceived_Ack.
Every once in a while, the DataAvailable tag will get stuck on along with the DataReceived_Ack tag. Tag history makes it clear that the DataReceived_Ack tag was turned on at the same time as DataAvailable, and we have every reason to believe that the second Gateway Tag Change Script from #3 above executed correctly.
Does anyone have any insight into what could cause this scenario?
By the way, we had our controls team remove the second half of the "double handshake" so we are no longer seeing this issue. I'm just trying to understand how the Tag Provider processes requests so we don't run into a similar situation with something else.
My guess is the transaction is happening so fast that the DataAvailable being turned on/off that quickly in succession that OPC hasn't verified the write or there's a race condition with it being written to immediately after it wrote it to a 1. What might be better is to let the PLC turn on DataRequest, then Ignition turns on DataAvailable after it retrieves the data, then once the PLC processes the data as an acknowledgement, it just simply turns off both DataRequestand DataAvailable. Does Ignition need to have any other form of acknowlegement from the PLC tha the data was received?
Edit: See below comments by @pturmel as he's correct in that the DataAvailable should only be written to (and should really only ever echo the state of DataRequest).
Yeah, that's what I would recommend. Turning off DataRequest is sufficient acknowledgement. And Ignition then turning off DataAvailable lets the PLC know that another request is possible.
That is, DataAvailable should simply echoDataRequest, after any requested data is actually available. Everything off is everything idle.
This is what we have defined as our standard for handshakes between Ignition and the PLCs. This particular "double handshake" was left over from an old configuration. Ignition does not need any additional confirmation from the PLC.
I think you're probably correct with this assessment.
I'm not quite sure what @michael.flagler meant, but I took his comment to mean that the PLC will turn off both DataRequest and DataAvailableonly after Ignition turns on DataAvailable. Unless I'm missing something, there shouldn't be a race condition since the PLC won't start writing to the DataAvailable tag until after it has been turned on by Ignition.
Added Note: To clarify, only Ignition turns that tag ON in our environment, and only the PLC turns it OFF.
Let me clarify: Don't do it. Have Ignition turn off DataAvailable when DataRequest turns off. That is the only way to be sure the PLC knows that Ignition is ready for another request.
Really: don't write to tags from two directions in handshakes.
If you want a faster handshake, use an incrementing integer that doesn't need to be reset (skip zero) and echo that as the "data available" signal.
I edited my post above so anyone coming here and not reading the full thread doesn't make that mistake. Yeah, it makes more sense to have Ignition only echo to DataAvailable once the data is available, but then when it reads the DataRequest as 0 and echos the 0 back to the PLC, the PLC knows Ignition has seen the DataRequest clear out and that it's safe to send another request.
Can you provide some clarification on the risks? Our standard handshake has been the following, and we have been using it across multiple locations for many years without any known issues.
PLC Turns on DataRequest
Ignition runs query, populates various tags, and turns on DataAvailable
PLC turns off DataRequest and DataAvailable
I suspect this is what you are recommending for the handshake:
PLC Turns on DataRequest
Ignition runs query, populates various tags, and turns on DataAvailable
PLC turns off DataRequest
Ignition turns off DataAvailable
Are you concerned about a timing issue (i.e. DataRequest turns off and on between polls from Ignition) or is there some other technical issue when both the PLC and Ignition could be writing to a single tag? If it's a timing issue, our takt time is around 10-12 seconds, so we've never had an issue with the timing unless there was some other major problem (e.g. network outage).
Edit: I should add that I definitely can see the benefits of the second handshake above if the handshake needs to happen rapidly between Ignition and the PLC. If both sets of logic understand this, it would likely be much faster and more reliable. Our time between triggers is just so slow (i.e. 10+ seconds) that we haven't had issues with the first handshake above.
Yes. If there is a hiccup in Ignition's polling, the PLC has no way to know if Ignition has seen DataRequest turn off, and could turn it back on before Ignition sees it.
That could theoretically happen anyways, depending on your poll rate versus your process rate. Any processing delay on either end could put the DataRequest off -> on transition ahead of Ignition's poll that would see "off".
Making Ignition write DataAvailable off, and making the PLC wait for it to be off, guarantees there's no race.
Fundamentally, you cannot make your handshake reliable in less than fourtwo poll cycles. That is why, for fast cycles, I recommend the integer handshake. It only needs twoone cycle.
Two versus one instead of four versus two: the PLC isn't polling. Writes are pushed into the PLC.