I am wondering if anyone knows of any "smart" way to change an integer value in a PLC over OPC relative to its current value (+10/-10 etc.)
Currently I am solving this by using the system.tag.readBlocking and writeBlocking functions but as expected if the user clicks either the increment or decrement buttons too fast the comms can't keep up and the value ends up being incorrect. Using the readAsync and writeAsync has pretty much the same outcome since when the read happens the value isn't always updated on the PLC.
I was thinking of maybe having a "holding integer" of sorts that gets updated either in the client or on the gateway as a memory tag. I would then feed it into the actual OPC tag every X seconds or something along those lines, but I have no idea if this is the best solution for it or not. I feel like this is a very workaround and poorly made solution, but it might be the best bet currently.
Has anyone made any functionality like this before and if so what would your recommended way of solving it be?
We would need to see the code. WriteBlocking is “as the name says” blocking. So multiple clicks should stack up and complete in the order they’re received.
IMO, this is best handled by writing a bit to the PLC and letting the PLC handle the increment/decrement operation. There is no need (in most cases) to read the value apply the increment/decrement and then write it back. If the PLC does any type of write to the value then the PLC should be the source of truth for the value and therefore should handle all write operations.
This should be able to be handled with only traditional bindings in Ignition and PLC logic.
If the PLC never writes to this value itself, consider using a memory tag instead of an OPC tag. The memory tag would have a change event that uses system.opc.writeValue() to push any changes to the PLC. Never read it, so no race.
Is there any real difference between using system.opc.writeValue() vs. system.tag.writeBlocking() that targets an OPC tag?
I will probably use this solution to solve the issue as we are not able to change the logic on the PLC at the current time. The tag on the PLC does get written to in emergency situations, but we have access to the tags that trigger the emergency situation so I can use them in the change script as conditionals.
The main problem with using a Bit that lets the PLC write the tag is that clicking would be blocked entirely until the PLC resets the bit locally. We have converted the customers old WinCC application to Ignition and they wish to have the functionality as similar as possible.
system.opc.writeValue() is not constrained by Ignitions tag systems (scan classes) the value is written directly to the device.
If Ignition is setting the bit, it should be the source of truth for that tag, the PLC shouldn’t reset it, Ignition should. Assuming this is not for control of equipment a momentary button can safely be used, and the PLC need only look for the rising edge.
The difference is that the former needs no Ignition tag at all. And therefore is not associated with any reading of that PLC value. An OPC tag's purpose is to track the PLC value, and writing is incidental.
Would this work? From my previous experience with different HMI and SCADA applications it is considered bad practice to reset the the control bit in the HMI or the SCADA after setting it as it can lead to the PLC not actually picking up the rising edge value due to cycle time and communication load.
Ok thank you for the explanation.
I will try using system.opc.writeValue() on a memory tag with a change script