feat: Adiciona suporte para controle de LED RGB e animações de estado
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
#include "led_indicator.h"
|
||||
#include "led_strip_encoder.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;
|
||||
}
|
||||
Reference in New Issue
Block a user