From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What causes my state machine stop working?

Solved!
Go to solution

Hi Application Engineers,

 

I used state machine to control a motor for vertical positioning a sensor. Initially, there were 20 states or cases, and all worked fine. later, I combined a few cases to simplify the operations, however, the machine stooped working after I deleted 3 cases from the case structure and the enum controls.  The problem is that the internal while loop does not update its loop counter, hence no new value passes to the next state/case to perform state transition.

 

Could someone helps me with this troubleshooting? I am using 2015 version

 

I removed the actual coding for various motor actions so that the trouble shooting can be focused on the case transition, which is in the initial case.

 

See the attached vi and Enum control

Thanks,

Gu

edmonton_0-1631409794651.png

 

Download All
0 Kudos
Message 1 of 12
(2,431 Views)
Solution
Accepted by edmonton

Your "States" array constant only has 1 element in it.  So the most the loop will iterate is once.


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 2 of 12
(2,425 Views)

@edmonton wrote:

Hi Application Engineers,

 

I used state machine to control a motor for vertical positioning a sensor. Initially, there were 20 states or cases, and all worked fine. later, I combined a few cases to simplify the operations, however, the machine stooped working after I deleted 3 cases from the case structure and the enum controls.  The problem is that the internal while loop does not update its loop counter, hence no new value passes to the next state/case to perform state transition.

 

Could someone helps me with this troubleshooting? I am using 2015 version

 

I removed the actual coding for various motor actions so that the trouble shooting can be focused on the case transition, which is in the initial case.

 

See the attached vi and Enum control

Thanks,

Gu

edmonton_0-1631409794651.png

 


You FOR loop has two autoindexing arrays.  The FOR loop will iterate as many times as the number of array elements of the smaller array.  Your state array consists of just one element, so it just processes the first Boolean element.  Honestly, as I see this, I think you were better off leaving it as twenty different states.  State machines are supposed to have discrete states.  This should have a state for each choice.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 3 of 12
(2,422 Views)

Hi 

 

0 Kudos
Message 4 of 12
(2,401 Views)
Solution
Accepted by edmonton

When you click on the enum you see the name of elements your enum can contain. But that is not the number of elements your array contains.

 

Instead you should expand the array to show more than one element and then you see that only the first contains a value (the others are grayed out).

enum array constant.jpg

But your program has another significant problem. You don't see it now as your states do absolutely nothing and LabVIEW will go through it faster than any human ever could possibly click two buttons at the same time but motion control is something very slow (for computers) and each state will take a long time once you implement the real thing. While your program spends time in a specific state the user might click easily more than one button in the meantime.

 

There are two approaches to this problem.

 

1) After every button detection immediately disable all the buttons and enable them back on once your operation is done

 

2) Use an event structure in your Idle case, that has one event case for each button! It still may be useful to disable the buttons whenever you start a lengthy operation. It is super annoying for a user to push buttons and not see an immediate reaction. The disabled buttons at least give an indication that currently the program is not able to accept any input.

 

All in all your single element state machine will more sooner than later totally make you bend your neck in impossible turns to get this motion application working. With one element only in the shift register you can't define sequences that get triggered from a certain action but only ever linear state transitions.

 

Let's assume you want to implement the "Disable Button" approach. Multiple of your button actions will require that but you can't easily put this code in its own state since once you are in that state you don't know which button was pressed in your event handling case. So your state machine needs at least a second shift register that can store the state that should be moved too once you have completed such a common state that you want to use in different sequences.

 

Or you can use a state machine that has a multi element queue. You could do that with an array in the shift register or with a string like what the JKI state machine uses. Now when you have a specific button press, you can push multiple elements into the state machine queue: "disable all buttons", "initialize action x", "wait for action x to reach final position", "cleanup action", "enable all buttons".

 

Rolf Kalbermatter
My Blog
Message 5 of 12
(2,374 Views)

Hi  ,

 

Thank you for your explanation in detail and suggestions. I got it now, the constant array contained only one element, which is an enum with a list of cases. I treated the list of cases in the enum element as elements of the array. The array should contain multiple enums. I have changed it, and the machine can work as my expectation. 

 

The machine worked fine with a real motor connected before I deleted the three cases for simplicity. I think that I mistakenly deleted more elements from the array than what I wanted. I will add more code as you suggested to avoid some user's wrong button clicks.

 

Now there is a new issue, the case structure shows a number rather than a case name and there is a red dot at the places where indicated using a arrow, this makes the program readability very low. I did not have such a problem before. The case structure shows case names as normal once the program is disconnected from the shift register at right side. See below the screenshots and the attached program.

 

Could you please take a look?

 

Best regards, 

Gu

 

edmonton_3-1631467097096.png

 

edmonton_4-1631467146290.png

 

 

 

 

 

 

 

Download All
0 Kudos
Message 6 of 12
(2,351 Views)

I recommend going back to the drawing board and start with some basic tutorials. You are not ready yet to jump into the deep end of state machines. 😄

 

  1. Almost none of your buttons have the correct mechanical action. Reasonable would be latch when released. (you currently use switch until released, meaning that presses can be missed if the timing is off. There are very few cases where "switch until released" is a good choice, e.g. a car horn! It is not the default, so you must have manually changed these for some obscure reasoning).
  2. Why does your "initial" switch default to true?
  3. Why is diagram and front panel maximized to the screen? Why is the front panel such a disorganized mess?
  4. Most of your buttons could be combined into a single radiobutton control (not shown)
  5. Your polling code to turn an array of booleans into a state enum could be implemented e.g. as follows (assuming that the elements are correctly ordered and correspond to the enum items):

 

altenbach_0-1631467369245.png

 

Message 7 of 12
(2,348 Views)

Hi  ,

 

Thank you very much for your suggestions.

1. I fully agree with you that latch when released is better than switch until released. 

2. All bottoms are checked in the initial case, I wanted the machine to go back to initial case so that a button press can be picked up. The first button press may not be picked up if initial case is not in default.  

3. It looks fine  on my computer, but do not know how it shows up on other computers. I have not tried to run the code  using different computers.  The front panel is well organized in my full code, but is not well organized in the vi uploaded here, because majority of code was removed for the state transition troubleshooting. 

4. Yes, the the buttons could be combined into a single radio button control. You showed me a better way of doing it by using a search array instead of a while loop. One thing I noticed is that I have more cases than number of buttons,  one run button runs into  a few cases continuously. There is a while loop (not show) to check a motor's position-reached-flag immediately after the case structure so that  all cases can share the flag-check loop to show live position. If multiple motor cations (cases) are combined in one run case, then the flag-check code must inserted after each action. e.g. UP, flag-check, Down, flag-check.

5. Could you please let me know the name of the vi between search array and Enum #1 as I could not figure out what it is from your snip.

 

Best regards,

Gu

0 Kudos
Message 8 of 12
(2,343 Views)
  1. Yes.
  2. My code will automatically return "initial" when no button is true. No extra code needed.
  3. If I open your VI, both windows are maximized to the screen. Typically I want to see both and even the help windows at the same time. A maximized windows prevents that. Annoying!
  4. I did not understand your explanation. Are you talking about the state case structure? Words like "continuously" are poorly defined. Any state can decide what should happen next. If something needs to overwrite that under unusual conditions, the next state value could be adjusted outside the case structure.
  5. I use coerce to type. (Very old LabVIEW versions might not show it in the palette).
Message 9 of 12
(2,324 Views)

Hi Altenbach,

 

1. Could you please let me know how to setup my VI so that it will not maximize the panel when I share my VIs?

2. I checked my 2015 version for the coerce to type vi, it does not show up. Could you please add it to my VI and upload it so that I can give a try to see if it works on 2015 version?

 

3. When I used "continuously", it was for a series of motor actions in one case, or one action after another immediately.  It can be done in one case, it can also be done using multiple cases. I used multiple cases with a run-button click. I should have used a better word or explanation.

 

Regards,

Gu

0 Kudos
Message 10 of 12
(2,306 Views)