LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

queue and notifier with state machine

Solved!
Go to solution

I am trying to implement a notifier and a queue to gather data that is running on a state machine in two seperate loops.  I am new to the whole queue and notifier methods and I think I am really close to getting it to work the way I want.  When I run the state machine the first time everything works good and it is doing what I would expect.  When I try to restart the test and do it again it acts like the queue hasn't been cleared and it won't log anything to the queue.  I am using the queue as a buffer for the data being collected between iterations of the state machine loop.  I flush the queue and add all the data to an array.  The notifier seems to be working in all situations the way I want.  I have attached a simplified version of what I am trying to do.  Any ideas? Thanks.

0 Kudos
Message 1 of 6
(4,415 Views)

Why are you using Flush queue?

 

The normal mode of operation for a queue is to use Dequeue Element.  The code waits until there is an element in the queue and dequeues it once it arrives.

 

I'm worried you may have a race condition.  It seems like you have state machine that is divided between two loops.  And the other loop determines which state to execute based on a local variable of the state that is determined in the bottom loop.  So you might have a loss of synchronization between what the two loops are doing.

 

It's hard to say.  The overall architecture seems to be 2-3 times more complicated than it needs to be.  When you say "restart the test", do you mean actually stopping the VI and restarting it?  If so, I don't know why the queue would have stale information in it because you are killing the queue after the bottom loop stops.

0 Kudos
Message 2 of 6
(4,399 Views)
I am using the flush queue to get all the elements between iterations of the bottom loop.  The bottom loop runs much slower and by flushing it I essentially catch up with the upper loop.  The two state machines have the same cases.  Normally I would have just the state machine in the bottom loop, but I want to add to the queue at certain times in the state machine and that is the only way I know how to do it.  Si there a easier way to do it?
0 Kudos
Message 3 of 6
(4,393 Views)
I removed the second state machine in the upper loop and it still acts the same, so I don't think I am getting into a race condition with the local variable.  When you run it the first time by pressing start and then slowly increase the force it will add to the queue and build the array that I want.  Without stopping the vi, lower the force back to zero and press Restart and do it again and it no longer queues anything.  All I am doing when I press the restart button is move the state machine to a different state, so I don't know how that is effecting the queue at all.  I am probably making this a lot harder than it really is like Raven Fan said.
0 Kudos
Message 4 of 6
(4,369 Views)
Solution
Accepted by topic author secr1973

After running your code (I had to make up my own custom control for the states since you didn't include yours) and probing some values, here is the conclusion I have come to: 

 

It's not your queue.

 

It's your math.

 

In your upper loop, put probes on the values you're using to trigger the "True" case (specifically, put a probe on the values going into your "greater than or equal to" function), and then watch their values as you run your code.  The value that's coming through the shift register is your problem.  It doesn't get set back to zero when you restart the test.  The first time you run your program, that value is zero.  For subsequent iterations, it's whatever the last calculated deflection was.  Run your "force" knob back down to zero after your test is complete, and have a look at what that value is doing.

 

So, when you restart your test without restarting your program, you're starting with a nonzero value for calculated deflection.  This is preventing your delta from ever exceeding 0.001in, and therefore your "True" case never executes.  Thus nothing ever shows up in your queue.  You're not putting anything in your queue.

 

The reason you make it to your "complete" state in the lower loop when you hit 0.3in deflection is because the current "deflection" value is passed through your notifier, and is not dependent on the previous value the way your queue is.  So you can always hit 0.3in deflection, without the calculated delta being greater than 0.001in.

 

Try resetting that shift register value in your upper loop to zero every time you restart the test, and your program will probably work.

 

And Ravens Fan has a point about the complexity.  He usually does.  Smiley Happy

Message Edited by DianeS on 03-16-2010 07:05 PM
Message 5 of 6
(4,360 Views)

Thank you so much Diane, thats it!

 

As far as the complexity of the vi, what can I change?  Does it make sense what I am trying to do?  I basically just want a buffer between the two loops that run as different rates.  The dequeue function is not really what I want because all I get is one point, and sense the upper loop is running much faster, I fall furthur behind.

0 Kudos
Message 6 of 6
(4,345 Views)