Showing results for 
Search instead for 
Did you mean: 

state machine running out of order

Go to solution

Here is my latest attempt.  I got rid of all the internal while loops and tried to keep the states flowing from one to another.  I had to wire the shift registers together with nothing between them or else I would get errors while the code ran.  This code works but not well.  I know I need to smooth out the logic on the Compare frame but I am sure there are other things I can make it do to run smoother.  


Am I on the right track or should I try using a different architecture like nested for loops? 


This has been incredibly frustrating for me.  You guys are my only help since there is nobody I know of here at the university to help me.  Thanks again.   



0 Kudos
Message 11 of 20

Small victory!  I smoothed out the code a little bit on the COMPARE case and implemented a counter. My linear actuator increments from the beginning position out to the max and then returns to zero.  It then starts incrementing back out to the max again as it should but the program stalls once the actuator is about half way out.  Any ideas? 

0 Kudos
Message 12 of 20

When you say stops, does it go through the stop case or what? What state is it sitting in when it stops?



Also, your desired voltage control, do you ever put anything in there manually or is it simply to indicate the output that you are targetting? If it is the latter then you can change the control to an indicator and run the Desired Position calculation straight to the input of the case structure.

0 Kudos
Message 13 of 20
Accepted by topic author jas4513

Your latest code still has some things which are probably fighting you.


1. Create your AI taks in the Init state as you do for the digital tasks. The digital tasks can probably be combined into one task using an array of booleans as inputs.

2. You need another state to clear all the tasks, or this could be done in the Stop state after writing False to both lines. ### Just noticed that the Stop button is not connected to the Stop state. The way you have it will leave the actuators in an unknown state, possibly running when the VI stops.   Not good!

3. Get rid of the local variables. Use shift registers to pass data from one state to another.

4. You have race conditions/conflict generated by the use of the local variables. Desired Voltage is both a user control and the output of a calculation based on Desired Actuator Post which is also both a user control and driven by local variables from calculations.  Which one do you actually want the uer to enter? The other should be an indicator.
5. Selectors with True wired to the boolean input seem rather silly.  Just wire the state enum constant to the output tunnel in those cases.

6. Consider using an event structure to handle the things the user needs to change while the program is running, such as the Start and Stop buttons.

7. The AI Read and associated calculations should be in a Read or Get Position state.  Very little code, especially code which perfomrs key functionality of the program, should be outside the case structure.

8. Straightening the wires would make it much easier to follow what the program is doing.



0 Kudos
Message 14 of 20

My program stops in the Acutator out frame.  When I hit the lightbulb it appears my program is still running so I am starting to wonder if I am over heating my actuator.  However, when I hit the stop button the program takes about a minute to actually stop.  Could I be having a memory issue?  The way my program is written, am I actually storing anything or using any memory for anything?  


And yes I meant to use the desired voltage control as an indicator.  I forgot to change that. 



0 Kudos
Message 15 of 20

In Actuator Out the next state is set to Compare. There is nothing in your state machine which stops it. It will continue cylcing through various states indefinitely.  If it ever gets into Stage Up or Stage Down, it will stay there forever.


One useful troubleshooting tool for state mahcines is to place an indicator on the state line coming out of the case structure. It will flicker rapidly since most states execute in microseconds but you may be able to get some idea of what it is doing.



0 Kudos
Message 16 of 20

I moved my create channel outside of the while loop and increased my delay time and the program runs better.  I think the computer was constantly creating a new channel and that was part of the issue.  


-Once I get the program all working I will minimize the use of local variables.  I am trying to keep it easier to understand for now. 

-I am also using while loops inside my stage up and stage down cases.  (Shame on me.. but it works for now) And yes I know I don't have any way for the code to execute those for now. 

-I got rid of the useless selectors.  

-Changed one control to an indicator. 


Two issues:


-First: How can I add a new case without having to create all new ENUMs and messing up the names of my cases?  Every time I have tried to add a case it causes way more problems than it has been worth.  I assume there is a much easier way than I have been trying. 


-Second: In reference to comment number two "You need another state to clear all the tasks, or this could be done in the Stop state after writing False to both lines. ### Just noticed that the Stop button is not connected to the Stop state. The way you have it will leave the actuators in an unknown state, possibly running when the VI stops.   Not good!"  How do I create a case that does this?  I have definitely had my actuator keep moving after the program stops.



0 Kudos
Message 17 of 20

First: Change the enum to a typedef. Then any changes to the enum will automatically propagate to all instances, including constants throughout your program. You will need to replace all the existing constants one time with the typedef constants. Then when you add a new state, add it to the enum first. After it is in the enum, create a new case. It will automatically have the enum item as the selector label!


Second: I use the word Halt for the state where I close everything down before exiting the VI. In the Halt state you write False to both motors (or whatever shuts them down). Then you clear the DAQmx tasks. You also want to close any files and anything else you do not want left dangling.  See above for how to add a state.


You may eventually want to consider a state which handles errors. For example if the calculated actuator position is way outside the normal range you may want to stop the motors to avoid a mechanical crash! 





Message 18 of 20

So changing everything to type def was easy.  But after it is changed I can't figure out how to add a case. 

0 Kudos
Message 19 of 20

Add an item to the typedef enum.


With the enum wired to the selection terminal of the case structure pop up on the border of the case structure and select Add Case After (Before) or Duplicate Case. 


The new case should have the added item in the selector label (or the first item which did not already have a case).



0 Kudos
Message 20 of 20