Go Down

Topic: Simple Button Input Floating Problems - New User (Read 7477 times) previous topic - next topic


I am a new user and have been struggling with the simple button.  I started with a more complex board, but when I saw I was having problems with that, I reduced it to the simple button as outlined in the tutorial with a simple serial interface so I can watch it on Putty.
The problem I am having is over extended periods of time (over a few hours), my button inputs will float from high to low (or low to high depending on whether I am using the internal pullup or an external pulldown).  It floats over for a few milliseconds and floats right back.  In the internal pullup scenario, I just have a simple tact switch on a breadboard with a 100-ohm resistor to pin on one side and wire to ground on the other side.  In the pulldown scenario, I used a tact switch on a breadboard with a 10K-resistor between ground and pin on one side and 100-ohm resistor to 5V on the other side.
My wires are as short as I can make them, and I have tried wrapping the wires in foil.  I've tried this on an Uno and on the Sparkfun SerIO board with the same results.  I've tried using the interrupt pins and interrupt functions, and I've also tried putting the pin status code into the loop code, with the same results.  I've tried using pins 2-7 with the same results.
If I leave it overnight, each input pin (pullup and pulldown) seems to float about 4-5 times.
What could I be doing wrong?  I don't know what else to try.

Jack Christensen

Need more info from you.
How are you detecting and timing the floating condition?
What tutorial are you referring to (link?)
I'm not familiar with Putty, what is that?
Can you post your hookup (schematic and/or picture?)

This should be a non-critical circuit layout.  Foil, etc. should not be necessary.
Only a single resistor is required, 10K is fine, 100? is too small.
Stick to getting it to work just with a regular input pin, save the interrupts for later.
Hook up the switch as shown in CIRC-07 here: http://ardx.org/src/guide/2/ARDX-EG-ADAF-WEB.pdf

Many tact switches have four pins, but they are just single-pole momentary contact switches, so there can be some confusion.  There are two pairs of pins that are connected together.  Check the switch with an ohmmeter (or just use an LED with a current-limiting resistor) to be sure you've got the pins identified correctly.


To answer those questions in order:

I am timing/detecting by spitting out over serial the pin status anytime it changes.  I had it talking over serial to my home automation controller which provides time of each message that comes over serial.

The arduino tutorial on buttons - http://www.arduino.cc/en/Tutorial/Button

Putty is a versatile ssh, telnet, serial comm tool.

I will take a picture when I go home, but it's a pretty simple setup.

I tried foil because I had tried everything else, and I thought maybe I was picking up noise.

I used the second resistor to protect the input pin - it doesn't help or hurt to put it in or pull it out.  That's the 100ohm resistor.  I am using a 10K for the external pulldown scenario, and the internal 20K for the pullup scenario.

As I mentioned, interrupts have nothing to do with the problem - my problem is not the coding - it's the hardware.

I have my setup the same as the example you showed, only I am using the internal pullup rather than an external pullup as shown.

Finally, I know how a tact switch works.  And, I lied - after I broke the pins on my tact switch, I am now using a momentary push-button.

I'll post a picture tonight. Thanks for the suggestions, any other thoughts/ideas?

Jack Christensen

Curiouser and curiouser.  Just seems like one of those things that is so simple that it cannot possibly fail.  Sorry about the tact switch comment, thought I'd mention just in case.  What I would do in this situation is reduce both the hardware and software down to the absolute minimum, and see if it still exhibits the problem, or maybe even better, start from scratch and build up a new minimal configuration.

Also try swapping components.  Sounds like you already swapped the switch.  How about the resistor?  Sounds stupid, but I had a resistor fail on me the other day for no apparent reason.  First time in 40 years of fiddling with electronics that I'd seen such a thing.  It was intermittent at first, thought it was just a bad breadboard connection.  Then it went completely open-circuit.  Brand spanking new 1/4W carbon film resistor, shot to hell, LOL.  Go figure.

I'm tempted to try and duplicate the problem.  So all I would need is a button on some input pin, and the software would just monitor it as fast as possible and send a serial message when its state changes?  I don't have Putty but I have CoolTerm, TeraTerm, and of course the Arduino serial monitor, I assume they would all be equivalent for the purpose.


Yes, it's driving me nuts... especially, since I get notifications from my home automation controller everytime it floats, and every time I get a notification, I die a little inside...

I had some free time in my all-day meeting, so I drew up my scenarios in fritzing.  I'll also post the arduino sketch and take pictures when I get home tonight.


Apr 20, 2011, 07:57 pm Last Edit: Apr 20, 2011, 07:59 pm by DaveO Reason: 1
only a newbee, but here's my guess.

I assume that the button is a simple contact type button, so unless the button is pressed, there is no pull up or pull down resistor on pins 2 or 3.

From my understanding ( very limited ) you need to pull the pins 2 and 3 to either high, with the buttons connecting Gnd to the pin, or pull pins 2 and 3 to low with the buttons connecting 5V+ to the pins.

In either case, you don't need a resistor in series from the button to the pin, as you're passing the boards own 5V+ (or Gnd) back to the pin.

I would move the resistor to connect the pin 2 and 3 to the 5V+, and then join Gnd to the button, and the other side of the button to the pin.

I could be wrong, in fact quite possible, but this is my 0.02c based on my understanding.

Jack Christensen

OK I couldn't resist, I set up the identical circuit, except just one button, the one on pin 2.  CoolTerm is monitoring and capturing the serial output.  More later.  Here's the code I'm using:
Code: [Select]
void setup(void) {
    pinMode(2, INPUT);

void loop(void) {
    static boolean switchState, lastState;
    switchState = digitalRead(2);
    if (switchState != lastState) {
        Serial.print(millis(), DEC);
        Serial.print(' ');
        Serial.println(switchState, DEC);
        lastState = switchState;

Jack Christensen

Apr 20, 2011, 10:35 pm Last Edit: Apr 20, 2011, 10:48 pm by J Christensen Reason: 1
Update: I added the other switch and modified the code accordingly.  I'll let it run a few hours and report back later this evening.  So far all I have is the following.  The first two lines are intentionally generated the first time through the loop, then I tested each button once.  Amazing, these tact buttons don't bounce much, you sorta gotta try to make 'em do it!
sw2=0 @ 1
sw3=1 @ 2
sw2=1 @ 2107
sw2=0 @ 2373
sw3=0 @ 4164
sw3=1 @ 5681

Code: [Select]
void setup(void) {
   pinMode(2, INPUT);
   pinMode(3, INPUT);
   digitalWrite(3, HIGH);    //turn on internal pullup

void loop(void) {
   boolean sw2, sw3;
   static boolean sw2Last=1, sw3Last=0; //init so that we print the state first time through the loop
   sw2 = digitalRead(2);
   sw3 = digitalRead(3);

   if (sw2 != sw2Last) {
       Serial.print(sw2, DEC);
       Serial.print(" @ ");
       Serial.println(millis(), DEC);
       sw2Last = sw2;
   if (sw3 != sw3Last) {
       Serial.print(sw3, DEC);
       Serial.print(" @ ");
       Serial.println(millis(), DEC);
       sw3Last = sw3;


Apr 20, 2011, 10:37 pm Last Edit: Apr 20, 2011, 10:43 pm by woodsby Reason: 1
@DaveO, the reason I put the 100-ohm resistor immediately in front of pins 2 and 3 is to protect those pins, in the event they ever get set to outputs... unlikely...  but I don't know if it's a bad habit.

In the pin 2 setup, with button open, I have pin 2 connected to ground through the 10K and the 100 ohm resistor, keeping the pin from floating to high.  Remember, as @J mentioned, the tact switch has two pairs of always connected pins- in this case, the two on left keep pin 2 low.  When I close the button, it connect 5V through the path of least resistance (100 ohm) to the pin.

In the pin 3 setup, with button open, the internal 20K pullup keeps the pin from floating to low.  When I close the button, I connect the pin to ground through the 100-ohm resistor.  It seems to me that the pin 3 setup is the safer and smarter setup, and yes the 100-ohm resistor is overkill in this setup.

Again, I am new to this (but trying to learn quickly), so if any of the above is not true, please provide advice.

@J, if you've had it running smooth for the last two hours, you're doing better than me already.  Actually, last night, I got 5 email notifications all night - 11:47, 12:05, 12:45, 3:56 and 4:55.  Since I woke up, they hit at 5:53, 7:48, 1:36, 2:34, and 3:32.  So there doesn't seem to be any pattern at all.  ~58 minutes apart has seemed common though, but it's 4:41 now, and I didn't get one at 4:30, so it's not common enough.

Jack Christensen

DaveO, technically the 100? resistor isn't necessary, but it will provide some protection against the scenario woodsby describes, and neither should it hurt anything.

woodsby, you don't happen to have another Arduino?  You should, you know ;) the darn things are like potato chips...

Tried posting an image but not being successful with the img tags, try this link to see my setup.



I do have another arduino - I started with the SerIO board from Sparkfun, and when I noticed this problem, I ordered an Uno.  Same problem.

As for debouncing, I don't think that will help in this scenario.  Debouncing prevents the bounce, so in my case, it would show the input as floating from low to high, but not show it floating back.  Correct me if I'm wrong.


Debouncing the button is exactly what you need, you just need to change the debounce delay to suit your needs, and modify the code depending on whether you are using pull downs or pull ups. If it detects a change in the button state, it will only update that to the buttonState variable if it has been in its current state for greater than the debounce delay. This will fix your problem. Note that if you are checking button states in your main loop along with other delays, you will have to change those delays according to the blink without delay example, or move your button checking and debouncing to an ISR.

Jack Christensen

As for debouncing, I don't think that will help in this scenario.

I didn't get the feeling this was a debouncing issue, either.  My understanding is that the thing changes level just sitting there, untouched.  Correct?


Yes but regardless of the cause, using a debouncing method will fix it. I don't know how else to explain it, but I will try this. The bounce is caused by the reading changing for a few ms and then changing back. The debounce code only accepts a reading if it has been the same for > 50ms (or whatever you set the debounceDelay to). Thus, it will ignore your bounces. See?

Go Up