Board and part

Arduino Mega Button Simulator: Wiring, Code and a Live Circuit

This is a pushbutton wired to an Arduino Mega 2560, with a debounced press counter running live: hold the button on the drawing and the serial monitor counts each press exactly once.

  • 5 V logic
  • No library
  • Input on pin 2
  • Internal pull-up, 20 ms debounce
Arduino Mega · Buttonlive0.000 s 0.00x
Hold the button
The circuit itself, running on the simulator with the sketch below. Press what can be pressed; click anything else to open it in the editor.
Connections

Wiring the Button to the Arduino Mega

Two wires and no resistor: pin 2 to one side of the button, GND to the other, and the Arduino Mega’s internal pull-up does the rest.

Every connection in the circuit above, with the board’s own pin names.

Button pinArduino Mega pinWhy
One side (1a)pin 2With INPUT_PULLUP the ATmega2560’s own resistor holds the pin high.
The other side (2a)GNDPressing connects the pin to ground, so it reads LOW.

Power

No resistor and no supply wire: the ATmega2560’s internal pull-up ties the pin to 5 V until the button pulls it to ground.

Pins to leave alone on the Arduino Mega

Pins 14 to 19 are the three extra serial ports and 20 and 21 are I2C, so keep them free if you will need those. An Uno shield’s I2C on A4 and A5 is not connected to anything on a Mega.

On a real bench

The Mega is long, so put the breadboard beside its double row of pins 22 to 53 and leave the left-hand headers free. The Button uses only a few of its 54 pins; a Mega earns its size when one sketch drives a keypad, a display and several sensors at once.

The sketch

The code, and what it does.

The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.

Debounced button on Arduino Mega pin 2
const int BUTTON_PIN = 2;   // pin 2 to the button, the button to GND
const unsigned long DEBOUNCE_MS = 20;

int lastReading = HIGH;
int state = HIGH;
unsigned long changedAt = 0;
unsigned int presses = 0;

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);   // HIGH when up, LOW when pressed
  Serial.println("Press the button");
}

void loop() {
  int reading = digitalRead(BUTTON_PIN);
  if (reading != lastReading) changedAt = millis();
  lastReading = reading;
  if (millis() - changedAt > DEBOUNCE_MS && reading != state) {
    state = reading;
    if (state == LOW) {
      presses++;
      Serial.print("Pressed, count ");
      Serial.println(presses);
    }
  }
}

pinMode(BUTTON_PIN, INPUT_PULLUP) turns on the pull-up inside the chip, so the pin reads HIGH while the button is up and LOW while it is held. That is backwards from what most people expect the first time, and it saves a resistor.

A real button bounces: for a few milliseconds after it closes, the contacts open and close many times. The sketch notes the time of every change and only accepts a new state once the reading has stayed put for 20 ms, so one press counts once. The simulated button bounces like a real one, so you can see it fail by setting DEBOUNCE_MS to 0.

Serial.begin(9600) opens the serial monitor. Serial is the USB port; Serial1 to Serial3 are on pins 18 and 19, 16 and 17, and 14 and 15.

Pitfalls

Common mistakes with the Button on the Arduino Mega

A floating input

With plain INPUT and no resistor, the pin reads whatever noise is nearby and the sketch sees presses nobody made. Use INPUT_PULLUP, or a 10 k resistor to the supply.

Counting the bounce

Without a debounce, one press can count as three or four. The simulated button bounces for a few milliseconds the way real contacts do, so the fix here is the fix on a desk.

Taking the serial or I2C pins

Pins 0 and 1 are the USB serial port, 14 to 19 are Serial1 to Serial3 and 20 and 21 are I2C. the button works on any of them until the sketch needs that port, so start on pin 2 and up.

FAQ

Questions and answers

Can I simulate a button with an Arduino Mega 2560?

Yes. The circuit at the top of this page is an Arduino Mega 2560 with a pushbutton, running in your browser on a simulated ATmega2560. Hold the button on the drawing to press it; the contacts bounce like a real switch. Press Run it in the editor to change the wiring or the code; it is free and needs no account.

Why does the button read LOW when pressed?

Because the pull-up holds the pin HIGH and the button connects it to ground. Compare with LOW in the code, or wire the button to the supply with a pull-down resistor if you want the opposite.

Should I use attachInterrupt() for a button?

You can, but an interrupt fires on every bounce too, so it still needs a debounce. Polling every pass of loop() is simpler and fast enough for a person.

Is there a library for buttons?

Bounce2.h, OneButton.h and AceButton.h all compile here. The sketch above does the same job in a dozen lines, which is worth understanding before reaching for one.

Build your own Button project

Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.