Arduino MKR WiFi 1010 - Button - Debounce

Welcome to this essential guide on button debouncing with the Arduino MKR WiFi 1010! If you've ever experienced unreliable button behavior—where one press registers as multiple presses—this tutorial will solve that frustrating problem.

Understanding the Chattering Problem

Here's a question: When you press or release a button once, does its electrical state change exactly once from LOW to HIGH (or HIGH to LOW)?

You might think: Yes, one press = one state change.

The reality: No! In the physical world, mechanical buttons don't make clean transitions. When you press a button, the metal contacts inside bounce against each other multiple times before settling. This happens incredibly fast—within milliseconds—but microcontrollers like the Arduino are fast enough to detect each bounce as a separate press!

Arduino MKR WiFi 1010 chattering phenomenon

This phenomenon is called chattering or bounce, and it causes serious problems:

The solution is called debouncing—a technique to filter out these false signals and detect only genuine button presses.

What You'll Learn:

Hardware Preparation

1×Arduino MKR WiFi 1010
1×Micro USB Cable
1×Breadboard-mount Button with Cap
1×Breadboard-mount Button Kit
1×Panel-mount Push Button
1×Push Button Module
1×Breadboard
1×Jumper Wires
1×Optionally, DC Power Jack

Or you can buy the following kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
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

Before tackling debouncing, you should understand basic button operation with Arduino. If you're new to buttons, we highly recommend starting with our foundational button tutorial.

Prerequisite Tutorial: Arduino MKR WiFi 1010 - Button tutorial

This foundational guide covers:

  • How push buttons work electrically
  • Pull-up and pull-down resistors
  • Reading button states with digitalRead()
  • Basic button wiring to Arduino pins
  • Understanding pressed vs released states

Once you're comfortable reading button states, debouncing becomes a straightforward extension—you're just adding timing logic to filter out noise.

Wiring Diagram

Connect a button to your Arduino MKR WiFi 1010 as shown. This simple circuit will let us demonstrate the chattering problem and its solution.

The wiring diagram between Arduino MKR WiFi 1010 Button

This image is created using Fritzing. Click to enlarge image

Our Testing Strategy: To clearly demonstrate why debouncing is necessary, we'll run two experiments:

  1. Without Debouncing: You'll see the chattering problem in action
  2. With Debouncing: You'll see the clean, reliable button detection

Comparing these two approaches will make the value of debouncing crystal clear!

Reading Button Without Debounce

Let's first see the problem in action. This code reads the button state directly without any debouncing. Watch what happens!

Detailed Instructions

New to Arduino MKR WiFi 1010? Complete our Getting Started with Arduino MKR WiFi 1010 tutorial first to set up your development environment.

  • 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 code below and paste it into the Arduino IDE
/* * 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-debounce */ #define BUTTON_PIN 2 // Arduino Nano 33 IoT pin D2 pin connected to button int prev_state = LOW; // The previous state from the input pin int button_state; // The current reading from the input pin void setup() { // 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); } void loop() { // 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"); else if (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 to compile and upload
  • Open the Serial Monitor
  • Press the button and hold it for a few seconds, then release
  • Observe the results on the Serial Monitor
COM6
Send
The button is pressed The button is pressed The button is pressed The button is released The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

What Happened? You pressed the button once and released it once, but the Serial Monitor shows multiple press and release events! This is chattering in action.

Why This Happens: When the button contacts touch, they don't make a solid connection immediately. They bounce apart and together several times within 5-50 milliseconds. Your Arduino, running at millions of cycles per second, detects each bounce as a separate state change.

※ NOTE THAT:

Testing Note: Chattering doesn't occur consistently—it depends on how you press the button, the button's mechanical quality, and even environmental factors like temperature. If you don't observe chattering on your first try, test several times with different pressing speeds and pressures. You'll likely see it appear.

Reading Button With Debounce

Now let's solve the problem! This code implements debouncing using millis() timing. It ignores state changes that happen within a short time window (typically 50ms), filtering out the bounces.

Detailed Instructions

  • Copy the code below and paste it into your Arduino IDE.
/* * 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-debounce */ #define BUTTON_PIN 2 // Arduino Nano 33 IoT pin D2 pin connected to button #define DEBOUNCE_TIME 50 // The debounce time in millisecond, increase this time if it still chatters int prev_state_steady = LOW; // The previous steady state from the input pin int prev_state_flick = LOW; // The previous flickerable state from the input pin int button_state; // The current reading from the input pin unsigned long last_debounce_time = 0; // The last time the output pin was toggled void setup() { // 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); } void loop() { // read the state of the switch/button: button_state = digitalRead(BUTTON_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch/button changed, due to noise or pressing: if (button_state != prev_state_flick) { // reset the debouncing timer last_debounce_time = millis(); // save the the last flickerable state prev_state_flick = button_state; } if ((millis() - last_debounce_time) > DEBOUNCE_TIME) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // if the button state has changed: if(prev_state_steady == HIGH && button_state == LOW) Serial.println("The button is pressed"); else if(prev_state_steady == LOW && button_state == HIGH) Serial.println("The button is released"); // save the the last steady state prev_state_steady = button_state; } }
  • Click the Upload button to compile and upload
  • Open the Serial Monitor
  • Press and hold the button for a few seconds, then release
  • Observe the results on the Serial Monitor
COM6
Send
The button is pressed The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Success! Now you see exactly one press event and one release event—matching your physical button action perfectly. The false signals have been eliminated!

How Debouncing Works: The code uses millis() to track time. When it detects a state change, it waits 50 milliseconds before checking again. During this "debounce period," any additional state changes are ignored. After 50ms, the bouncing has settled, and the button is in its true stable state.

The 50ms delay is:

  • Long enough to let mechanical bouncing settle
  • Short enough that users don't perceive any lag
  • A good default for most buttons (adjust if needed for specific hardware)

We Made It Simple - Button Debounce with ezButton Library

While the manual millis() approach works, implementing debouncing for multiple buttons gets complex quickly. You need separate timing variables for each button, careful state tracking, and lots of repetitive code.

Enter the ezButton Library: We created this library specifically to make button handling simple and reliable, especially for beginners and multi-button projects.

Why Use ezButton?

  • Automatic Debouncing: Built-in debounce handling—no timing code needed
  • Clean Syntax: Simple, readable methods like isPressed() and isReleased()
  • Multiple Buttons: Easily manage many buttons without complexity explosion
  • Additional Features: Press duration, count presses, state changes, and more
  • Proven and Tested: Used in thousands of projects worldwide

Learn more: Arduino Button Library Tutorial

Arduino MKR WiFi 1010 Button Debounce Code for A Single Button

Here's how simple it becomes with ezButton:

/* * 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-debounce */ #include <ezButton.h> #define DEBOUNCE_TIME 50 // Set debounce duration in milliseconds; increase if button chatter persists ezButton button(D2); // Instantiate an ezButton for digital pin D2 void setup() { Serial.begin(9600); button.setDebounceTime(DEBOUNCE_TIME); // Configure the button's debounce duration to 50 ms } void loop() { button.loop(); // Call the loop() method first to update the button state if (button.isPressed()) Serial.println("The button is pressed"); if (button.isReleased()) Serial.println("The button is released"); }

Arduino MKR WiFi 1010 Button Debounce Code for Multiple Buttons

Handling multiple buttons is where ezButton really shines. Instead of managing separate timing variables for each button, you simply create multiple button objects. The library handles everything!

Example: Let's debounce three buttons simultaneously.

The wiring diagram

The wiring diagram between Arduino MKR WiFi 1010 Button Library

This image is created using Fritzing. Click to enlarge image

/* * 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-debounce */ #include <ezButton.h> #define DEBOUNCE_TIME 50 // define debounce duration in milliseconds, adjust upward if button chatter persists ezButton button1(D6); // instantiate an ezButton object for digital pin D6 ezButton button2(D7); // instantiate an ezButton object for digital pin D7 ezButton button3(D8); // instantiate an ezButton object for digital pin D8 void setup() { Serial.begin(9600); button1.setDebounceTime(DEBOUNCE_TIME); // apply debounce duration of 50 milliseconds to button1 button2.setDebounceTime(DEBOUNCE_TIME); // apply debounce duration of 50 milliseconds to button2 button3.setDebounceTime(DEBOUNCE_TIME); // apply debounce duration of 50 milliseconds to button3 } void loop() { button1.loop(); // call loop() method to update button1 state button2.loop(); // call loop() method to update button2 state button3.loop(); // call loop() method to update button3 state if (button1.isPressed()) Serial.println("The button 1 is pressed"); if (button1.isReleased()) Serial.println("The button 1 is released"); if (button2.isPressed()) Serial.println("The button 2 is pressed"); if (button2.isReleased()) Serial.println("The button 2 is released"); if (button3.isPressed()) Serial.println("The button 3 is pressed"); if (button3.isReleased()) Serial.println("The button 3 is released"); }

Video Tutorial

Additional Knowledge

Choosing Debounce Time

The optimal DEBOUNCE_TIME value depends on your specific hardware:

  • Typical Range: 20-50ms works for most buttons
  • High-Quality Buttons: May need only 10-20ms
  • Cheap/Old Buttons: Might require 50-100ms
  • Switches: Toggle and slide switches often need longer (50-100ms)

How to Find Your Value: Start with 50ms. If you still see occasional double-triggers, increase it in 10ms increments until behavior is reliable.

Debouncing Other Devices

Debouncing isn't just for buttons! These devices also benefit from debouncing:

  • Toggle/Slide Switches: Any mechanical switch can chatter
  • Limit Switches: Common in CNC and robotics
  • Reed Switches: Magnetic sensors used in door/window sensors
  • Touch Sensors: Can have electrical noise requiring debouncing

The same debouncing techniques apply to all these devices—they're all reading digital inputs that can have noisy transitions!

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • 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!