LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Adding button outside case structure to force state

Solved!
Go to solution

I'm making a relatively simple .vi to step a motor through a number of speeds. It's my first attempt at making a state machine architecture, I had previously been working from an example provided by the motor manufacturer that was a timed sequence.

 

I am trying to add a button to my vi that forces the state to "Disabled" to stop the motor, but I'm having trouble putting it somewhere where the reaction is fast enough. It's not supposed to be an emergency stop so it doesn't need to be completely instant - there's a hardware button for that - but it's more of a "oh balls, I had the wrong option selected" kind of thing.

 

Outside of the main loop it obviously doesn't get read after the program starts. Within the main loop but outside the case structure also doesn't seem to work, and within the case structure I thought of putting it in the "Spin" state but that takes 5s to respond due to the wait function.

Download All
0 Kudos
Message 1 of 8
(3,077 Views)

Your states take too long.  You should not have "long" waits in your states.  You are allowed to repeat states until an amount of time has elapsed.  Then you can react to the button press a lot faster.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 2 of 8
(3,039 Views)

I see, so do you think it would be better to split my current "Spin" state so I have one state that sends the message to the motor to start spinning, and then move to a new "Spinning" state that I repeat as necessary?

 

How would I best repeat the state for a set time? Would you have a Wait function that is a fraction of the desired time and an iteration counter that increments until it reaches the total time divided by the wait time?

0 Kudos
Message 3 of 8
(3,029 Views)

Take a look at queues. Basically, you want one "master loop" that queues messages to a "slave" loop and when you press the stop button it queues the state in front of the queue, forcing it to execute first. It will be easier to synchronize and program than a traditional state machine.

0 Kudos
Message 4 of 8
(3,025 Views)
Solution
Accepted by topic author Martin_N

@Martin_N wrote:

How would I best repeat the state for a set time? Would you have a Wait function that is a fraction of the desired time and an iteration counter that increments until it reaches the total time divided by the wait time?


Use the Elapsed Time express VI.  You will want to keep the reset in a shift register so that you only reset it on the first iteration of the spin.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 5 of 8
(3,024 Views)

Thanks, that was really helpful. It solved that particular issue and helped me to come up with ways to do some other things too.

0 Kudos
Message 6 of 8
(2,992 Views)

I am glad you solved your problem, but there are quite a few other things that require attention that will help you in the future. Here are some:

 

  • Your state enum should be a typedef. Imagine you are adding a new state in the future, having you tediously replace plain enums everywhere!
  • "Test step" should probably be a plain numeric, you are randomly mixing it with an enum. If you want it as an enum, you need to do it everywhere, including inside the cluster.
  • It would be simpler to eliminate the case structure inside the init case and just index into an array of profiles using the "test profile".
  • Similarly, you could index into an array of velocities using the "step" value (spin state).
  • The "test profile" control will only get read once when the program starts (it is outside the main loop!), this also means that the inner case never changes. That control probably belongs inside the init case. (If you leave it outside, you should also move the inner case structure outside because the output will never change for the duration of the run.
  • You are suing the timed loop as a glorified FOR loop. Why?
  • "Dividing two integers, rounding down, back to integer" could be replaced by "quotient &remainder"
  •  etc. (this is just the tip of the iceberg lettuce)
Message 7 of 8
(2,980 Views)

Thanks for your comment, all of those issues have already been fixed. The VI I have now is considerably improved from what I originally posted. I'm now into a whole new world of fun - CAN

0 Kudos
Message 8 of 8
(2,974 Views)