#include <esp_log.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "freertos/queue.h"
#include "Led_config.h"
#include "button_config.h"
//#define LONG_MS 500
#define DEBOUNCE_MS 30
static const char *TAG = "BTN_LED_ISR";
//#define LED_PIN 2
//Queue for button intveruption инициализируем очередь
static QueueHandle_t btn_event_queue = NULL;
// Обработчик прерываний
static void IRAM_ATTR btn_isr_handler (void *arg){
uint32_t evt = 1;
xQueueSendFromISR(btn_event_queue, &evt, NULL);
}
void app_main() {
led_pin_init();
button_pin_init();
//Создаем очередь
btn_event_queue = xQueueCreate(5, sizeof(uint32_t));
// Проверяем создалась ли очередь
if (btn_event_queue == NULL)
return; // если ошибка выходим из app_main и останавливаемся
// Разрешаем прерывания
ESP_ERROR_CHECK(gpio_install_isr_service(0));
// Регистрируем обработчик прерывания для кнопки BUTT_ PIN
ESP_ERROR_CHECK(gpio_isr_handler_add(BUTT_PIN, btn_isr_handler, NULL));
// Предварительно выключаем светодиод
bool led_on = false;
led_set(led_on);
const TickType_t DEB = pdMS_TO_TICKS(DEBOUNCE_MS);
while (true) {
uint32_t evt = 0;
if (xQueueReceive(btn_event_queue, &evt, portMAX_DELAY)){
TickType_t t0 = xTaskGetTickCount();
// Защита от дребезга ждем 30 мс
while ((xTaskGetTickCount() - t0) < DEB){
vTaskDelay(1);
}
if (gpio_get_level(BUTT_PIN) != 0){
ESP_LOGI(TAG, "Fake press");
} else { while((gpio_get_level(BUTT_PIN) == 0)){ // Пока на пине 0, ничего не делаем
vTaskDelay(1);
}
// Как только 0 пропал, засекаем время
t0 = xTaskGetTickCount();
// Защита от дребезга при отключении кнопки
while((xTaskGetTickCount() - t0) > DEB) {
vTaskDelay(1);
}
// Меняем состояние светодиода
led_on = !led_on;
led_set(led_on);
ESP_LOGI(TAG, "Fake press");
}
// Очистка очереди. удаляем элементы пока очередь не опустеет
while(xQueueReceive(btn_event_queue, &evt, 0) == pdTRUE){
}
}
/*
{
// Если кнопка нажата
if (gpio_get_level(BUTT_PIN) == 0) {
//else gpio_set_level(LED_PIN, state);
TickType_t t0 = xTaskGetTickCount();
// Ожидаем 30 сек пока не пройдет дребезг контактов
while(gpio_get_level(BUTT_PIN) == 0 &&
(xTaskGetTickCount() - t0) < pdMS_TO_TICKS(DEBOUNCE_MS)){
vTaskDelay(1);
}
// Если кнопка все еще нажата обновляем t0
if (gpio_get_level(BUTT_PIN) == 0){
t0 = xTaskGetTickCount();
// Если кнопка по прежнему нажата, делаем задержку
while (gpio_get_level(BUTT_PIN) == 0) vTaskDelay(1);
// Когда кнопку отпустили, объявляем now
TickType_t now = xTaskGetTickCount();
// Ждем 30 мс пока пройдет дребезг при отключении контактов
while(gpio_get_level(BUTT_PIN) == 1 &&
(xTaskGetTickCount() - now) < pdMS_TO_TICKS(DEBOUNCE_MS)){
vTaskDelay(1);
}
// Подсчитываем время прошедшее с нажатия кнопки
TickType_t dur = xTaskGetTickCount() - t0;
if (dur >= pdMS_TO_TICKS(LONG_MS)){
gpio_set_level(LED_PIN, 0);
}
else gpio_set_level(LED_PIN, 1);
}
}
vTaskDelay(1);
}
*/
}
}