From 9bcbd9f4b11d736334604a6a9b9c79f731a4753d Mon Sep 17 00:00:00 2001 From: rkcf Date: Sat, 28 Jan 2023 13:40:44 -0600 Subject: [PATCH] add in code for button debouncing --- main/esp32-sequencer.c | 49 +++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/main/esp32-sequencer.c b/main/esp32-sequencer.c index 1b90ff1..5f6a878 100644 --- a/main/esp32-sequencer.c +++ b/main/esp32-sequencer.c @@ -34,8 +34,12 @@ static QueueHandle_t control_event_queue = NULL; #define LEDC_GATE_OUT (6) /* Timers */ -gptimer_handle_t tap_tempo_timer = NULL; -gptimer_handle_t gate_timer = NULL; +static gptimer_handle_t tap_tempo_timer = NULL; +static gptimer_handle_t gate_timer = NULL; + +static const uint16_t DEBOUNCE_TIMEOUT = 20; // polling period length when debouncing in ms +static uint64_t debounce_time = 0; // system time of last intterupt +static uint8_t btn_state = 1; // state of gpio last recorded static const uint32_t DEFAULT_BPM = 120; @@ -71,20 +75,49 @@ static void mutate_seq(uint8_t *sequence) { } } +/* Handle tap tempo button presses */ +static void tap_tempo_handler(){ + // check the count to see if we have already started the timer + uint64_t count; + ESP_ERROR_CHECK(gptimer_get_raw_count(tap_tempo_timer, &count)); + if (count == 0) { // the timer hasn't started yet + ESP_ERROR_CHECK(gptimer_start(tap_tempo_timer)); + ESP_LOGI(TAG, "Starting tap tempo monitoring"); + } else { // stop the timer and calc bpm + ESP_ERROR_CHECK(gptimer_stop(tap_tempo_timer)); + ESP_LOGI(TAG, "Stopping tap tempo monitoring at %" PRIu64 "µs", count); + } +} + static void IRAM_ATTR gpio_isr_handler(void* arg) { + debounce_time = xTaskGetTickCount(); // set time of interrupt uint32_t gpio_num = (uint32_t)arg; + btn_state = gpio_get_level(gpio_num); // set state xQueueSendFromISR(control_event_queue, &gpio_num, NULL); } static void control_event_handler(void* arg) { uint32_t gpio_num; + uint8_t last_btn_state; + uint64_t last_debounce_time; while (1) { - if(xQueueReceive(control_event_queue, &gpio_num, portMAX_DELAY)) { - ESP_LOGI(TAG, "Handling control from GPIO %" PRIu32 , gpio_num); - switch (gpio_num) { - case GPIO_MUTATE_BTN: - mutate_seq(sequence); - break; + // save these so we can make comparisons + last_btn_state = btn_state; + last_debounce_time = debounce_time; + uint8_t current_state = gpio_get_level(gpio_num); + if (xQueueReceive(control_event_queue, &gpio_num, portMAX_DELAY)) { + // Check if interrupt triggered stays the same for long enough + if ((current_state == last_btn_state) && + (xTaskGetTickCount() - last_debounce_time > DEBOUNCE_TIMEOUT)) { + ESP_LOGI(TAG, "Handling control from GPIO %" PRIu32, gpio_num); + switch (gpio_num) { + case GPIO_MUTATE_BTN: + mutate_seq(sequence); + break; + case GPIO_TAP_TEMPO_BTN: + tap_tempo_handler(); + break; + } } } }