09-14-2012 01:19 PM
Hi All,
So I have this VI that needs to control two solenoid valves by opening and closing them through the digital outputs.
I want the program to have a function like this
Phase 1: Valve 1 open, Valve 2 closed (Amount of time for this defined by user)
Phase 2: Both valves closed (for .1 seconds)
Phase 3: Valve 1 closed, Valve 2 open (Again, this amount of time is defined by user)
and I want it to cycle through phase 1-3 100,000 times. However, every 10,000 cycles of phase 1-3 I want it to change the condition on Phase 2 so that both valves are closed for an hour instead of .1 seconds, then after this hour loop I want it to return back to the original cycling conditions (.1 sec instead of 1 hour) until it does another 10,000 cycles.
I was thinking that a sequence loop would be fine because I would wire it up with timing and a counter, and every time it goes to the last sequence it would increase the counter so that when its at the phase 2 timing I can use a case structure (if counter > 10,000 hold 1 hour, if counter <10,000 hold .1 sec) and then in the last sequence reset the counter to 1 if it is >10,000.
I thought a sequence structure would be good for this but I'm fairly new to labview and if theres a better way to do this I'm open to suggestions :).
Attached is my code so far, except that I have not finished wiring the ports for valve B
09-14-2012 01:34 PM
Here's a picture attachment of my block diagram incase anyone has trouble opening the vi.
09-14-2012 01:46 PM
You should definately be using a state machine. You should also keep track of your iterations yourself. You can do this with a shift register and increment. One trick I have done is to use the Quotient and Remainder to reset the iteration count every so often, in your case 10,000. When this reset happens, then you perform your 1 hour wait.
09-14-2012 02:01 PM
Hi, thanks for the quick reply! I'm pretty new to Labview and have never really played with state machines. How would I control the timing conditions in the state machine?
09-14-2012 02:18 PM
As I already stated, when your counter resets back to 0, you perform your 1 hour wait. Everything else should work the same.
09-14-2012 02:28 PM
Okay I understand that, and sorry for my basic understanding of labview but would the case structure in the while loop be like state 1, 2, 3, and hour delay state? Like would I put in state 1 the timer with valve A open, then make it move to state two where valve A closes for some time, etc? How do I control the time that each valve is open? Do I just put the wait (ms) thing in the same case as the valve A opening? Sorry for asking so many questions but I am just unsure of how to set up this state machine so that it can control the timing of each valve opening and closing.
09-14-2012 03:05 PM
To better restate my question, without including the 1 hour delay part, would I do the same method as the sequence structure above where the first block is case 1, second is case 2 etc...?
09-14-2012 03:30 PM - edited 09-14-2012 03:37 PM
First, you should avoid the use of a sequence structure. Don't even consider it to be an option. At least not at this stage of your learning. Learn how to use data flow. Also, avoid the use of local/global variables. They tend to lead to race conditions which in turn result in some difficult bugs to find and fix. Think of the wires as your variables.
As for the time delay in your state machine, your actual state should delay for a short time like 100 ms. Use the current time of day to determine when you have reached your desired timeout. If you use a single delay of an hour your program will be unresponsive for that hour. Users tend to get very annoyed if they try to stop the program and they have to wait a long time for it to actually stop.
Here is a basic example that shows the concept in a state machine.
When naming states for your state machine give them a meanigful name. Use a typedefed ENUM for your state variable. For simplicity sake the example attached does not use a typedef. But naming things like State 1, State 2 and so on makes the code difficult to read and understand. Your Open/Close valves states can be written in such a way that they are generic and take the valve data as input. At a minimum I would create a subVI to do this so you only have one piece of code to manage. You could have explcit states though such as Open Valve A and Open Valve B that call your generic Open Vavle subVI with the appropriate input data.
One last comment, the express VIs tend to be very inefficient. They are OK for learning how things are done but I would implement their functionality directly. For example, the express VIs tend to open, initialize, do something, close the instrument. You really don't have to do all of that every time. Open and Initialize once in the begining (hint, this could be a state), put the stuff that does the work in appropriate states/subVIs (other states) and then close at the end of your application (the exit state for example).
09-14-2012 10:46 PM - edited 09-14-2012 11:10 PM