Arduino Uno Switches

This project demonstrates how to read the state of a push button using an Arduino Uno and display the status via the Serial Monitor. It provides a basic introduction to working with digital inputs.

How It Works

A mechanical switch is the simplest input a microcontroller can read: two contacts that either touch or they do not. What makes switches worth a tutorial is not the switching itself but everything around it — how the pin is biased when the switch is open, and what happens in the milliseconds while the contacts settle.

An unconnected input pin is floating. It has no defined voltage and picks up electrical noise from nearby wiring, so reading it returns a stream of random HIGH and LOW values. A switch must therefore always be paired with a resistor that defines the idle level. The ATmega328P provides this internally: declaring the pin with INPUT_PULLUP connects roughly a 20–50 kΩ resistor to 5 V, so the pin idles HIGH and the switch pulls it to ground when pressed. This inverts the logic — pressed reads LOW — which surprises people the first time.

The second issue is contact bounce. The metal contacts inside a switch are springy, and for 1–20 ms after a press they make and break contact repeatedly. A loop fast enough to see it will count one press as five or ten. Debouncing means ignoring further changes until the signal has been stable for a set period, typically 50 ms.

Components Needed

  • Arduino Uno
  • Push Button
  • Jumper Wires
  • 10k Ohm Resistor (optional, for external pull-down configuration)

Wiring to the Arduino Uno

Wire one leg of the switch to D2 and the other leg directly to GND. No external resistor is needed when the internal pull-up is used. If you prefer an external pull-up, fit a 10 kΩ resistor from D2 to 5 V and declare the pin as plain INPUT.

A four-pin tactile push button is the usual source of confusion: its pins are connected in pairs internally. The pairs sit across the body, so pressing the button bridges the two pairs. If your button appears permanently pressed, rotate it 90° in the breadboard.

The Arduino Uno runs on 5 V logic, which matches the output swing of most hobby modules, so the signal pin connects directly with no level shifting.

Switch terminalConnects toWhy
One legD2The input pin being read
Other legGNDPulls the pin to 0 V when closed
(internal)Pull-up to 5 VEnabled in software with INPUT_PULLUP

Build and Upload

Open the Arduino IDE and create a new sketch.

Copy and paste the provided Arduino code into the sketch.

Upload the code to the Arduino Uno.

Open the serial monitor with a baud rate of 9600.

Press the push button and observe the state change in the Serial Monitor.

Example Code

Debounced switch reading on the Arduino Uno, printing only genuine state changes. Upload it with the board set to Arduino Uno and open the Serial Monitor at 9600 baud.

Debounced switch reading on the Arduino Uno, printing only genuine state changes
const int SWITCH_PIN = 2;
const unsigned long DEBOUNCE_MS = 50;

int stableState   = HIGH;   // idle HIGH thanks to the pull-up
int lastReading   = HIGH;
unsigned long lastChange = 0;

void setup() {
  Serial.begin(9600);
  pinMode(SWITCH_PIN, INPUT_PULLUP);
}

void loop() {
  int reading = digitalRead(SWITCH_PIN);

  // Any edge restarts the settling timer
  if (reading != lastReading) {
    lastChange = millis();
    lastReading = reading;
  }

  // Accept the level only once it has held still long enough
  if (millis() - lastChange > DEBOUNCE_MS && reading != stableState) {
    stableState = reading;
    Serial.println(stableState == LOW ? "PRESSED" : "RELEASED");
  }
}

Applications

A switches turns up in a wide range of projects. These are the uses where it is the right choice rather than a compromise:

  • Power and mode selection on battery-operated instruments
  • Limit and end-stop detection on 3D printers, CNC machines and sliding doors
  • User menus on devices with an LCD or OLED, where a few buttons replace a keypad
  • Safety interlocks that cut a motor when an enclosure lid is opened
  • Reset and calibration triggers held during power-up to enter a service mode

Working with the Arduino Uno

The Arduino Uno is built around the ATmega328P and runs on 5 V logic with 2 KB of SRAM and 32 KB of program flash. These details change how this circuit is wired and what the sketch can do, so they are worth stating plainly before you build.

The Uno runs at 5 V, so most hobby sensor modules connect directly with no level shifting.

With only 2 KB of SRAM, avoid large buffers and prefer the F() macro for constant strings.

The single hardware UART is shared with the USB connection, so heavy Serial printing competes with uploads.

Arduino Uno characteristicValueWhy it matters here
Logic voltage5 VMatches most hobby modules directly
ADC resolution10-bit (0–1023)Sets how finely an analog reading can be resolved
Analog inputsA0–A5 (six channels)Determines how many analog sensors can share the board
PWM outputsD3, D5, D6, D9, D10 and D11Needed for brightness, speed and tone control
I²C pinsA4 (SDA) and A5 (SCL)Fixed by hardware — wiring copied from another board may not match
Interrupt pinsD2 and D3 onlyRequired for counting fast or asynchronous events
Seriala single hardware UART shared with USBMonitor runs at 9600 baud by default

Troubleshooting

Most problems with this module fall into a handful of categories. Work through these before suspecting the part itself:

  • Readings flicker randomly — the pin is floating. Confirm INPUT_PULLUP is set, or add a 10 kΩ external pull-up.
  • One press counts as several — bounce is not being filtered. Raise the debounce window towards 50 ms.
  • The button seems always pressed — a four-pin tactile switch is rotated the wrong way; turn it 90°.
  • Logic looks inverted — with a pull-up, pressed is LOW. Compare against LOW, not HIGH.
  • Code written for an ESP board gives odd analog values — the Arduino Uno uses a 10-bit ADC returning 0–1023; rescale any constant taken from a 12-bit example.
  • An I²C sensor is not found after copying wiring from another Arduino — on the Arduino Uno I²C is on A4 (SDA) and A5 (SCL).

Taking It Further on the Arduino Uno

Once the basic reading works, where you go next depends very much on which board you are using. These are the directions that suit the Arduino Uno specifically:

The Uno’s shield ecosystem is its real advantage. Once the circuit works on a breadboard, a prototyping shield turns it into something permanent that still stacks with a data-logging or Ethernet shield without rewiring.

Logging to an SD card via a shield is the natural next step, since the Uno has no onboard storage and no network. Timestamp each reading with a DS3231 real-time clock so the log survives power cuts with correct times.

Because SRAM is limited to 2 KB, keep logged strings short and write them out immediately rather than buffering. Building a long String in memory is the most common cause of an Uno sketch that runs for hours and then freezes.

Notes and Practical Limits

Using the internal pull-up costs nothing in parts and frees board space, but its value is loose (20–50 kΩ on the ATmega328P). Long cable runs act as antennas and may still pick up noise; in that case fit an external 4.7 kΩ pull-up, which holds the line more firmly.

For switches that must wake the board from sleep, mount them on an interrupt-capable pin — on the Arduino Uno that means D2 and D3 only.