Files
esp32-zigbee/main/led_indicator.c
T
2026-01-15 23:11:17 +00:00

151 lines
4.5 KiB
C

#include "led_indicator.h"
#include "led_strip_encoder.h"
#include "device_config.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/rmt_tx.h"
#include "esp_log.h"
#include <math.h>
static const char *TAG = "LED_INDICATOR";
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) // 10MHz resolution
static rmt_channel_handle_t led_channel = NULL;
static rmt_encoder_handle_t led_encoder = NULL;
static TaskHandle_t led_task_handle = NULL;
static led_state_t current_led_state = LED_OFF;
static gpio_num_t led_gpio = GPIO_NUM_NC;
typedef struct {
uint8_t green;
uint8_t red;
uint8_t blue;
} grb_t;
static void led_write(grb_t color) {
uint8_t led_data[3];
led_data[0] = color.green;
led_data[1] = color.red;
led_data[2] = color.blue;
rmt_transmit_config_t tx_config = {
.loop_count = 0,
};
ESP_ERROR_CHECK(rmt_enable(led_channel));
ESP_ERROR_CHECK(rmt_transmit(led_channel, led_encoder, led_data, sizeof(led_data), &tx_config));
ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_channel, portMAX_DELAY));
ESP_ERROR_CHECK(rmt_disable(led_channel));
}
static void led_indicator_task(void *arg) {
grb_t color;
uint32_t tick = 0;
while (1) {
switch (current_led_state) {
case LED_OFF:
color = (grb_t){0, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(1000));
break;
case LED_PAIRING:
// Azul piscando
color = (tick % 2 == 0) ? (grb_t){0, 0, 50} : (grb_t){0, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(500));
tick++;
break;
case LED_CONNECTED:
// Verde fixo
color = (grb_t){30, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(1000));
break;
case LED_DISCONNECTED:
// Vermelho piscando
color = (tick % 2 == 0) ? (grb_t){0, 50, 0} : (grb_t){0, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(300));
tick++;
break;
case LED_RELAY_ON:
// Verde brilhante
color = (grb_t){60, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(100));
break;
case LED_RELAY_OFF:
// Verde escuro
color = (grb_t){10, 0, 0};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(100));
break;
case LED_FACTORY_RESET:
// Arco-íris rotativo
{
float hue = (tick % 360) * 3.14159f / 180.0f;
color = (grb_t){
(uint8_t)(30 * (1 + sinf(hue))),
(uint8_t)(30 * (1 + sinf(hue + 2.0943f))),
(uint8_t)(30 * (1 + sinf(hue + 4.1888f)))
};
led_write(color);
vTaskDelay(pdMS_TO_TICKS(20));
tick++;
}
break;
}
}
}
esp_err_t led_indicator_init(gpio_num_t gpio_num) {
esp_err_t ret;
led_gpio = gpio_num;
ESP_LOGI(TAG, "Inicializando LED RGB no GPIO %d", gpio_num);
// Configurar canal RMT TX
rmt_tx_channel_config_t tx_chan_config = {
.clk_src = RMT_CLK_SRC_DEFAULT,
.gpio_num = gpio_num,
.mem_block_symbols = 64,
.resolution_hz = LED_STRIP_RMT_RES_HZ,
.trans_queue_depth = 4,
};
ret = rmt_new_tx_channel(&tx_chan_config, &led_channel);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Falha ao criar canal RMT TX: %s", esp_err_to_name(ret));
return ret;
}
// Criar encoder customizado para LED strip
led_strip_encoder_config_t encoder_config = {
.resolution = LED_STRIP_RMT_RES_HZ,
};
ret = rmt_new_led_strip_encoder(&encoder_config, &led_encoder);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Falha ao criar encoder LED: %s", esp_err_to_name(ret));
return ret;
}
// Criar task para controlar LED
xTaskCreate(led_indicator_task, "led_indicator", 2048, NULL, 5, &led_task_handle);
ESP_LOGI(TAG, "LED RGB inicializado com sucesso");
return ESP_OK;
}
void led_indicator_set_state(led_state_t state) {
current_led_state = state;
}