123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #include "single_led.h"
- #include "application.h"
- #include <esp_log.h>
- #define TAG "SingleLed"
- #define DEFAULT_BRIGHTNESS 4
- #define HIGH_BRIGHTNESS 16
- #define LOW_BRIGHTNESS 2
- #define BLINK_INFINITE -1
- SingleLed::SingleLed(gpio_num_t gpio) {
- // If the gpio is not connected, you should use NoLed class
- assert(gpio != GPIO_NUM_NC);
- led_strip_config_t strip_config = {};
- strip_config.strip_gpio_num = gpio;
- strip_config.max_leds = 1;
- 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 blink_timer_args = {
- .callback = [](void *arg) {
- auto led = static_cast<SingleLed*>(arg);
- led->OnBlinkTimer();
- },
- .arg = this,
- .dispatch_method = ESP_TIMER_TASK,
- .name = "blink_timer",
- .skip_unhandled_events = false,
- };
- ESP_ERROR_CHECK(esp_timer_create(&blink_timer_args, &blink_timer_));
- }
- SingleLed::~SingleLed() {
- esp_timer_stop(blink_timer_);
- if (led_strip_ != nullptr) {
- led_strip_del(led_strip_);
- }
- }
- void SingleLed::SetColor(uint8_t r, uint8_t g, uint8_t b) {
- r_ = r;
- g_ = g;
- b_ = b;
- }
- void SingleLed::TurnOn() {
- if (led_strip_ == nullptr) {
- return;
- }
-
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(blink_timer_);
- led_strip_set_pixel(led_strip_, 0, r_, g_, b_);
- led_strip_refresh(led_strip_);
- }
- void SingleLed::TurnOff() {
- if (led_strip_ == nullptr) {
- return;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(blink_timer_);
- led_strip_clear(led_strip_);
- }
- void SingleLed::BlinkOnce() {
- Blink(1, 100);
- }
- void SingleLed::Blink(int times, int interval_ms) {
- StartBlinkTask(times, interval_ms);
- }
- void SingleLed::StartContinuousBlink(int interval_ms) {
- StartBlinkTask(BLINK_INFINITE, interval_ms);
- }
- void SingleLed::StartBlinkTask(int times, int interval_ms) {
- if (led_strip_ == nullptr) {
- return;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- esp_timer_stop(blink_timer_);
-
- blink_counter_ = times * 2;
- blink_interval_ms_ = interval_ms;
- esp_timer_start_periodic(blink_timer_, interval_ms * 1000);
- }
- void SingleLed::OnBlinkTimer() {
- std::lock_guard<std::mutex> lock(mutex_);
- blink_counter_--;
- if (blink_counter_ & 1) {
- led_strip_set_pixel(led_strip_, 0, r_, g_, b_);
- led_strip_refresh(led_strip_);
- } else {
- led_strip_clear(led_strip_);
- if (blink_counter_ == 0) {
- esp_timer_stop(blink_timer_);
- }
- }
- }
- void SingleLed::OnStateChanged() {
- auto& app = Application::GetInstance();
- auto device_state = app.GetDeviceState();
- switch (device_state) {
- case kDeviceStateStarting:
- SetColor(0, 0, DEFAULT_BRIGHTNESS);
- StartContinuousBlink(100);
- break;
- case kDeviceStateWifiConfiguring:
- SetColor(0, 0, DEFAULT_BRIGHTNESS);
- StartContinuousBlink(500);
- break;
- case kDeviceStateIdle:
- TurnOff();
- break;
- case kDeviceStateConnecting:
- SetColor(0, 0, DEFAULT_BRIGHTNESS);
- TurnOn();
- break;
- case kDeviceStateListening:
- case kDeviceStateAudioTesting:
- if (app.IsVoiceDetected()) {
- SetColor(HIGH_BRIGHTNESS, 0, 0);
- } else {
- SetColor(LOW_BRIGHTNESS, 0, 0);
- }
- TurnOn();
- break;
- case kDeviceStateSpeaking:
- SetColor(0, DEFAULT_BRIGHTNESS, 0);
- TurnOn();
- break;
- case kDeviceStateUpgrading:
- SetColor(0, DEFAULT_BRIGHTNESS, 0);
- StartContinuousBlink(100);
- break;
- case kDeviceStateActivating:
- SetColor(0, DEFAULT_BRIGHTNESS, 0);
- StartContinuousBlink(500);
- break;
- default:
- ESP_LOGW(TAG, "Unknown led strip event: %d", device_state);
- return;
- }
- }
|