feat: add led strip class
This commit is contained in:
219
main/led_strip/led_strip_wrapper.cc
Normal file
219
main/led_strip/led_strip_wrapper.cc
Normal file
@ -0,0 +1,219 @@
|
||||
#include "led_strip_wrapper.h"
|
||||
#include "board.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <esp_log.h>
|
||||
|
||||
#define TAG "LedStripWrapper"
|
||||
|
||||
LedStripWrapper::LedStripWrapper(gpio_num_t gpio, uint8_t max_leds) {
|
||||
if (gpio == GPIO_NUM_NC) {
|
||||
ESP_LOGI(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
led_ = new Led(gpio, max_leds);
|
||||
|
||||
esp_timer_create_args_t led_strip_timer_args = {
|
||||
.callback = [](void *arg) {
|
||||
auto light = static_cast<LedStripWrapper*>(arg);
|
||||
light->OnBlinkTimer();
|
||||
},
|
||||
.arg = this,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "Led Strip Timer",
|
||||
.skip_unhandled_events = false,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_timer_create(&led_strip_timer_args, &led_strip_timer_));
|
||||
}
|
||||
|
||||
LedStripWrapper::~LedStripWrapper() {
|
||||
if (led_strip_timer_ != nullptr) {
|
||||
esp_timer_delete(led_strip_timer_);
|
||||
}
|
||||
if (led_ != nullptr) {
|
||||
delete led_;
|
||||
}
|
||||
}
|
||||
|
||||
void LedStripWrapper::OnBlinkTimer() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
counter_--;
|
||||
timer_callback_();
|
||||
}
|
||||
|
||||
void LedStripWrapper::SetLedBasicColor(LedBasicColor color, uint8_t brightness) {
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (color) {
|
||||
case kLedColorWhite:
|
||||
led_->SetWhite(brightness);
|
||||
break;
|
||||
case kLedColorGrey:
|
||||
led_->SetGrey(brightness);
|
||||
break;
|
||||
case kLedColorRed:
|
||||
led_->SetRed(brightness);
|
||||
break;
|
||||
case kLedColorGreen:
|
||||
led_->SetGreen(brightness);
|
||||
break;
|
||||
case kLedColorBlue:
|
||||
led_->SetBlue(brightness);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LedStripWrapper::SetLedStripBasicColor(uint8_t index, LedBasicColor color, uint8_t brightness) {
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= led_->max_leds()) {
|
||||
ESP_LOGE(TAG, "Invalid led index: %d", index);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (color) {
|
||||
case kLedColorWhite:
|
||||
led_strip_set_pixel(led_->led_strip(), index, brightness, brightness, brightness);
|
||||
break;
|
||||
case kLedColorGrey:
|
||||
led_strip_set_pixel(led_->led_strip(), index, brightness, brightness, brightness);
|
||||
break;
|
||||
case kLedColorRed:
|
||||
led_strip_set_pixel(led_->led_strip(), index, brightness, 0, 0);
|
||||
break;
|
||||
case kLedColorGreen:
|
||||
led_strip_set_pixel(led_->led_strip(), index, 0, brightness, 0);
|
||||
break;
|
||||
case kLedColorBlue:
|
||||
led_strip_set_pixel(led_->led_strip(), index, 0, 0, brightness);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LedStripWrapper::StartBlinkTask(uint32_t times, uint32_t interval_ms) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
counter_ = times * 2;
|
||||
timer_callback_ = [this]() {
|
||||
if (counter_ & 1) {
|
||||
led_->TurnOn();
|
||||
} else {
|
||||
led_->TurnOff();
|
||||
if (counter_ == 0) {
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
}
|
||||
}
|
||||
};
|
||||
esp_timer_start_periodic(led_strip_timer_, interval_ms * 1000);
|
||||
}
|
||||
|
||||
void LedStripWrapper::BlinkOnce(LedBasicColor color, uint8_t brightness) {
|
||||
Blink(color, brightness, 1, 100);
|
||||
}
|
||||
|
||||
void LedStripWrapper::Blink(LedBasicColor color, uint32_t times, uint32_t interval_ms, uint8_t brightness) {
|
||||
SetLedBasicColor(color, brightness);
|
||||
StartBlinkTask(times, interval_ms);
|
||||
}
|
||||
|
||||
void LedStripWrapper::ContinuousBlink(LedBasicColor color, uint32_t interval_ms, uint8_t brightness) {
|
||||
SetLedBasicColor(color, brightness);
|
||||
StartBlinkTask(COUNTER_INFINITE, interval_ms);
|
||||
}
|
||||
|
||||
void LedStripWrapper::StaticLight(LedBasicColor color, uint8_t brightness) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
SetLedBasicColor(color, brightness);
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
led_->TurnOn();
|
||||
}
|
||||
|
||||
void LedStripWrapper::ChasingLight(LedBasicColor base_color, LedBasicColor color, uint32_t interval_ms, uint8_t brightness) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
counter_ = COUNTER_INFINITE;
|
||||
timer_callback_ = [this, base_color, color, brightness]() {
|
||||
auto index = counter_ % led_->max_leds();
|
||||
for (uint8_t i = 0; i < led_->max_leds(); i++) {
|
||||
if (i == index || i == (index + 1) % led_->max_leds()) {
|
||||
SetLedStripBasicColor(i, color, brightness);
|
||||
} else {
|
||||
SetLedStripBasicColor(i, base_color, LOW_BRIGHTNESS);
|
||||
}
|
||||
}
|
||||
led_strip_refresh(led_->led_strip());
|
||||
};
|
||||
esp_timer_start_periodic(led_strip_timer_, interval_ms * 1000);
|
||||
}
|
||||
|
||||
void LedStripWrapper::BreathLight(LedBasicColor color, uint32_t interval_ms) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
counter_ = COUNTER_INFINITE;
|
||||
timer_callback_ = [this, color]() {
|
||||
static bool increase = true;
|
||||
static uint32_t brightness = LOW_BRIGHTNESS;
|
||||
|
||||
for (uint8_t i = 0; i < led_->max_leds(); i++) {
|
||||
SetLedStripBasicColor(i, color, brightness);
|
||||
}
|
||||
led_strip_refresh(led_->led_strip());
|
||||
|
||||
if (brightness == HIGH_BRIGHTNESS) {
|
||||
increase = false;
|
||||
} else if (brightness == LOW_BRIGHTNESS) {
|
||||
increase = true;
|
||||
}
|
||||
|
||||
if (increase) {
|
||||
brightness += 2;
|
||||
} else {
|
||||
brightness -= 2;
|
||||
}
|
||||
};
|
||||
esp_timer_start_periodic(led_strip_timer_, interval_ms * 1000);
|
||||
}
|
||||
|
||||
void LedStripWrapper::LightOff() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (led_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Builtin LED not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_timer_stop(led_strip_timer_);
|
||||
led_->TurnOff();
|
||||
}
|
||||
58
main/led_strip/led_strip_wrapper.h
Normal file
58
main/led_strip/led_strip_wrapper.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef _LED_STRIP_WRAPPER_H_
|
||||
#define _LED_STRIP_WRAPPER_H_
|
||||
|
||||
#include "led.h"
|
||||
|
||||
#define COUNTER_INFINITE -1
|
||||
|
||||
enum LedStripEvent {
|
||||
kStartup,
|
||||
kListening,
|
||||
kListeningAndSpeaking,
|
||||
kSpeaking,
|
||||
kStandby,
|
||||
kConnecting,
|
||||
kUpgrading,
|
||||
};
|
||||
|
||||
enum LedBasicColor {
|
||||
kLedColorWhite,
|
||||
kLedColorGrey,
|
||||
kLedColorRed,
|
||||
kLedColorGreen,
|
||||
kLedColorBlue,
|
||||
};
|
||||
|
||||
typedef std::function<void()> TimerCallback;
|
||||
|
||||
class LedStripWrapper {
|
||||
private:
|
||||
Led* led_ = nullptr;
|
||||
std::mutex mutex_;
|
||||
|
||||
uint32_t counter_ = 0;
|
||||
esp_timer_handle_t led_strip_timer_ = nullptr;
|
||||
TimerCallback timer_callback_;
|
||||
|
||||
void SetLedBasicColor(LedBasicColor color, uint8_t brightness);
|
||||
void SetLedStripBasicColor(uint8_t index, LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void StartBlinkTask(uint32_t times, uint32_t interval_ms);
|
||||
void OnBlinkTimer();
|
||||
|
||||
public:
|
||||
LedStripWrapper(gpio_num_t gpio, uint8_t max_leds);
|
||||
virtual ~LedStripWrapper();
|
||||
|
||||
void LightOff();
|
||||
virtual void LightOn(LedStripEvent event) = 0;
|
||||
|
||||
protected:
|
||||
void BlinkOnce(LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void Blink(LedBasicColor color, uint32_t times, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void ContinuousBlink(LedBasicColor color, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void StaticLight(LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void ChasingLight(LedBasicColor base_color, LedBasicColor color, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS);
|
||||
void BreathLight(LedBasicColor color, uint32_t interval_ms);
|
||||
};
|
||||
|
||||
#endif // _LED_STRIP_WRAPPER_H_
|
||||
39
main/led_strip/multiple_led.cc
Normal file
39
main/led_strip/multiple_led.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include "multiple_led.h"
|
||||
#include <esp_log.h>
|
||||
|
||||
#define TAG "MultipleLed"
|
||||
|
||||
MultipleLed::MultipleLed(gpio_num_t gpio, uint8_t max_leds) : LedStripWrapper(gpio, max_leds) {
|
||||
}
|
||||
|
||||
MultipleLed::~MultipleLed() {
|
||||
}
|
||||
|
||||
void MultipleLed::LightOn(LedStripEvent event) {
|
||||
switch (event) {
|
||||
case kStartup:
|
||||
ChasingLight(kLedColorWhite, kLedColorBlue, 100, HIGH_BRIGHTNESS);
|
||||
break;
|
||||
case kListeningAndSpeaking:
|
||||
BreathLight(kLedColorRed, 100);
|
||||
break;
|
||||
case kListening:
|
||||
BreathLight(kLedColorRed, 100);
|
||||
break;
|
||||
case kSpeaking:
|
||||
StaticLight(kLedColorGreen, HIGH_BRIGHTNESS);
|
||||
break;
|
||||
case kStandby:
|
||||
BlinkOnce(kLedColorGreen);
|
||||
break;
|
||||
case kConnecting:
|
||||
Blink(kLedColorBlue, 1000, 500);
|
||||
break;
|
||||
case kUpgrading:
|
||||
ContinuousBlink(kLedColorGreen, 100);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Invalid led strip event: %d", event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
14
main/led_strip/multiple_led.h
Normal file
14
main/led_strip/multiple_led.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _LED_STRIP_EFFECT_V2_H_
|
||||
#define _LED_STRIP_EFFECT_V2_H_
|
||||
|
||||
#include "led_strip_wrapper.h"
|
||||
|
||||
class MultipleLed : public LedStripWrapper {
|
||||
public:
|
||||
MultipleLed(gpio_num_t gpio, uint8_t max_leds);
|
||||
virtual ~MultipleLed();
|
||||
|
||||
void LightOn(LedStripEvent event) override;
|
||||
};
|
||||
|
||||
#endif // _LED_STRIP_EFFECT_V2_H_
|
||||
39
main/led_strip/single_led.cc
Normal file
39
main/led_strip/single_led.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include "single_led.h"
|
||||
#include <esp_log.h>
|
||||
|
||||
#define TAG "SingleLed"
|
||||
|
||||
SingleLed::SingleLed(gpio_num_t gpio) : LedStripWrapper(gpio, 1) {
|
||||
}
|
||||
|
||||
SingleLed::~SingleLed() {
|
||||
}
|
||||
|
||||
void SingleLed::LightOn(LedStripEvent event) {
|
||||
switch (event) {
|
||||
case kStartup:
|
||||
ContinuousBlink(kLedColorBlue, 100);
|
||||
break;
|
||||
case kListeningAndSpeaking:
|
||||
StaticLight(kLedColorRed, HIGH_BRIGHTNESS);
|
||||
break;
|
||||
case kListening:
|
||||
StaticLight(kLedColorRed, LOW_BRIGHTNESS);
|
||||
break;
|
||||
case kSpeaking:
|
||||
StaticLight(kLedColorGreen, HIGH_BRIGHTNESS);
|
||||
break;
|
||||
case kStandby:
|
||||
BlinkOnce(kLedColorGreen);
|
||||
break;
|
||||
case kConnecting:
|
||||
Blink(kLedColorBlue, 1000, 500);
|
||||
break;
|
||||
case kUpgrading:
|
||||
ContinuousBlink(kLedColorGreen, 100);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Invalid led strip event: %d", event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
14
main/led_strip/single_led.h
Normal file
14
main/led_strip/single_led.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _LED_STRIP_EFFECT_V1_H_
|
||||
#define _LED_STRIP_EFFECT_V1_H_
|
||||
|
||||
#include "led_strip_wrapper.h"
|
||||
|
||||
class SingleLed : public LedStripWrapper {
|
||||
public:
|
||||
SingleLed(gpio_num_t gpio);
|
||||
virtual ~SingleLed();
|
||||
|
||||
void LightOn(LedStripEvent event) override;
|
||||
};
|
||||
|
||||
#endif // _LED_STRIP_EFFECT_V1_H_
|
||||
Reference in New Issue
Block a user