Digital Read Issue with Button

I simply want to trigger some event when a button is pressed (circuit closed.) I have a wire going from pin 9 to one side of the button and 5v to the other side. I then set pin 9 as a digital input and monitor that pin from the Serial Monitor.

When the button is pressed, everything works perfectly, the Serial Monitor reads a "1" to indicate it is pressed. The problem is that when the button is released, it should just read "0" as the connection is interrupted, but as I view it on the Serial Monitor, the input is toggling quickly between 0's and 1's.

I thought maybe I'd get more precision if I used an Analog read on an anolog pin, but similar problem. When the button is pressed, it reads 1023, the problem is that when it's depressed, the reading changes to a lower number, which is fine, but sometimes jumps up to 1023 and shows a "false" button pressed reading.

I'm assuming both of these are happening because there is some "noise" on the line - any suggestions on getting this fixed.

Ultimately my project is lighting various patterns on an led strip and having the pattern change using a case switch every time the button is pressed. My issue of course is getting that clean reading for the button being pressed.

Any help would be appreciated.

It’s called “bounce.”

Most switches don’t cleanly make connection, but rather, well, bounce a bit.

You need to debounce. While you could do it with delay(), don’t.

Log the millis() when contact is made, and ignore every change for an appropriate number of milliseconds, depending upon your switch.

I don't think this is bounce so much as a floating input. When the switch is open the high-impedance input of the pin is at the mercy of static and stray fields and will react, often rapidly switching high and low.

OP, you need to either:

a) Add a 100K pull-down resistor to control it when the switch is open, or (and much better),
b) change the switch from 5V to ground and set the pinMode to INPUT_PULLUP. This will give much better results (you'll need to change your code to look for LOW instead of HIGH...)

It's indeed not bounce but a floating input. Input pins have a high impedance and can pick up noise from the environment.

Blackfin's solution with the pull-down resistor is one way if you don't want to reverse the logic (HIGH means pressed, LOW means released).

Alternative is to use the internal pull-up and reverse the logic (LOW means pressed, HIGH means released).

void setup()
{
  pinMode(somePin, INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(somePin) == LOW)
  {
    do whatever needs to be done when the button is pressed
  }
}

To make it more readable, you can add a #define like below and test for ISPRESSED instead of LOW

#define ISPRESSED LOW
void setup()
{
  pinMode(somePin, INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(somePin) == ISPRESSED)
  {
    do whatever needs to be done when the button is pressed
  }
}

Thank you Arduino geniuses, that worked perfectly, Karma for everyone.