Toggle through button?

We are having some trouble with storing variables. We would like to create some code that when you press a button and then release the button, we can toggle a t/f or change a variable. For example, switch between the numbers 1, 2, and 3 by hitting a button. The problem we’ve run into is getting the number to stay once the button has been released. As soon as the button goes back to false, the toggle goes back to default…

Depending on what language you’re using, and assuming that we’re using Java and joystick button 2, the code would look something like:


if joystick.getButton(2) == true && number < 2 {
     number++
} else if joystick.getButton(2) == true && number == 2 {
     number = 0
}

Note - this code is untested. Be sure to declare “number” and set it to 0 earlier in the program.

Also, this code will use values 0, 1, and 2, rotating each time the button is pressed.

I don’t know how the Java code handles the button calls, but wouldn’t that just cycle through the numbers without stopping? Unless getButton removes the read value when you read it the first time, this would set one number one loop, and see that the button is still pressed in the next loop and set the next number. You need a second variable to hold the last read button value. In the same Java code, it would look like this:

if joystick.getButton(2)==true && number<2 && lastState==false {
     number++
} else if joystick.getButton(2)==true && number==2 && lastState==false {
     number = 0
}
   lastState=joystick.getButton(2);

Since lastState is set after the if() structure, the new value will not be read until the next run through. So if it’s FALSE now and you push the button, it will increment the variable, then set lastState to TRUE, which will be read the next time, and the structure will not run. Then, when you release the button, it sets lastState to FALSE again, and you can increment the variable again.

You can also use a shorter code system utilizing modulus. Modulus (%) reports the remainder in a division. So, 5 % 3 = 2. This will only report the values 0 (divisible by 3), 1 (1 more than a factor of 3) and 2 (2 more than a factor of 3). This will allow you to use a slightly longer equation, but shorter code which might actually run a bit faster (however insignificant with a 400Mhz processor):

if joystick.getButton(2) == true && lastState == false {
     number = (number+1) % 3;
}
   lastState = joystick.getButton(2);

Good luck, and let us know if you have any more problems.

@Daltore: You’re probably right, I didn’t think of that.

We aren’t in java, i forgot to mention we are in Labview…

Okay, so the setup for LabView will be the same as in Java, you need to variables. In LabView, variables are just read/write calls to indicators and controls. Create two indicators or controls on the front panel (one boolean, one numeric). Then go to the block diagram, right-click, and go to the Structures pallet. There will be a gray box near the bottom that says “LOCAL”. Click this and place it on the block diagram. It will have a question mark and a pin on the left. Click the question mark, and it will show a list of indicators and controls that currently exist in that VI. Select your boolean or numeric. To change the variable to read instead of write, right-click on the variable, and select “Change to Read”. This will allow you to input and output data from the controls and indicators in your VI more than once.

However, since LabView is by nature a parallel language, we need a way of doing the increment and setting the last seen variable separately. To do this, you can use either a Flat Sequence Structure or a Stacked Sequence Structure (both in the structures pallet). A Flat Sequence structure looks like a film reel, and each frame is executed one after another, from left to right. To add a frame, right click on the right edge of the structure and select “Add Frame After”. In the first frame, you need to have an AND operator (boolean pallet), a NOT operator on the lastSeen variable to negate its value (also boolean pallet), a Quotient and Remainder VI (numeric pallet, I think), and a case statement. The Quotient and Remainder VI works just like the “%” modulus symbol in the Java example, you plug in “number + 1” into X and “3” into Y, and the remainder appears on the top right corner (R, for "remainder). Wire that to your “number” variable.

In the next frame, you need to set “lastSeen” (or whatever you called your boolean variable) to the joystick button value.

That should be it, let me know if you want me to explain anything further.

http://frcmastery.com/try-me/state-machines/
this may actually be able to explain it better than any of us can. this is the clean way of doing that

You could just use a Shift Register or Feedback Node, that seems like the simplest thing to do. Add a feedback node, set the input (bottom terminal) to what you want it to start as, then when you set it set the right terminal and that data will be available to the left terminal when you next run the loop.

Yep. In labview, a true/false structure that increments or decrements the number, along with an in-range check to keep it within the numbers you want and a feedback node to return the last value. The only hitch is that you will need to code a trigger-style VI that latches until it sees the button released so it won’t count up if it loops several times during a single button press.

The LabVIEW key word is
uninitialized shift register

Untitled.png


Untitled.png