#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
// Định nghĩa các chân GPIO cho rơ le, nút nhấn
#define BUTTON_PIN GPIO_NUM_13
#define RELAY_PIN GPIO_NUM_16
#define DEBOUNCE_DELAY_MS 50
static const char *TAG = "TOGGLE_APP";
void app_main(void)
{
// Cấu hình chân Relay (OUTPUT)
gpio_config_t io_conf_output = {};
io_conf_output.pin_bit_mask = (1ULL << RELAY_PIN);
io_conf_output.mode = GPIO_MODE_OUTPUT;
gpio_config(&io_conf_output);
// Cấu hình chân Button (INPUT)
gpio_config_t io_conf_input = {};
io_conf_input.pin_bit_mask = (1ULL << BUTTON_PIN);
io_conf_input.mode = GPIO_MODE_INPUT;
// Sơ đồ đã có điện trở kéo xuống bên ngoài nên không cần cấu hình pull-down nội
gpio_config(&io_conf_input);
// Khởi tạo trạng thái ban đầu
bool isLightOn = false;
gpio_set_level(RELAY_PIN, 1); // Giả định relay active-low, set HIGH để tắt
ESP_LOGI(TAG, "Hệ thống sẵn sàng. Đèn đang tắt.");
bool lastButtonState = false;
uint32_t lastDebounceTime = 0;
while (1) {
bool currentButtonState = gpio_get_level(BUTTON_PIN);
// Phát hiện sườn lên (thời điểm nút vừa được nhấn)
if (currentButtonState == 1 && lastButtonState == 0) {
// Chống dội phím
if ((xTaskGetTickCount() * portTICK_PERIOD_MS - lastDebounceTime) > DEBOUNCE_DELAY_MS) {
isLightOn = !isLightOn;
gpio_set_level(RELAY_PIN, isLightOn ? 0 : 1); // 0 để BẬT, 1 để TẮT
ESP_LOGI(TAG, "Trạng thái đèn: %s", isLightOn ? "BẬT" : "TẮT");
lastDebounceTime = xTaskGetTickCount() * portTICK_PERIOD_MS;
}
}
lastButtonState = currentButtonState;
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}