I’ve been fighting with this a while now, and I believe you might have some good advise on the best way to solve the issue.
At the moment in my DB I have 100 recipes x 100 steps x about 30 setpoints.
The columns in the DB are like [recipeNumber, stepNumber, sp1, sp2, sp3…sp30]
On my script I use a select query to get a single recipe dataset (100 steps x 30sp) .
I then run a for loop (index is the stepnumber) and write to the PLC with system.tag.writeAll(paths,values) where paths is something like PLCtag[rownumber] and values the results of the for loop on the dataset.
Now this means that I’m launching 100 times the system.tag.writeAll(paths,values) functions and it causes some issues on the GUI and the tag quality.
I’ve been suggested to use asynchronous threads, but I’m not sure if it’s a good idea to start 100 separate threads keeping the existing for loop and I have no much idea how the code could look like.
Yes, that’s quite possible. Consider extracting all of the OPC Item Paths from the tags and using system.opc.writeValues() instead. And yes, from an asynchronous task, as that is a blocking operation. Using this will avoid the timeouts for tag writes. Do inspect the list of qualities returned to ensure everything was successfully written. The asynchronous task needs to use .invokeLater to report results back to your UI. See this topic for more info:
I’ve used the system.tag.readAll() function to get the OPC paths from the defined tags on my script (I hope it makes sense to do this), and then I used system.opc.writeValues(), launched from an asynchronous task, but still at the end of writing, about 20-25 seconds later, I keep getting this red blinking in the GUI, and the comms for that PLC going to bad for about a second.
If I reduce the number of tags and I download only 50-60% of my list, it does work fine.
I’m now thinking if there is a way to download a 50% of tags first, then wait and download the remaining tags, since the operator won’t be using the second group of tags for a long amount of time.
EDIT: even with 50/60% sometimes it doesn’t work well, could I be missing something else??
No, just one. Looping through the percentages. Sleeping a bit each time through the loop. (Threads launched by system.util.invokeAsynchronous() can safely sleep, but not interact with the GUI.) Be sure you follow the guidance in the linked topic above.
I’ve changed the Scan cycle load on the PLC from 20% to 50%, but it didn’t change much the result.
I’ve divided the list into 3 big blocks and used sleep function (I went up to 7 seconds between the writings) but still sometimes I have the issue.
I’ve now noticed that not all PLC tags are affected, so I have other memories I’m using that are not going in red/bad status, and I’m start thinking that it can be something else.
All the 3000 tags I’m using to download the recipe are stored in a single big UDT (with 100 sub UDTs for every step).
Could it be that the UDT performance is somehow affected?
I’m still working on 7.9 but I have installed a 8.1 server recently to test the migration, so I might give it a go in that version too.
In the meantime I’ll test a different PLC and dividing the download in 10 blocks as suggested.
Did you consider transaction groups? Assuming you are writing to arrays in the PLC a block transaction group should be considered. You could easily break this out into multiple TGs and utilize the handshake to validate the PLC properly received all the data.
If you aren’t writing all this to an array in the PLC, fix that first.
Are the elements of the UDT array you are writing just the recipe settings? Or are operational and recipe elements mixed together in UDT? If the latter, Ignition won’t be able to optimize the writes into large blocks of bytes. You need to be writing every element of the UDT (also hopefully consecutive instances of the UDT in the array) in order for Ignition to make a big, efficient write.
The elements of the UDT are just the recipe settings.
I actually had an internal memory with the step Name, but I tried to remove it just to check if it was the real cause.
I still had the same issue at the end of the writing.
Then I tried the version 8 test server…and it looks like the problem doesn’t exist anymore
The writing is also faster and same the GUI response.
Maybe the UDT performance / drivers have been improved?
If this is the case I guess I only have to speed up the migration, even if it wasn’t planned yet…
This may or may not be the most efficient given the UDT structure, however you could always write to a buffer array in the PLC to optimize the Ignition data transfer, then when the TG handshake confirms a valid transfer, use PLC logic to copy the buffer array to the appropriate recipe UDT members.