turning a push button into a switch

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

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.

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.

Latch.vi (8.21 KB)


Latch.vi (8.21 KB)

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/

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.

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.

feedbacknode.PNG


feedbacknode.PNG

Looks like you accidentally made two topics…

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

Thanks. I merged the threads.

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.

Good catch. That is why it is better to actually write and run code and not just talk about it.

Greg McKaskle

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.

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.

What we did was pretty much what Acarid did except we finished it to change the state:D

Latch Button.vi (6.25 KB)


Latch Button.vi (6.25 KB)