I added a button to GPIO 4(board pin 6) in my pico board. GPIO pin is normally pulled up and button press will bring it to ground. I want to add a simple debounce logic to the button press in the IRQ callback function.

This is what I have so far (modified form the LED blinking sample project)

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "tusb.h"

const uint LED_PIN = 25;

// #define PUSH_BUTTON_01  4
const uint PUSH_BUTTON_01 = 4;
int led_state = 0;

void button_debounce_01(){
    // debounce button and check if the button went from high to low and is staying low
    // 20 ms delay for H to L edge debounce
    bool push_btn_1_state;
    printf("button_debounce_01() entered\n");
    // sleep_ms(1);
    printf("sleep_ms() ended\n");
    if( gpio_get(PUSH_BUTTON_01) == 0){
        // debounce succesful, button press detected
        if(led_state == 0){
          led_state = 1;
        } else{
          led_state = 0;
    else {
        return;     // button press NOT detected

int main() {

  bi_decl(bi_program_description("This is a test binary."));
  bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED"));


  while (!tud_cdc_connected()) {

  printf("hello button debounce test\n");

  gpio_set_dir(LED_PIN, GPIO_OUT);

  gpio_set_dir(PUSH_BUTTON_01, GPIO_IN);
  gpio_set_irq_enabled_with_callback(PUSH_BUTTON_01, GPIO_IRQ_EDGE_FALL , true, &button_debounce_01);

#if 0
  while (1) {
    gpio_put(LED_PIN, 0);
    gpio_put(LED_PIN, 1);
    puts("Hello World\n");

    gpio_put(LED_PIN, led_state);

The program will only start running after I open a terminal program in PC (I am using Putty) and I am using the pico board's USB serial port. When I run the program and press the button I get the following output on serial terminal

hello button debounce test
button_debounce_01() entered  

Looks like the program doesn't go past the sleep_us(500); line in the IRQ function.

Am I doing something wrong? Is there a simple button debounce routine in one of the official examples?

1 Answer 1


There should be minimal processing in any interrupt service routine. Set a flag and exit is best.

Any system call is likely to screw the system. Don't sleep, don't call printf.

Debounce is not trivial.

See picod debounce

  • While not considered great practice, calling printf() in a Pico ISR is permitted, and done in the official examples. So it shouldn't be the cause of the issue here.
    – Malvineous
    Commented May 6, 2022 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.