Feat: add rotary encoder switch handling. Including debounce

main
rkcf 2023-02-08 16:10:49 -06:00
parent aedbb7ef94
commit a3c225cf6a
1 changed files with 63 additions and 0 deletions

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include "driver/gpio.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
@ -9,6 +10,7 @@
#include "esp_log.h"
#include "driver/pulse_cnt.h"
#include "driver/ledc.h"
#include "hal/gpio_types.h"
#include "hal/ledc_types.h"
#include "hal/pcnt_types.h"
@ -26,8 +28,63 @@
pcnt_unit_handle_t pcnt_unit;
static QueueHandle_t pcnt_queue = NULL;
/* Button Settings */
static QueueHandle_t control_event_queue = NULL;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
static const uint16_t DEBOUNCE_TIMEOUT = 20; /* Polling period lenght for debounce */
static uint64_t debounce_time = 0; /* system time of last intterupt */
static uint8_t btn_state = 1; /* state of gpio last recorded */
static const char *TAG = "RE Demo"; /* logging tag */
static void IRAM_ATTR gpio_isr_handler(void *arg) {
uint32_t gpio_num = (uint32_t)arg;
portENTER_CRITICAL_ISR(&mux);
debounce_time = xTaskGetTickCount(); /* set time of interrupt */
btn_state = gpio_get_level(GPIO_BTN_PIN); /* set state */
portEXIT_CRITICAL_ISR(&mux);
xQueueSendFromISR(control_event_queue, &gpio_num, NULL);
}
static void control_event_handler(void *arg) {
uint8_t last_btn_state;
uint64_t last_debounce_time;
ESP_LOGI(TAG, "Starting Control Event Handler");
while (1) {
/* save these so we can make comparisons */
portENTER_CRITICAL_ISR(&mux);
last_btn_state = btn_state;
last_debounce_time = debounce_time;
portEXIT_CRITICAL_ISR(&mux);
uint8_t current_state = gpio_get_level(GPIO_BTN_PIN);
uint32_t gpio_num = GPIO_BTN_PIN;
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, "Switch pushed!");
}
}
}
}
/* Initialize encoder switch */
static void btn_init(void) {
ESP_LOGI(TAG, "Initializing Encoder Switch");
/* Setup gpio control event queue */
control_event_queue = xQueueCreate(10, sizeof(uint32_t));
/* install gpio isr hservice */
gpio_install_isr_service(0);
/* Setup Encoder button */
gpio_reset_pin(GPIO_BTN_PIN);
gpio_pullup_dis(GPIO_BTN_PIN);
gpio_pulldown_en(GPIO_BTN_PIN);
gpio_set_direction(GPIO_BTN_PIN, GPIO_MODE_INPUT);
gpio_set_intr_type(GPIO_BTN_PIN, GPIO_INTR_POSEDGE);
/* Hook in handler for button */
gpio_isr_handler_add(GPIO_BTN_PIN, gpio_isr_handler, (void *)GPIO_BTN_PIN);
}
/* Initialize LEDC for RGB LEDS in encoder */
static void ledc_init(void) {
@ -153,7 +210,13 @@ void app_main(void){
/* Initialize pulse counter */
pcnt_init();
/* Initialize led driver */
ledc_init();
/* Initialize gpio switch */
btn_init();
/* Start task to handle control events */
xTaskCreate(control_event_handler, "control event handler", 2048, NULL, 10, NULL);
/* ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 4095)); */
/* ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); */