Switches

The Switches project demonstrates how to read the state of a switch using an Arduino Nano. Switches, also known as push buttons, are simple input devices used to toggle between two states: ON and OFF. They are widely used in various electronic applications, including control panels, user interfaces, and interactive systems.

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 Nano
  • Switches module
  • Arduino Nano
  • USB cable for programming and power
  • Arduino Nano

Wiring to the Arduino Nano

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 Nano 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 paste the provided code.

Upload the code to the Arduino Nano.

Once the code is uploaded, open the serial monitor.

Press the switch and observe the state change displayed in the serial monitor.

Release the switch and observe the state change again.

Example Code

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

Debounced switch reading on the Arduino Nano, 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 Nano

The Arduino Nano 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 Nano shares the Uno’s ATmega328P but adds A6 and A7, which are analog-input only and cannot be used as digital pins.

Its DIP footprint drops straight into a breadboard, which suits permanent sensor builds.

Older clones use the CH340 USB bridge and may need that driver plus the "ATmega328P (Old Bootloader)" processor option.

Arduino Nano 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–A7 (eight channels, two more than the Uno)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 Nano 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 Nano I²C is on A4 (SDA) and A5 (SCL).

Taking It Further on the Arduino Nano

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 Nano specifically:

The Nano’s DIP footprint makes it the natural choice once a breadboard prototype becomes a soldered build. Mount it on female headers rather than soldering it down, so the board can be recovered if the project is retired.

With A6 and A7 available in addition to A0–A5, the Nano can read two more analog sensors than an Uno. Remember that those two pins are analog-input only — they cannot be used with digitalWrite or as digital inputs.

For battery-powered builds, the Nano’s regulator and USB bridge dominate idle current. Powering the 5V pin directly from a regulated supply and removing the power LED substantially extends runtime.

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 Nano that means D2 and D3 only.