Arduino UNO Q - Button - Debounce

When programming Arduino UNO Q to detect a button press, a single press might be detected multiple times. This happens because mechanical contacts rapidly bounce between LOW and HIGH — a phenomenon called chattering. This tutorial shows you how to fix it through debouncing.

Arduino UNO Q chattering phenomenon
Arduino UNO Q - Button Debounce

Hardware Preparation

1×Arduino UNO Q
1×USB Cable for Arduino Uno Q
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×Recommended: Screw Terminal Block Shield for Arduino Uno
1×Recommended: Sensors/Servo Expansion Shield for Arduino Uno
1×Recommended: Breadboard Shield for Arduino Uno
1×Recommended: Enclosure for Arduino Uno
1×Recommended: Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

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

Learn about buttons (pinout, wiring, how they work) in the Arduino UNO Q - Button tutorial.

Wiring Diagram

The wiring diagram between Arduino UNO Q Button

This image is created using Fritzing. Click to enlarge image

MCU Code — Without Debounce (for comparison)

The Arduino UNO Q has two processors: the STM32 MCU (handles real-time hardware control) and the Qualcomm MPU (runs Debian Linux). In this section, only the STM32 MCU is programmed — the Linux side stays idle. A later section will show how both processors work together.

This is the version without debounce from the Button tutorial. Notice how a single press may register multiple events:

/* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ #define BUTTON_PIN 7 // The Arduino UNO Q pin connected to the button int button_state; int prev_button_state = HIGH; // HIGH = not pressed (pull-up) void setup() { // initialize the pushbutton pin as a pull-up input pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the button (LOW = pressed, HIGH = not pressed) button_state = digitalRead(BUTTON_PIN); if (prev_button_state == HIGH && button_state == LOW) { // button was just pressed (HIGH → LOW transition) // TO DO: add your press action here } else if (prev_button_state == LOW && button_state == HIGH) { // button was just released (LOW → HIGH transition) // TO DO: add your release action here } // save the last state prev_button_state = button_state; }

Detailed Instructions

  • First time with Arduino UNO Q? Follow the Getting Started with Arduino UNO Q tutorial to get your development environment ready before proceeding.
  • Wire the button: Connect one button pin to GND and the other to pin 7 according to the wiring diagram.
  • Connect: Plug the Arduino UNO Q into your computer with a USB-C cable.
  • Open Arduino App Lab: Launch Arduino App Lab and wait until it detects your Arduino UNO Q.
  • Create a new App: Click the Create New App button.
Create New App in Arduino App Lab on Arduino UNO Q
  • Give the App a name, for example: DIYables_ButtonDebounce
  • Click Create to confirm.
  • You will see a set of folders and files generated inside your new App.
Arduino App Lab App folders and files on Arduino UNO Q
  • Find the sketch/sketch.ino file — this is where you will paste the MCU sketch.
  • Paste the sketch: Copy the no-debounce code above and paste it into the sketch file. Keep other files as default.
  • Upload: Click the Run button in Arduino App Lab to compile and upload to the STM32.
  • Click Run button in Arduino App Lab on Arduino UNO Q
    • Press the button once then release it — observe that multiple events may be logged (visible via the Bridge Monitor in the next section).
    • Notice: This is the chattering effect — the next section fixes it.

    MCU Code — With Debounce (using millis)

    This version uses millis() to wait for the signal to stabilize before treating it as a real event. Only state changes that persist for more than DEBOUNCE_TIME milliseconds are accepted:

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ #define BUTTON_PIN 7 // The Arduino UNO Q pin connected to the button #define DEBOUNCE_TIME 50 // The debounce time in milliseconds; increase if output flickers int last_steady_state = LOW; // the previous stable state from the input pin int last_flickerable_state = LOW; // the previous flickerable state from the input pin int current_state; // the current reading from the input pin unsigned long last_debounce_time = 0; // the last time the state changed void setup() { // initialize the pushbutton pin as a pull-up input pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the current state of the button current_state = digitalRead(BUTTON_PIN); // if the state changed (due to noise or a press/release), reset the debounce timer if (current_state != last_flickerable_state) { last_debounce_time = millis(); last_flickerable_state = current_state; } if ((millis() - last_debounce_time) > DEBOUNCE_TIME) { // the state has been stable for DEBOUNCE_TIME ms — treat it as real if (last_steady_state == HIGH && current_state == LOW) { // TO DO: button pressed action here } else if (last_steady_state == LOW && current_state == HIGH) { // TO DO: button released action here } last_steady_state = current_state; } }
    • How it works: If the button state changes rapidly (bouncing), the timer resets each time. Only when the state is stable for 50ms is it treated as a real press or release.
    • Pro Tip: If your button still shows multiple events, try increasing DEBOUNCE_TIME to 75 or 100.

    ※ NOTE THAT:

    The optimal DEBOUNCE_TIME depends on the button quality and the application. 50ms is a safe default for most push buttons.

    Simpler Debounce with the ezButton Library

    For beginners and multi-button projects, we built the ezButton library — it handles INPUT_PULLUP, debounce, and edge detection automatically.

    Single button with ezButton:

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ #include <ezButton.h> ezButton button(7); // create ezButton object attached to pin 7 void setup() { button.setDebounceTime(50); // set debounce time to 50 milliseconds } void loop() { button.loop(); // MUST call the loop() function first if (button.isPressed()) { // TO DO: button pressed action here } if (button.isReleased()) { // TO DO: button released action here } }
    • Install the library: Click the Add sketch library button (the open book icon with a + sign) in the left sidebar.
    Add sketch library in Arduino App Lab on Arduino UNO Q
    • Search for ezButton created by ArduinoGetStarted.com and click the Install button.
    My Apps / DIYables Apps
    Run
    Bricks
    No bricks added...
    Sketch Libraries
    No sketch libra...
    Files
    python
    sketch
    .gitignore
    README.md
    app.yaml
    sketch.ino
    Add sketch library
    ezButton ArduinoGetStarted.com

    Button library supports debounce, pressed/released events and the press counting. It is easy to use with multiple buttons. The library can be used for push-button, momentary switches, toggle switch, magnetic contact switch (door sensor)... It is designed for not only beginners but also experienced users.

    1.0.6
    Install
    More Info
    • Search for Arduino_RouterBridge created by Arduino and click the Install button.
    My Apps / DIYables Apps
    Run
    Bricks
    No bricks added...
    Sketch Libraries
    No sketch libra...
    Files
    python
    sketch
    .gitignore
    README.md
    app.yaml
    sketch.ino
    Add sketch library
    Arduino_RouterBridge Arduino

    This library provides a simple RPC bridge for Arduino UNO Q boards, allowing communication between the board and other devices using MsgPack serialization.

    0.4.1
    Install
    More Info
    • How it works: button.loop() must be called every loop cycle. Then button.isPressed() returns true exactly once per physical press, and button.isReleased() returns true exactly once per release — no chattering.

    Multiple buttons with ezButton (three buttons on pins 6, 7, 8):

    The wiring diagram between Arduino UNO Q Multiple Button

    This image is created using Fritzing. Click to enlarge image

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ #include <ezButton.h> ezButton button_1(6); // ezButton object on pin 6 ezButton button_2(7); // ezButton object on pin 7 ezButton button_3(8); // ezButton object on pin 8 void setup() { button_1.setDebounceTime(50); button_2.setDebounceTime(50); button_3.setDebounceTime(50); } void loop() { button_1.loop(); button_2.loop(); button_3.loop(); if (button_1.isPressed()) { /* button 1 pressed action */ } if (button_1.isReleased()) { /* button 1 released action */ } if (button_2.isPressed()) { /* button 2 pressed action */ } if (button_2.isReleased()) { /* button 2 released action */ } if (button_3.isPressed()) { /* button 3 pressed action */ } if (button_3.isReleased()) { /* button 3 released action */ } }

    Linux + MCU Bridge Programming

    The Arduino UNO Q has two processors that work together: the MPU (Qualcomm, runs Debian Linux) and the MCU (STM32, runs Zephyr OS with your Arduino sketch). They communicate using RPC via the Arduino_RouterBridge library — never via raw serial ports.

    • The button is connected to the MCU (STM32) — wired to a digital input pin on the STM32. The MCU reads and debounces button presses using the ezButton library.
    • The MPU cannot read the button directly — it must request data from the MCU via Bridge.call(). The MCU responds with the press count or resets it.
    • The MPU has Wi-Fi — because the MPU runs full Debian Linux with Wi-Fi, it can report press counts via Telegram and accept reset commands remotely.
    • Communication: Bridge.call() on the Linux side invokes Bridge.provide() functions on the MCU side
    • ⚠️ Reserved: /dev/ttyHS1 (Linux) and Serial1 (MCU) are used by the Arduino Router — never open them directly

    In short: MCU debounces button presses and counts them → MPU requests the count → MPU forwards it via Telegram.

    MCU sketch — button debounce with press counter and Bridge:

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ #include "Arduino_RouterBridge.h" #include <ezButton.h> ezButton button(7); int press_count = 0; void get_press_count() { Monitor.println("Press count: " + String(press_count)); } void reset_count() { press_count = 0; Monitor.println("Press count reset to 0"); } void setup() { button.setDebounceTime(50); Bridge.begin(); Monitor.begin(); Bridge.provide("get_press_count", get_press_count); Bridge.provide("reset_count", reset_count); Monitor.println("Button Debounce Bridge ready"); } void loop() { button.loop(); if (button.isPressed()) { press_count++; Monitor.println("Button PRESSED — count: " + String(press_count)); } if (button.isReleased()) Monitor.println("Button RELEASED"); }

    Python script (Arduino App Lab) — poll press count from Linux:

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ from arduino.app_utils import * import time def loop(): while True: count = Bridge.call("get_press_count") print(f"Current press count: {count}") time.sleep(3) App.run(user_loop=loop)
    • Note: Make sure Bridge.begin() is called in the MCU sketch and the sketch is uploaded before running the Python script on the Linux side.
    • ⚠️ Warning: Never directly open /dev/ttyHS1 (on Linux) or use Serial1 (on MCU) in your code — these are reserved by the Arduino Router and accessing them will break the Bridge.

    Detailed Instructions

    • Upload the MCU sketch: Open Arduino App Lab, create a new App, paste the Bridge MCU sketch above into sketch/sketch.ino, install the ezButton and Arduino_RouterBridge libraries, and click Run.
    • Add the Python script: Paste the Python code above into the Python tab of the same App.
    • Run the App: Click Run — the Python side polls the press count every 3 seconds.
    • Press the button several times.
    • Check the console: Open the Console tab → MCU Monitor subtab to see press/release events. Open the Python Console subtab to see the polled count.

    App Lab Console Output

    DIYables_Apps
    Stop
    sketch.ino
    1#include "Arduino_RouterBridge.h"
    Serial Monitor
    Python
    Message (Enter to send a message to "Newbiely" on usb(2820070321))
    New Line
    9600 baud
    Button Debounce Bridge ready Button PRESSED — count: 1 Button RELEASED Button PRESSED — count: 2 Button RELEASED Button PRESSED — count: 3 Button RELEASED

    Telegram Integration

    You can query the button press count or reset it from anywhere via Telegram.

    If you do not have a Telegram bot yet, see How to Create a Telegram Bot to get your bot token before continuing.

    MCU sketch: Keep the same MCU sketch from the previous Bridge section — no changes needed. Make sure it is already uploaded and running on the STM32 before proceeding.

    Python script (Arduino App Lab) — Telegram bot for button press tracking:

    /* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-button-debounce */ from arduino.app_utils import * import requests import time BOT_TOKEN = "YOUR_BOT_TOKEN" API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}" last_update_id = 0 def send_message(chat_id, text): requests.post(f"{API_URL}/sendMessage", json={"chat_id": chat_id, "text": text}) def get_updates(): global last_update_id resp = requests.get(f"{API_URL}/getUpdates", params={"offset": last_update_id + 1, "timeout": 5}) return resp.json().get("result", []) def loop(): global last_update_id updates = get_updates() for update in updates: last_update_id = update["update_id"] msg = update.get("message", {}) chat_id = msg.get("chat", {}).get("id") text = msg.get("text", "").strip() if text == "/count": count = Bridge.call("get_press_count") send_message(chat_id, f"Button pressed {count} time(s) since last reset") elif text == "/reset": Bridge.call("reset_count") send_message(chat_id, "Press count reset to 0") else: send_message(chat_id, "Commands:\n/count — get button press count\n/reset — reset the count to 0") time.sleep(1) App.run(user_loop=loop)
    • Note: Replace YOUR_BOT_TOKEN with the token obtained from @BotFather on Telegram.
    • Send /count to see how many times the button has been pressed since power-on or last reset.
    • Send /reset to reset the counter to 0.

    Detailed Instructions

    • Upload the MCU sketch: Use the Bridge MCU sketch from the previous section (upload it first if not already done).
    • Paste the Telegram script: Copy the Python code above into the Python tab of your App in Arduino App Lab.
    • Set your token: Replace YOUR_BOT_TOKEN in the script with your actual bot token.
    • Run the App: Click Run — the bot starts listening for Telegram messages immediately.
    • Test it: Press the button 5 times, then send /count on Telegram — you should receive 5. Then send /reset and /count again to confirm it resets.
    • Pro Tip: Use this as an event counter for counting visitors, machine cycles, or triggered alerts.

    App Lab Console Output

    DIYables_Apps
    Stop
    sketch.ino
    1#include "Arduino_RouterBridge.h"
    Serial Monitor
    Python
    [2026-04-29 12:00:01] Telegram: /count [2026-04-29 12:00:01] Button pressed 5 time(s) since last reset [2026-04-29 12:01:30] Telegram: /reset [2026-04-29 12:01:30] Press count reset to 0 [2026-04-29 12:01:45] Telegram: /count [2026-04-29 12:01:45] Button pressed 0 time(s) since last reset
    Telegram
    Telegram 12:45
    Welcome to Telegram!
    ArduinoBot 10:19
    Chatting with Arduino...
    telegram-botfather
    BotFather Yesterday
    Your bot has been created.

    ArduinoBot

    bot
    Today
    /count
    10:15 AM ✓✓
    Button pressed 5 time(s) since last reset
    10:16 AM
    /reset
    10:17 AM ✓✓
    Press count reset to 0
    10:18 AM
    /count
    10:19 AM ✓✓
    Button pressed 0 time(s) since last reset
    10:20 AM

    OpenClaw Integration

    OpenClaw integration for Arduino UNO Q button debounce is coming soon.

    • Coming Soon: OpenClaw support for button press tracking on Arduino UNO Q will be covered in a future update.

    Application/Project Ideas

    • Visitor counter: Place a button at a door — press count tracks how many people entered
    • Machine cycle counter: Count actuator cycles in a production line, check count via Telegram
    • Manual event log: Press button to log a timestamped event on the Linux side (MPU has real clock)
    • Multi-mode controller: Each button press cycles to the next mode; check mode via Telegram
    • Press-to-order: Press button to send a Telegram "reorder" message for supplies

    Challenge Yourself

    • Easy: Modify the Bridge sketch to also track how many times the button was released
    • Medium: Add a get_last_press_time() Bridge function that returns the number of seconds since the last press
    • Advanced: Build a Telegram bot that automatically sends a message when the press count reaches a target number (e.g., "10 presses reached!")

    Function References

    ※ 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!