I have a program that contains producer-consumer design. On producer part program acquires data from accelerometers and saves data to TDMS file, on consumer part it process the data and gives an alarm/sends e-mail on different threshold levels. It also has some other consumer parts for different calculations.
What I want to do is add re-start button to front panel, and able to restart recording/processing after stopping the program. I added state machine structure, however I cannot restart the program.
I attached a simplified vi. I would appreciate if someone could help me on this. Thanks in advance.
Solved! Go to Solution.
You have a race condition in your Stop state. You are trying to read a control at the same time you are reinitializing all controls on the front panel. If that re-init happens first, which it sounds like it is at least most of the time for you, then the read value of the control will always be FALSE. I would move the invoke node into the case structure in that state. This way you only reinitialize the front panel when the Init state is being called again.
I tired to do what you said but it didn't solve the problem. I also tried removing invoke node completely but problem stays the same.
Can you be more specific about "cannot restart the program"? Is your state machine not going back to init and then to your acquisition state? Is one of both of your loops not running? Did you try running with Highlight Execution to try to see what is happening?
I tried with Highlight Execution mode and it is not going into "stop" state. When I push stop recording button, case structure which contains enum goes to true (go to stop case), however the state stays in the run not goes to stop.
I'm surprised it works at all!
The DAQ assistant is putting out an array of waveforms and the queue is a single waveform
I think you have a classic condition where your consumer loop is waiting for a message through the queue even though the producer loop stopped. The simple solution is get rid of the tag channel and the queue. Instead, use the Streaming channel. One of the inputs to the Streaming Channel Writer is something like "last element". You can set that to TRUE when you are stopping your producer loop. Then the consumer can just have that output wired to its stop terminal.
A Little Known Fact about Streaming Channels is that once they have been stopped by wiring True to Last Element?, the Channel is closed and cannot be used again. So if the idea is to "restart" the parallel loop, you won't be able to use the Channel!
Back before we had Channel Wires, I wrote a Data Acquisition/Control routine that ran a behavioral Experiment. The basic routine was structured as a Queued Message Handler, with Front Panel buttons sending Messages that governed what happened. The first Message (enqueued outside the Message Handler) was "Initialize", which "manually" initialized all of the Controls and Shift Registers to the desired Default values (I don't trust "Reinitialize to Default"). I think of this QMH as a sort of State Machine (yes, I know it's incorrect, but its a "metaphor"), and one of the last States is to ask the User whether or not to Restart, after which we Exit.
Now, consider the QMH and all its associated parallel loops (like the Event Structure loop). I wrap this inside one more While loop. Wire the output from the "Restart?" question to the "Continue" indicator of this outer While Loop (Continue = Stop Indicator after a left-click), so if you leave the QMH having said "Restart = True", the outer loop makes you do the QMH and its parallel loops all over again. And it is cheap (in space and code) and requires very little coding.
I tried to change tag channel to streaming channel as crossrulz suggested. I was able to stop and restart the loops at the first time but not second time. I was thinking that I was doing something wrong but Bob's message explained the situation about streaming channel, I will also try your other suggestion.
crossrulz and Bob thanks for the help.
As Bob_Schor advised I used QMH and it solved my problem. I started by using Queued Message Handler Template and integrated my vi s into it. Thank you for the help.