View Full Version : turning a push button into a switch
iblis432
04-02-2011, 23:04
I am trying to get the robot to switch a state based off the single press of a joystick button. I designed a system that i thought would work, but it began constantly switching the state back and forth without me pressing anything every (what I believe based off how i designed it) 10 ms.
I don't have the code with my right now, but in pseudo code this is what i did.
In periodic Tasks
iblis432
04-02-2011, 23:12
I am trying to get the robot to switch a state based off the single press of a joystick button. I designed a system that i thought would work, but it began constantly switching the state back and forth without me pressing anything every (what I believe based off how i designed it) 10 ms.
I don't have the code with my right now, but in pseudo code this is what i did.
In periodic Tasks.vi
10 ms loop
If button pressed
if global button data == true
set global button data = false
if global button data == false
set global button data = true
In Teleop.vi
If global button data == true
set solenoid = forward
else
set solenoid = reverse
So basically, I have two case structures inside each other in the periodic tasks loop thats constantly checking for if the button is pressed, and I THINK I have the state changing when the button is pressed. I put it in the 10 ms loop because i didn't want it switching every cycle just because we held the button for more than a nanosecond, but i didn't want a WAIT slowing down our teleop. Anyway, the state is sent to the Global Robot Data and called in teleop, where a single case structure determines the solenoids.
If anyone can tell me why it did what it did, how to fix it, or another approach altogether, I would very much appreciate it.
I will post the real code ASAP.
WizenedEE
04-02-2011, 23:29
I attached the code we made this year. To use it, just put it in a vi, connect up your momentary button and "switched" output, and then make a shift register and wire that up to the top. The shift register is outside the vi so we can use the same vi many times (if it were inside, the shift register would maintain its values from call to call, not just from loop to loop.)
The problem with your program is that if you press the button for more than 10 ms, it will change twice. My program waits until the button then gets unpressed before going back to the "ready to receive button" state.
I have no idea why your code would switch when you're not pressing the button if that's the actual way you coded it.
My vi works fine in teleop; there's a 20ms loop in teleop and your code has a 10ms loop; it's not a big difference. The 20ms actually helps debounce the switch for us.
NOTE: This code is untested in the real world - you might have to do something to debounce switches. I did test it in the vi with the front panel controls though.
EDIT: Added bundle/unbundle to code to have only one shift register.
Joe Ross
04-02-2011, 23:30
Based on your pseudo-code, I'm not sure why it would be toggling without anything pressed. However, it will definitely toggle every 10 ms when the button is pressed.
What you need to do is to save the state of the button in the previous loop and compare it to the value in the current loop and only do something when it changes. You can save old values using feedback nodes or shift registers.
Take a look at the "button action" examples from http://team358.org/files/programming/ControlSystem2009-/LabVIEW/
Joe Ross
05-02-2011, 00:03
I attached the code we made this year. To use it, just put it in a vi, connect up your momentary button and "switched" output, and then make a shift register and wire that up to the top. The shift register is outside the vi so we can use the same vi many times (if it were inside, the shift register would maintain its values from call to call, not just from loop to loop.)
My vi works fine in teleop; there's a 20ms loop in teleop and your code has a 10ms loop; it's not a big difference. The 20ms actually helps debounce the switch for us.
NOTE: This code is untested in the real world - you might have to do something to debounce switches. I did test it in the vi with the front panel controls though.
You can put shift registers or feedback nodes inside the VI if you set it to be reentrant in the VI properties.
Here's how my team does it: http://forums.usfirst.org/showthread.php?t=10544
WizenedEE
05-02-2011, 00:08
You can put shift registers or feedback nodes inside the VI if you set it to be reentrant in the VI properties.
Here's how my team does it: http://forums.usfirst.org/showthread.php?t=10544
Wow, that's pretty amazing.
I guess labview can run the robot without motors.
iblis432
05-02-2011, 00:28
Wow, that's pretty amazing.
I guess labview can run the robot without motors.
Oh yeah, you can simulate the entire system without even connecting to the cRIO if you know what your doing. I rarely get the robot until the last minute, so I'm usually simulating everything, though my simulation didn't pick up the constant solenoid changing.
Anyway, thanks for the help everyone. will test it out tomorrow.
Take a look at this:
http://zone.ni.com/reference/en-XX/help/371361B-01/glang/feedback_node/
When you wire something into a feedback node, it's previous value comes out.
If its previous value is false, and its current value is true, then it was just pressed and you can change states.
This ensures it will only change states once per press.
I attached an example of this here.
Looks like you accidentally made two topics...
http://www.chiefdelphi.com/forums/showthread.php?t=90955
Greg McKaskle
05-02-2011, 10:00
The attached code does work, but may I suggest replacing the negate and AND with a notEqual node? In Boolean algebra, they are equivalent, but if this were a number or string, Boolean doesn't work any longer. I also think the verbal description is probably more understandable to others.
Greg McKaskle
Bharat Nain
05-02-2011, 10:36
Looks like you accidentally made two topics...
http://www.chiefdelphi.com/forums/showthread.php?t=90955
Thanks. I merged the threads.
The attached code does work, but may I suggest replacing the negate and AND with a notEqual node? In Boolean algebra, they are equivalent, but if this were a number or string, Boolean doesn't work any longer. I also think the verbal description is probably more understandable to others.
Greg McKaskle
A not-equal wouldn't be quite the same, since it'd also activate when the button is released. A greater-than might work though... I'm not entirely sure if it'd work with booleans... hmm.
Greg McKaskle
06-02-2011, 08:31
Good catch. That is why it is better to actually write and run code and not just talk about it.
Greg McKaskle
wilsonmw04
06-02-2011, 09:47
Looks like you accidentally made two topics...
http://www.chiefdelphi.com/forums/showthread.php?t=90955
Yeah, I told Iblis about this last night. We live in a rather rural county where most of my students only option for net access is dial up. It does some strange things sometimes. Thanks for merging the two.
We are still working on our code. Thanks for all the advice. We will post code this week. Thanks again for all the help.
Alan Anderson
06-02-2011, 12:22
A not-equal wouldn't be quite the same, since it'd also activate when the button is released. A greater-than might work though... I'm not entirely sure if it'd work with booleans... hmm.
Greater-than and less-than are perfectly happy with boolean values. My favorite idiom for detecting the moment of a button press is to use a feedback node and a greater-than. Using a less-than instead will detect the button release.
bladetech932
06-02-2011, 12:45
What we did was pretty much what Acarid did except we finished it to change the state:D
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.