Can someone advise me whether the SFC module is powerful enough to act as 'recipe' program manager?
For background, within my PLC most of the production and CIP logic is done through a csv file. It uses a list of instructions (ex. Valve_1, turnOn, 60 (seconds), comment) and runs through them one at a time and through a number of 'commands' turns on and off all my I/O.
What I'd like to do is replicate this in Ignition if possible so I have the benefit of writing to non-matching PLCs in the facility. I envision it as pulling a recipe (i.e. list of instructions) from a db, writing values to tags based on these instructions, and building in protections built in that safely exit if there is an issue.
Is this something the SFC module would be good at? I'm struggling to think of how to get it done using Gateway scripts.
I'm rather biased against SFCs, in PLCs and in Ignition.
I would use a gateway timer script that runs often enough to have the timing precision you want. I would cache a current recipe and step number and timestamp in a script module top-level dictionary, initialized from memory tags during any scripting restart. The timer script would normally write to these memory tags any time it changes the cache values.
That same dictionary would hold the current command set and duration target, and calculate "step complete" from those variables. I would have the script preload the next step from the database so there's no query delay when applying it.
If you choose keys wisely, a dictionary can be transformed to and from a single-row dataset in a single memory tag.
That's a great idea. Thanks.
So work off of a timestamp-difference for all of my timer features? Something like...
if ((now() - currentTimestamp) > stepDuration):
then... Execute next step
That sounds like a good plan. That said, I'm a little unclear on where the top-level dictionary exists. I do have a 'global' project with some modules I made.
Are you saying to store the current step and state of the system in a dictionary variable in a module? Or were you suggesting to hold that in a memory dataset tag and use a module dictionary to interpret and act from the dataset? I'm unclear how that works if it's the first option.
As a backup. Scripting restarts will destroy script module top level variables, but top-level code could read a memory tag to initialize from the last known state. The script would have to write the dictionary back to the memory tag whenever it changes to ensure it is available on restart.