123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- #include "circular_strip.h"
- #include "application.h"
- #include <esp_log.h>
- #define TAG "CircularStrip"
- #define BLINK_INFINITE -1
- CircularStrip::CircularStrip(gpio_num_t gpio, uint8_t max_leds) : max_leds_(max_leds) {
- // If the gpio is not connected, you should use NoLed class
- assert(gpio != GPIO_NUM_NC);
- colors_.resize(max_leds_);
- led_strip_config_t strip_config = {};
- strip_config.strip_gpio_num = gpio;
- strip_config.max_leds = max_leds_;
- strip_config.led_pixel_format = LED_PIXEL_FORMAT_GRB;
- strip_config.led_model = LED_MODEL_WS2812;
- led_strip_rmt_config_t rmt_config = {};
- rmt_config.resolution_hz = 10 * 1000 * 1000; // 10MHz
- ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_));
- led_strip_clear(led_strip_);
- esp_timer_create_args_t strip_timer_args = {
- .callback = [](void *arg) {
- auto strip = static_cast<CircularStrip*>(arg);
- std::lock_guard<std::mutex> lock(strip->mutex_);
- if (strip->strip_callback_ != nullptr) {
- strip->strip_callback_();
- }
- },
- .arg = this,
- .dispatch_method = ESP_TIMER_TASK,
- .name = "strip_timer",
- .skip_unhandled_events = false,
- };
- ESP_ERROR_CHECK(esp_timer_create(&strip_timer_args, &strip_timer_));
- }
- CircularStrip::~CircularStrip() {
- esp_timer_stop(strip_timer_);
- if (led_strip_ != nullptr) {
- led_strip_del(led_strip_);
- }
- }
- void CircularStrip::SetAllColor(StripColor color) {
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(strip_timer_);
- for (int i = 0; i < max_leds_; i++) {
- colors_[i] = color;
- led_strip_set_pixel(led_strip_, i, color.red, color.green, color.blue);
- }
- led_strip_refresh(led_strip_);
- }
- void CircularStrip::SetSingleColor(uint8_t index, StripColor color) {
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(strip_timer_);
- colors_[index] = color;
- led_strip_set_pixel(led_strip_, index, color.red, color.green, color.blue);
- led_strip_refresh(led_strip_);
- }
- void CircularStrip::Blink(StripColor color, int interval_ms) {
- for (int i = 0; i < max_leds_; i++) {
- colors_[i] = color;
- }
- StartStripTask(interval_ms, [this]() {
- static bool on = true;
- if (on) {
- for (int i = 0; i < max_leds_; i++) {
- led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue);
- }
- led_strip_refresh(led_strip_);
- } else {
- led_strip_clear(led_strip_);
- }
- on = !on;
- });
- }
- void CircularStrip::FadeOut(int interval_ms) {
- StartStripTask(interval_ms, [this]() {
- bool all_off = true;
- for (int i = 0; i < max_leds_; i++) {
- colors_[i].red /= 2;
- colors_[i].green /= 2;
- colors_[i].blue /= 2;
- if (colors_[i].red != 0 || colors_[i].green != 0 || colors_[i].blue != 0) {
- all_off = false;
- }
- led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue);
- }
- if (all_off) {
- led_strip_clear(led_strip_);
- esp_timer_stop(strip_timer_);
- } else {
- led_strip_refresh(led_strip_);
- }
- });
- }
- void CircularStrip::Breathe(StripColor low, StripColor high, int interval_ms) {
- StartStripTask(interval_ms, [this, low, high]() {
- static bool increase = true;
- static StripColor color = low;
- if (increase) {
- if (color.red < high.red) {
- color.red++;
- }
- if (color.green < high.green) {
- color.green++;
- }
- if (color.blue < high.blue) {
- color.blue++;
- }
- if (color.red == high.red && color.green == high.green && color.blue == high.blue) {
- increase = false;
- }
- } else {
- if (color.red > low.red) {
- color.red--;
- }
- if (color.green > low.green) {
- color.green--;
- }
- if (color.blue > low.blue) {
- color.blue--;
- }
- if (color.red == low.red && color.green == low.green && color.blue == low.blue) {
- increase = true;
- }
- }
- for (int i = 0; i < max_leds_; i++) {
- led_strip_set_pixel(led_strip_, i, color.red, color.green, color.blue);
- }
- led_strip_refresh(led_strip_);
- });
- }
- void CircularStrip::Scroll(StripColor low, StripColor high, int length, int interval_ms) {
- for (int i = 0; i < max_leds_; i++) {
- colors_[i] = low;
- }
- StartStripTask(interval_ms, [this, low, high, length]() {
- static int offset = 0;
- for (int i = 0; i < max_leds_; i++) {
- colors_[i] = low;
- }
- for (int j = 0; j < length; j++) {
- int i = (offset + j) % max_leds_;
- colors_[i] = high;
- }
- for (int i = 0; i < max_leds_; i++) {
- led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue);
- }
- led_strip_refresh(led_strip_);
- offset = (offset + 1) % max_leds_;
- });
- }
- void CircularStrip::StartStripTask(int interval_ms, std::function<void()> cb) {
- if (led_strip_ == nullptr) {
- return;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(strip_timer_);
-
- strip_callback_ = cb;
- esp_timer_start_periodic(strip_timer_, interval_ms * 1000);
- }
- void CircularStrip::SetBrightness(uint8_t default_brightness, uint8_t low_brightness) {
- default_brightness_ = default_brightness;
- low_brightness_ = low_brightness;
- OnStateChanged();
- }
- void CircularStrip::OnStateChanged() {
- auto& app = Application::GetInstance();
- auto device_state = app.GetDeviceState();
- switch (device_state) {
- case kDeviceStateStarting: {
- StripColor low = { 0, 0, 0 };
- StripColor high = { low_brightness_, low_brightness_, default_brightness_ };
- Scroll(low, high, 3, 100);
- break;
- }
- case kDeviceStateWifiConfiguring: {
- StripColor color = { low_brightness_, low_brightness_, default_brightness_ };
- Blink(color, 500);
- break;
- }
- case kDeviceStateIdle:
- FadeOut(50);
- break;
- case kDeviceStateConnecting: {
- StripColor color = { low_brightness_, low_brightness_, default_brightness_ };
- SetAllColor(color);
- break;
- }
- case kDeviceStateListening:
- case kDeviceStateAudioTesting: {
- StripColor color = { default_brightness_, low_brightness_, low_brightness_ };
- SetAllColor(color);
- break;
- }
- case kDeviceStateSpeaking: {
- StripColor color = { low_brightness_, default_brightness_, low_brightness_ };
- SetAllColor(color);
- break;
- }
- case kDeviceStateUpgrading: {
- StripColor color = { low_brightness_, default_brightness_, low_brightness_ };
- Blink(color, 100);
- break;
- }
- case kDeviceStateActivating: {
- StripColor color = { low_brightness_, default_brightness_, low_brightness_ };
- Blink(color, 500);
- break;
- }
- default:
- ESP_LOGW(TAG, "Unknown led strip event: %d", device_state);
- return;
- }
- }
|