Hang on, so I'm safe to just throw that whole bit of code into the event structure's timeout case with a value of 0? With a couple "Close hardware" VI's and a "ABORT VI" in the stop case?
Yes. Except don't use Abort VI. In the stop case after everything executes, just wire out a True constant to the stop terminal of the while loop. Now your VI will stop gracefully.
When you have an event driven state machine, typically the event structure is inside an Idle or Wait for Event state. EVERY OTHER state must complete and return control to the Wait for Event State in a relatively short time. I prefer to keep that time to <= 100 ms. The only place I see in your code images where that might be a problem is in the file initialization and logging VIs because the OS and Excel might take more time than you would like. If that becomes an issue, then the Producer/Consumer architecture (with the file I/O in a Consumer) becomes the preferred choice.
If the current implementations of some of the controllers results in them taking seconds to complete, it is quite likely that they could be reconfigured to repeat a state or series of states, each of which is fast.
I cannot be more specific without seeing the details of the subVIs.
The controllers are all relatively tiny, with the most intensive one being the primary. It computes an array of 300 booleans, of which one is true. It then searches for the true one, feeds the index into a 300-wide case statement, which assigns values to some variables in the variable cluster. The booleans in all controllers are computed via a series of if-then statements, so honestly they should take no more than a few hundred milliseconds to execute.
I am aware that this is not the best way to go about implementing such a thing, but the code was inherited. I've been charged with refactoring it and optimizing it, which I plan to do using some OOP in the near future. If you want, I could use a stacked sequence to compute timings on each controller.
Okay, so I added the event structure back in, and due to the Timing created by the Time Controller, the event does respond until the next loop iterate. Would this need to be a state machine to combat that issue?
I don't think you'd need to calculate the timing of the controllers unless you are starting to see problems with the timing of the process.
I would not use a "300-wide case statement". That sounds like a case structure with 300 cases in it, am I correct?
I would use an array that has 300 elements. Whether that is a 2-D array where each row is a "case" and each column is a value, or it is a 1-D array of clusters, each item is a cluster that contains whatever combination of data is appropriate for that "case". Then you just need to index out the appropriate row of a 2-D array, or cluster out of the 1-D array. A lot easier than creating and wiring 300 cases in a case structure.
It's already written, but fortunately it's written in a very modular way. It works for now, but I'll be trying something like that in the near future. Thanks for the tip!
Ah, if you need to do initialization (or something else that might take a little time), that's a perfect time to "extend" the Event Loop by adding some User Events. In particular, if you create a User Event called, say, State, and create an Enum TypeDef called State that has such things as "Initialize", "Loop", and "Stop", you can create what some might call a "State" Machine based on the User Event. Don't need a TimeOut.
Before entering the "enhanced" Event Loop, generate an Initialize User Event. In the User Event for State, wire State to a Case Statement (of course). Now put in Initialize anything that is slow and needs to be done first, like opening and reading Excel, getting Log files opened, etc. When you are ready to run your first Loop (perhaps because you responded to a button push), in the Button Push Event, generate a Loop State. The Loop State takes a Data point, and if it is "self-clocking" (meaning it doesn't exit until the time is up), have it generate another Loop State (unless you know you are done). Similarly, the Stop Button generates a Stop State, which (can you guess?) wires a True to the Stop Indicator, perhaps first closing files.
All this is much simpler if you have most of your code neatly packaged in sub-VIs. Maybe it's something Mathematicians understand to do ...
Fortunately, I've already done some heavy lifting in modularizing the vast majority of this code, so changing to a state machine like that won't be too hard. Thanks for the help! I'm marking this one solved.
Till next time!