LEDs review
This commit is contained in:
+74
-13
@@ -22,17 +22,31 @@ const LEDColor LEDColor::PINK_STRONG = LEDColor::from_rgb(0xFF, 0x00, 0x80);
|
|||||||
const LEDColor LEDColor::WHITE = LEDColor::from_rgb(0x04, 0x04, 0x04);
|
const LEDColor LEDColor::WHITE = LEDColor::from_rgb(0x04, 0x04, 0x04);
|
||||||
const LEDColor LEDColor::WHITE_STRONG = LEDColor::from_rgb(0xFF, 0xFF, 0xFF);
|
const LEDColor LEDColor::WHITE_STRONG = LEDColor::from_rgb(0xFF, 0xFF, 0xFF);
|
||||||
|
|
||||||
const static char* TAG = "leds";
|
static constexpr const char* TAG = "leds";
|
||||||
|
|
||||||
static led_strip_handle_t led_strip = NULL;
|
static led_strip_handle_t led_strip = nullptr;
|
||||||
static SemaphoreHandle_t led_mutex = NULL;
|
static SemaphoreHandle_t led_mutex = nullptr;
|
||||||
|
|
||||||
|
static bool leds_ready() {
|
||||||
|
if (led_strip != nullptr && led_mutex != nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "LEDs used before successful initialization");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void init_leds() {
|
void init_leds() {
|
||||||
led_mutex = xSemaphoreCreateMutex();
|
if (led_strip != nullptr || led_mutex != nullptr) {
|
||||||
if (led_mutex == NULL) {
|
ESP_ERROR_CHECK(led_strip != nullptr && led_mutex != nullptr
|
||||||
ESP_LOGE(TAG, "Failed to create LED mutex");
|
? ESP_OK
|
||||||
|
: ESP_ERR_INVALID_STATE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
led_mutex = xSemaphoreCreateMutex();
|
||||||
|
ESP_ERROR_CHECK(led_mutex != nullptr ? ESP_OK : ESP_ERR_NO_MEM);
|
||||||
|
|
||||||
/// LED strip common configuration
|
/// LED strip common configuration
|
||||||
led_strip_config_t strip_config = {
|
led_strip_config_t strip_config = {
|
||||||
.strip_gpio_num = PIN_NEOPIXEL,
|
.strip_gpio_num = PIN_NEOPIXEL,
|
||||||
@@ -58,24 +72,71 @@ void init_leds() {
|
|||||||
/// Create the LED strip object
|
/// Create the LED strip object
|
||||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||||
|
|
||||||
|
// Clear the strip once during initialization. Runtime clear() is lazy.
|
||||||
ESP_ERROR_CHECK(led_strip_clear(led_strip));
|
ESP_ERROR_CHECK(led_strip_clear(led_strip));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDController::set_led(uint32_t led, uint32_t color) {
|
void LEDController::set_led(uint32_t led, uint32_t color) {
|
||||||
xSemaphoreTake(led_mutex, portMAX_DELAY);
|
if (!leds_ready() || xSemaphoreTake(led_mutex, portMAX_DELAY) != pdTRUE) {
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, led, color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const esp_err_t err = led_strip_set_pixel(
|
||||||
|
led_strip, led, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set LED %u: %s", led, esp_err_to_name(err));
|
||||||
|
}
|
||||||
xSemaphoreGive(led_mutex);
|
xSemaphoreGive(led_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDController::flush() {
|
void LEDController::flush() {
|
||||||
xSemaphoreTake(led_mutex, portMAX_DELAY);
|
if (!leds_ready() || xSemaphoreTake(led_mutex, portMAX_DELAY) != pdTRUE) {
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(led_strip));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const esp_err_t err = led_strip_refresh(led_strip);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to refresh LEDs: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
xSemaphoreGive(led_mutex);
|
xSemaphoreGive(led_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDController::clear() {
|
void LEDController::clear() {
|
||||||
xSemaphoreTake(led_mutex, portMAX_DELAY);
|
clear(LEDColor::OFF);
|
||||||
ESP_ERROR_CHECK(led_strip_clear(led_strip));
|
}
|
||||||
|
|
||||||
|
void LEDController::clear(LEDColor color) {
|
||||||
|
clear_range(0, LED_COUNT, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::clear_indicators() {
|
||||||
|
clear_indicators(LEDColor::OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::clear_indicators(LEDColor color) {
|
||||||
|
clear_range(LED_SHAPE_COUNT, LED_INDICATOR_COUNT, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::clear_shape_display() {
|
||||||
|
clear_shape_display(LEDColor::OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::clear_shape_display(LEDColor color) {
|
||||||
|
clear_range(0, LED_SHAPE_COUNT, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::clear_range(uint32_t first_led, uint32_t led_count, LEDColor color) {
|
||||||
|
if (!leds_ready() || xSemaphoreTake(led_mutex, portMAX_DELAY) != pdTRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t value = color.value();
|
||||||
|
for (uint32_t led = first_led; led < first_led + led_count; ++led) {
|
||||||
|
const esp_err_t err = led_strip_set_pixel(
|
||||||
|
led_strip, led, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to clear LED %u: %s", led, esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
xSemaphoreGive(led_mutex);
|
xSemaphoreGive(led_mutex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ void init_leds();
|
|||||||
class LEDController {
|
class LEDController {
|
||||||
private:
|
private:
|
||||||
static void set_led(uint32_t led, uint32_t color);
|
static void set_led(uint32_t led, uint32_t color);
|
||||||
|
static void clear_range(uint32_t first_led, uint32_t led_count, LEDColor color);
|
||||||
public:
|
public:
|
||||||
/// Sets the color of an indicator LED.
|
/// Sets the color of an indicator LED.
|
||||||
///
|
///
|
||||||
@@ -99,11 +100,26 @@ public:
|
|||||||
set_led(static_cast<uint32_t>(led), color.value());
|
set_led(static_cast<uint32_t>(led), color.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outputs the data to the leds.
|
/// Outputs the pending data to the LEDs.
|
||||||
static void flush();
|
static void flush();
|
||||||
|
|
||||||
/// Clears the LEDs
|
/// Sets all LEDs to off without transmitting.
|
||||||
static void clear();
|
static void clear();
|
||||||
|
|
||||||
|
/// Sets all LEDs to `color` without transmitting.
|
||||||
|
static void clear(LEDColor color);
|
||||||
|
|
||||||
|
/// Sets all indicator LEDs to off without transmitting.
|
||||||
|
static void clear_indicators();
|
||||||
|
|
||||||
|
/// Sets all indicator LEDs to `color` without transmitting.
|
||||||
|
static void clear_indicators(LEDColor color);
|
||||||
|
|
||||||
|
/// Sets all shape-display LEDs to off without transmitting.
|
||||||
|
static void clear_shape_display();
|
||||||
|
|
||||||
|
/// Sets all shape-display LEDs to `color` without transmitting.
|
||||||
|
static void clear_shape_display(LEDColor color);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user