#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/gptimer.h"
#include "esp_timer.h"
#include "esp_log.h"
#define GPIO_BTN_A GPIO_NUM_0
#define GPIO_LED_BIT0 GPIO_NUM_2
#define TIMER_10S (10 * 1000000)
#define DEBOUNCE_TIME_US 250000 // Aumentado para 250ms para garantir estabilidade
static const char *TAG = "SISTEMA";
volatile bool btn_solicitado = false;
bool led_aceso = false;
gptimer_handle_t gptimer = NULL;
// Callback do Timer - Executa ao atingir 10s
static bool IRAM_ATTR timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data) {
gpio_set_level(GPIO_LED_BIT0, 0);
led_aceso = false;
gptimer_stop(timer);
return false;
}
// ISR do Botão - Apenas sinaliza a intenção de clique
static void IRAM_ATTR gpio_isr_handler(void* arg) {
static int64_t last_time = 0;
int64_t now = esp_timer_get_time();
if ((now - last_time) > DEBOUNCE_TIME_US) {
btn_solicitado = true;
last_time = now;
}
}
void app_main() {
// --- Configuração de Hardware (LED e Botão) ---
gpio_config_t io_conf = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = (1ULL << GPIO_LED_BIT0)
};
gpio_config(&io_conf);
gpio_set_level(GPIO_LED_BIT0, 0); // Garante que inicia desligado
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = (1ULL << GPIO_BTN_A);
io_conf.intr_type = GPIO_INTR_NEGEDGE; // Ativa na descida (pressionar)
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_BTN_A, gpio_isr_handler, NULL);
// --- Configuração do Timer ---
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000,
};
gptimer_new_timer(&timer_config, &gptimer);
gptimer_alarm_config_t alarm_config = { .alarm_count = TIMER_10S };
gptimer_set_alarm_action(gptimer, &alarm_config);
gptimer_event_callbacks_t cbs = { .on_alarm = timer_callback };
gptimer_register_event_callbacks(gptimer, &cbs, NULL);
gptimer_enable(gptimer);
while (1) {
if (btn_solicitado) {
btn_solicitado = false; // Consome o clique imediatamente
if (!led_aceso) {
// Ação: LIGAR
led_aceso = true;
gpio_set_level(GPIO_LED_BIT0, 1);
gptimer_set_raw_count(gptimer, 0); // Reseta contador
gptimer_start(gptimer); // Inicia contagem
ESP_LOGI(TAG, "LED LIGADO - Timer iniciado");
} else {
// Ação: DESLIGAR MANUAL
led_aceso = false;
gptimer_stop(gptimer); // Para o timer
gpio_set_level(GPIO_LED_BIT0, 0);
ESP_LOGI(TAG, "LED DESLIGADO - Manual");
}
}
vTaskDelay(pdMS_TO_TICKS(50)); // Delay para estabilidade do loop
}
}