Welcome to this comprehensive guide on using buttons with your Arduino MKR WiFi 1010! Buttons might seem straightforward—press to connect, release to disconnect—but their mechanical nature introduces challenges that trip up even experienced makers. This tutorial tackles those issues head-on, showing you proper wiring, clean code practices, and troubleshooting techniques.
What You'll Master:
Understanding button mechanics and internal connections
Solving the notorious "floating input" problem
Proper use of pull-up and pull-down resistors
Detecting button presses, releases, and state changes
Recognizing and handling the chattering phenomenon
※ NOTE THAT:
Critical Beginner Pitfalls (Read This First!)
Before we dive into button basics, let's address two fundamental issues that cause 90% of button-related frustrations:
1. Floating Input Issue (Random Readings)
What happens: You wire up a button, but readings bounce randomly between HIGH and LOW—even when you're not touching it. Your project behaves erratically.
Why it happens: When the button is open (not pressed), the input pin is electrically "floating"—not connected to anything. It picks up electromagnetic interference from your environment like an antenna, causing random voltage readings.
The fix: Always use a pull-up or pull-down resistor. These resistors "pull" the input to a known state (HIGH or LOW) when the button isn't pressed, ensuring predictable readings.
Details: Covered thoroughly in sections below.
2. Chattering (Multiple False Triggers)
What happens: You press the button once, but your Arduino registers 3-10 rapid presses. Counters increment wildly, and state machines go haywire.
Why it happens: Button contacts don't close cleanly. For about 1-20 milliseconds during physical contact, the metal contacts bounce against each other, rapidly connecting and disconnecting. Your Arduino samples these bounces as separate press events.
When it matters: Critical for counting button presses (click counter, game controller) or toggling states (ON/OFF switch simulation). Not a problem if you just want to know "is button currently held down?"
The fix: Use software debouncing (code-based filtering) or hardware debouncing (capacitor circuit). See our dedicated Arduino MKR WiFi 1010 - Button Debounce tutorial.
Quick Rule: Every button project needs pull-up/pull-down resistors. Projects that count presses or detect edges also need debouncing.
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. Additionally, some of these links are for products from our own brand, DIYables .
Overview of Button
A push button, also known as a pushbutton, tactile button, or momentary switch, is a switch that closes when you press and hold it, and opens when you let go. There are many kinds of push buttons, usually divided into two groups:
PCB-mount push buttons (suitable for breadboard mounting)
Most breadboard-friendly tactile buttons have four pins arranged in pairs. Here's the critical detail: Pins are internally connected in pairs!
Pin layout: Opposite pins (across the button) are always connected internally
Usage: You only need two pins that are NOT directly connected—typically one from each side
Why four pins? Mechanical stability! When you press a button, you apply force. Four pins distribute that force, preventing the button from tilting or popping out of the breadboard/PCB.
Valid Connection Combinations:
There are four possible ways to choose two pins, but due to symmetry, only two unique electrical configurations exist. We'll refer to properly selected pins as Pin A and Pin B (not internally connected).
Testing Your Button: Unsure which pins are connected? Use a multimeter in continuity mode. Test all six possible pin combinations to identify which pairs are always connected (avoid these pairs) and which connect only when pressed (use these).
Panel-Mount Buttons (2-Pin Buttons)
image source: diyables.io
These industrial-style buttons feature just two terminals, making wiring straightforward. No confusing pin pairs—just two contacts that connect when pressed. Perfect for permanent installations where you're not using a breadboard.
Button Modules (3-Pin Smart Buttons)
Button modules are beginner-friendly pre-built circuits featuring:
GND: Connect to Arduino ground
VCC: Connect to 3.3V or 5V power (check module specs)
OUT: Digital output signal to Arduino input pin
Built-in intelligence: These modules include a pull-down resistor already soldered on the PCB! Output is LOW when not pressed, HIGH when pressed—no external resistor required. They also often include debouncing circuits and LED indicators.
Trade-off: Modules are more expensive and take up more space, but they're perfect for learning without worrying about resistor calculations.
How Buttons Work (The Mechanics)
Buttons are simple mechanical switches with two states:
Button RELEASED (default): Pin A and Pin B are physically separated by an air gap—no electrical connection exists. Open circuit.
Button PRESSED: Internal spring mechanism forces metal contacts together, creating an electrical connection. Pin A connects to Pin B. Closed circuit.
Key Insight: The button doesn't generate voltage or signals—it's purely a mechanical switch. Think of it like a drawbridge: down (pressed) = traffic flows, up (released) = traffic stops. The Arduino provides the voltage; the button just controls whether it flows or not.
Arduino MKR WiFi 1010 - Button Integration
To read button presses, we connect the button between an Arduino digital input pin and a voltage rail (VCC or GND). The Arduino's digitalRead() function then reports whether the button is pressed or released.
Basic Circuit:
One button pin → Arduino digital input pin (e.g., D2)
Other button pin → VCC (3.3V) or GND (0V)
The challenge? When the button is NOT pressed, the input pin is floating (connected to nothing), causing unreliable readings. We solve this with resistors.
Input State vs. Pressing State (The Resistor Relationship)
The relationship between physical button state (pressed/released) and electrical pin state (HIGH/LOW) depends on your wiring configuration and resistor choice. There are two standard methods:
Method 1: Pull-Down Resistor Configuration (Button to VCC)
Wiring:
Button pin 1 → Arduino digital input pin
Button pin 2 → VCC (3.3V power)
Pull-down resistor (10kΩ) → Between input pin and GND
Behavior: Pressed = LOW, Released = HIGH (inverted logic)
※ NOTE THAT:
Why Resistors Are Mandatory
Without a pull-up or pull-down resistor, the input pin becomes electrically floating when the button is released. Floating pins:
Act like antennas, picking up electromagnetic noise
Read random HIGH/LOW values (completely unpredictable)
Cause erratic behavior—LEDs flickering, counters incrementing randomly, etc.
Can even change readings when you wave your hand near the circuit!
Analogy: Imagine a light switch that's neither fully ON nor fully OFF—it flickers randomly depending on nearby interference. Resistors "pull" the switch to a definite position.
Recommended Approach for Beginners
The Arduino MKR WiFi 1010 has built-in pull-up resistors on every digital pin! Enable them in code with:
Reliable—internal resistors are well-matched to Arduino specs
Configuration: Button between input pin and GND. Use inverted logic (pressed = LOW).
This tutorial uses INPUT_PULLUP for simplicity. All code examples reflect this approach.
Wiring Diagrams
These diagrams show the recommended pull-up resistor configuration (button to GND, internal pull-up enabled in code).
PCB-Mount Button (Breadboard-Friendly)
This image is created using Fritzing. Click to enlarge image
Connections:
Button pin (one side) → Arduino digital pin D2
Button pin (opposite side) → Arduino GND
No external resistor needed—internal pull-up used!
Remember: Use pins that are NOT internally connected (opposite corners of the button).
Panel-Mount Button (2-Pin)
This image is created using Fritzing. Click to enlarge image
Connections:
Button terminal 1 → Arduino digital pin D2
Button terminal 2 → Arduino GND
Internal pull-up configured in code
Pro Tip: Panel-mount buttons are ideal for enclosure-mounted controls. Drill a hole in your project box and secure the button with its included nut.
Programming Button Input
Pin Configuration (Setup Phase)
Configure the digital pin as an input with internal pull-up resistor enabled:
pinMode(2, INPUT_PULLUP); // Configure D2 as input, activate internal pull-up
What this does:
Sets pin D2 as an INPUT (not outputting voltage)
Activates the internal 10kΩ pull-up resistor
Pin defaults to HIGH when button is not pressed
Reading Button State (Loop Phase)
Read the current electrical state of the input pin:
int button_state = digitalRead(BUTTON_PIN); // Returns HIGH or LOW
Return values:
HIGH (1) = Button NOT pressed (pull-up resistor pulls to 3.3V)
LOW (0) = Button IS pressed (pin connected to GND)
Two Programming Approaches
※ NOTE THAT:
There are two common ways to use this:
First way: If the input is HIGH, do one action; if the input is LOW, do another action.
Second way: If the input changes from LOW to HIGH, do one action; if it changes from HIGH to LOW, do another action.
Which way you choose depends on what you need. For example, when using a button to control an LED:
If you want the LED to turn ON when the button is pressed and turn OFF when it is not pressed, use the first way.
If you want the LED to switch between ON and OFF every time you press the button, use the second way.
This sample code shows how to check when the state changes from LOW to HIGH.
#define BUTTON_PIN D2 // Button connected to D2int prev_state = HIGH; // Holds the previous button stateint button_state; // Stores the current button statevoidsetup() {Serial.begin(9600);// Configure the button pin with the internal pull-up resistor enabledpinMode(BUTTON_PIN, INPUT_PULLUP);}voidloop() {// Obtain the current state of the button button_state = digitalRead(BUTTON_PIN);if(prev_state == LOW && button_state == HIGH)Serial.println("The state changed from LOW to HIGH");// Update the previous state for the next cycle prev_state = button_state;}
Connect the components to the Arduino MKR WiFi 1010 board as depicted in the diagram
Plug your Arduino MKR WiFi 1010 into your computer's USB port
Launch the Arduino IDE on your computer
Select the Arduino MKR WiFi 1010 board and its COM port
Copy the following code and paste it into the Arduino IDE.
#define BUTTON_PIN 2 // Arduino Nano 33 IoT pin D2 pin connected to buttonvoidsetup() {// Initialize the Serial to communicate with the Serial Monitor.Serial.begin(9600);// initialize the button pin as an pull-up input (HIGH when the switch is open and LOW when the switch is closed)pinMode(BUTTON_PIN, INPUT_PULLUP);}voidloop() {// read the state of the switch/button:int button_state = digitalRead(BUTTON_PIN);// print out the button's stateSerial.println(button_state);}
Click the Upload button in the Arduino IDE to build your program and send it to your Arduino MKR WiFi 1010 board.
Open the Serial Monitor in the Arduino software.
Press and let go of the button several times.
Look at the output on the Serial Monitor. It should look like what is shown below.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino MKR WiFi 1010
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino MKR WiFi 1010' on 'COM15')
New Line
9600 baud
1
1
1
0
0
0
0
0
0
1
1
1
Ln 11, Col 1
Arduino MKR WiFi 1010 on COM15
2
1 means high, and 0 means low.
Line-by-line Code Explanation
The Arduino MKR WiFi 1010 code above shows an explanation for each line. Please look at the comments in the code!
Modifying Arduino MKR WiFi 1010 Code
Let's change the code so it can see when something is pressed and let go.
Detailed Instructions
Change the code as shown below.
/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-button */#define BUTTON_PIN 2 // Arduino Nano 33 IoT pin D2 pin connected to buttonint prev_state = LOW; // The previous state from the input pinint button_state; // The current reading from the input pinvoidsetup() {// Initialize the Serial to communicate with the Serial Monitor.Serial.begin(9600);// initialize the button pin as an pull-up input (HIGH when the switch is open and LOW when the switch is closed)pinMode(BUTTON_PIN, INPUT_PULLUP);}voidloop() {// read the state of the switch/button: button_state = digitalRead(BUTTON_PIN);if (prev_state == HIGH && button_state == LOW)Serial.println("The button is pressed");elseif (prev_state == LOW && button_state == HIGH)Serial.println("The button is released");// save the the last state prev_state = button_state;}
Click the Upload button on the Arduino IDE to compile and send the code to the Arduino MKR WiFi 1010 board.
Open the Serial Monitor in the Arduino IDE.
Press and then release the button.
Look at the result on the Serial Monitor. It should look like the image below.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino MKR WiFi 1010
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino MKR WiFi 1010' on 'COM15')
New Line
9600 baud
The button is pressed
The button is released
Ln 11, Col 1
Arduino MKR WiFi 1010 on COM15
2
※ NOTE THAT:
The Serial Monitor might show several press and release messages even if you only pressed and released the button once. This is normal and is known as the chattering phenomenon. In some projects, you need a way to remove this extra information. You can find out more in the Arduino MKR WiFi 1010 - Button Debounce tutorial.
To keep things simple for beginners, especially when using several buttons, we made a library called ezButton. You can learn more about it here: https://arduinogetstarted.com/tutorials/arduino-button-library.
When using the button module, set the pin as an input by using pinMode(BUTTON_PIN, INPUT). The module gives a LOW signal when not pressed and a HIGH signal when pressed.
Video Tutorial
Additional Knowledge
When should I use a pull-down or pull-up resistor, and when should I not?
SHOULD: When a sensor has two conditions—closed or open—you need to add a pull-up or pull-down resistor. This resistor helps change the conditions into two clear levels: LOW and HIGH. Examples include push-buttons, switches, and magnetic door sensors.
SHOULD NOT: When the sensor already gives two clear voltage levels (LOW and HIGH), you do not need a pull-up or pull-down resistor. Examples include motion sensors and touch sensors.
Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!