Hello,
I'm seeing some strange behavior at the plant with our Mitsubishi Q-series PLCs. There are two heartbeat tags on the PLC - MES_HEARTBEAT, and PLC_HEARTBEAT.
PLC_HEARTBEAT is a boolean that is written to (by the PLC) every second with true and false, alternating. I have a gateway tag change script configured for every PLC_HEARTBEAT tag.
I write either 1 or 0 to the MES_HEARTBEAT tag depending on its current value. The PLC monitors the amount of time between the last change in the MES_HEARTBEAT tag, and resets the connection between itself and the Ignition gateway if 30 seconds have passed between a change in the tag value.
My issue is that I'm seeing MES_HEARTBEAT stay on for an abnormally long amount of time, when it should change at the same rate as the PLC_HEARTBEAT.
The tag group that these MES and PLC heartbeat tags belong to is set to subscribed, with a polling rate of 1000ms.
I'd appreciate any help - thanks.
Can you change your script to use system.opc.writeValue
instead of system.tag.writeBlocking
?
1 Like
Why not just directly write the value of the PLC Heartbeat tag to the MES_Heartbeat tag? This way if either reads or writes gets stalled/hung the PLC should catch it. This would also simplify this significantly.
1 Like
I've just changed my script to the following, and it's already looking better:
Thanks!
Is there a rule of thumb for when to use system.opc.writeValue rather than the other write functions?
In the future, post your scripts as preformatted text as it makes it easier for us to help, but this is how I would go about it (inside your try block):
tagPath = str(event.getTagPath()).replace('PLC', 'MES')
system.tag.writeAsync([tagPath], [currentValue.value])
If "PLC" is in your tag paths besides the heartbeat tag, use the following instead:
tagPath = str(event.getTagPath()).replace('PLC_HEARTBEAT', 'MES_HEARTBEAT')
system.tag.writeAsync([tagPath], [currentValue.value])
1 Like
Its not clear to me why that would fix his issue. Does the write operation really take that long such that he shouldn't use .WriteBlocking? That would surprise me.
The tag system attempts to batch writes to OPC tags together, and those batches get executed in order, one at a time. I assume he has multiple PLC and tag change scripts all trying to execute more or less at the same time, but these writes from different threads can't be batched together. So all these heartbeat writes are just waiting in line behind other writes.
I've seen this countless times. Heartbeat scripts should always bypass the tag system and use system.opc.write*
and not system.tag.write*
.
7 Likes
Good to know! I'm assuming this depends a lot on how loaded the comms are, but forcing direct PLC writes would make sense. Do they essentially bypass the queue and "skip the line".
1 Like
Yes, that's exactly what's happening. There's no queue or concurrency constraints for system.opc
calls (because there's no batching attemped). They just go directly against the OPC connection, immediately.
1 Like
Awesome!! Super helpful Kevin thank you. I also missed the distinction between system.opc.write*
and system.tag.write*
1 Like