Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Push button with Arduino Uno — INPUT_PULLUP wiring and debouncing

Wire a tactile push button to an Arduino Uno R3 on D2 with the internal pull-up (no resistor), debounce it with millis() and toggle the on-board LED.

Arduino C++Verified — core avr 1.8.8, 3 Nov 2026Compile-only

Community draft — report a mistake

A push button is the simplest input there is, yet buttons cause plenty of beginner bugs: presses that happen by themselves, or one press counted three times. Both have standard fixes, and both are in this sketch.

On the Uno you don’t need a resistor at all. Wire one leg to D2 and the diagonal leg to GND, then turn on the chip’s internal pull-up with pinMode(2, INPUT_PULLUP). The pin now reads HIGH at rest and LOW while pressed.

The sketch debounces with millis() instead of delay(), so the rest of your code keeps running. Each clean press toggles the Uno’s on-board L LED and is counted on the Serial Monitor.

Wiring

Arduino Uno R3Only the pins used are shown · 5 V logicPush button (6 mm tactile switch)GNDD212
Every connection
Arduino Uno R3Push button (6 mm tactile switch)WireNotes
D21yellowWith INPUT_PULLUP the pin rests HIGH and reads LOW when pressed.
GND2blackOn a 4-leg button use diagonally opposite legs — legs on the same long side are always joined.

No supply — passive switch part, 5 V board. Wire the button between a GPIO and GND and use the internal pull-up. Never connect a button between a GPIO and 5 V on a 3.3 V board.

Board quirks

  • INPUT_PULLUP turns on a resistor of about 20–50 kΩ inside the ATmega328P, so the button needs only two wires and no external resistor. The logic is inverted: pressed = LOW.
  • A plain INPUT with nothing pulling it floats and reads random HIGH/LOW — touching the wire changes it. This is the most common “my button presses by itself” problem.
  • Contacts bounce for a few milliseconds, so one press can look like five. The sketch only accepts a change once the pin has been steady for 30 ms, and it never blocks with delay().
  • D2 is also an interrupt pin, but don’t use attachInterrupt() for a hand-pressed button — bounce fires it many times. Polling with debounce is simpler and reliable.

Code

button-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// Push button on an Arduino Uno R3 with the internal pull-up and debouncing.
// One leg → D2, the diagonal leg → GND. Not pressed = HIGH, pressed = LOW.
// Each press toggles the on-board "L" LED (D13) and is counted.
const uint8_t BUTTON_PIN = 2;
const unsigned long DEBOUNCE_MS = 30;

bool ledOn = false;
bool stableState = HIGH;
bool lastReading = HIGH;
unsigned long lastChange = 0;
unsigned int presses = 0;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // no external resistor needed
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.println(F("Press the button on D2"));
}

void loop() {
  bool reading = digitalRead(BUTTON_PIN);
  if (reading != lastReading) lastChange = millis();  // contacts bouncing - restart the timer
  lastReading = reading;

  if (millis() - lastChange > DEBOUNCE_MS && reading != stableState) {
    stableState = reading;
    if (stableState == LOW) {  // a clean press
      presses++;
      ledOn = !ledOn;
      digitalWrite(LED_BUILTIN, ledOn);
      Serial.print(F("Press #"));
      Serial.print(presses);
      Serial.println(ledOn ? F(" - LED on") : F(" - LED off"));
    }
  }
}

Expected serial output

Serial Monitor · 9600Output
Press the button on D2
Press #1 - LED on
Press #2 - LED off
Press #3 - LED on

Common errors

The LED toggles on its own or the count jumps

The pin floats: INPUT_PULLUP missing, or the button is wired to 5V instead of GND.

Nothing happens when pressed

Both wires on legs that are already joined inside the button. Move one wire to the diagonally opposite leg.

One press counts twice

Raise DEBOUNCE_MS to 50 for worn or cheap buttons.

↑↓ to move · Enter to open