No idea what sort of industry you mainly work in but in my case (before I retired) was any that was going, it was heavily into batch processes but sometimes this would fit nicely into other machine controls.
One thing I tend to use especially in process batching that require recipes is a structure like this:
The process is made up of tasks i.e. a batching process that adds/blends/heats & cools product.
The recipe has two main structures, a common for things to do with perhaps common settings, and processes where the recipe has say 16 stages consisting of the following, oil addition, water addition, slurry addition, heating/mixing, manual addition.
Each recipe stage is identical, i.e. it contains all the things it needs like weights/heating times/temperatures etc.
Then you have what we called units these consist of the different processes
We tended to use a control engine that took care of the starting/stopping/abort or hold statuses, then another engine that did the batching process.
When a recipe is loaded & the system started, it took the first stage from the recipe, checked what type of stage (process) was then called the code that controlled that, at the completion the next recipe stage was loaded, this again checked the type of process & loaded it.
So we had two processes, the main engine this was basically simple
the seq. word was as follows
0 = IDLE
10 = Startup
20 = Running
30 = Holding
40 = Held
50 = Held on exception
60 = resuming
So the operator presses the start button it puts 10 into the seq var.
this calls the startup routine when complete it steps on to 20 when at 20 it starts the process seq. this consists of the following steps
0 = IDLE
10 = Startup
When on this step it loads the first stage of the recipe checks the type of addition & forces the process seq. var to the range for the type of addition.
for example:
10-99 is water addition (note we tend to jump in steps of 10 to allow for extra ones in the future)
100 -199 Slurry
200-299 Oil
300 -399 manual addition
400 -499 heating/mixing
& so on.
it means we only had one bit of code for example manual addition as there could be perhaps 5 different manual additions we only needed one bit of code then contained the weights limits etc.
So for example, The recipe stage is checked for type of addition, if oil it forced the process sequence to 200, this enables the oil sequence & steps through, when complete it stepped on & loaded the next stage, if this happened to be manual addition then it forced the seq var to 300 & so on
As we could have 5 or 6 manual additions in a process it only used one bit of code where the current recipe stage was put into it's own stage variables.
One other thing we had in the recipe was that all recipes were based on 100kg size, when the recipe was loaded, the operator put in the batch size, the system took the weights for a 100kg batch a little maths & worked out the actual amounts to add.