single_led.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "single_led.h"
  2. #include "application.h"
  3. #include <esp_log.h>
  4. #define TAG "SingleLed"
  5. #define DEFAULT_BRIGHTNESS 4
  6. #define HIGH_BRIGHTNESS 16
  7. #define LOW_BRIGHTNESS 2
  8. #define BLINK_INFINITE -1
  9. SingleLed::SingleLed(gpio_num_t gpio) {
  10. // If the gpio is not connected, you should use NoLed class
  11. assert(gpio != GPIO_NUM_NC);
  12. led_strip_config_t strip_config = {};
  13. strip_config.strip_gpio_num = gpio;
  14. strip_config.max_leds = 1;
  15. strip_config.led_pixel_format = LED_PIXEL_FORMAT_GRB;
  16. strip_config.led_model = LED_MODEL_WS2812;
  17. led_strip_rmt_config_t rmt_config = {};
  18. rmt_config.resolution_hz = 10 * 1000 * 1000; // 10MHz
  19. ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_));
  20. led_strip_clear(led_strip_);
  21. esp_timer_create_args_t blink_timer_args = {
  22. .callback = [](void *arg) {
  23. auto led = static_cast<SingleLed*>(arg);
  24. led->OnBlinkTimer();
  25. },
  26. .arg = this,
  27. .dispatch_method = ESP_TIMER_TASK,
  28. .name = "blink_timer",
  29. .skip_unhandled_events = false,
  30. };
  31. ESP_ERROR_CHECK(esp_timer_create(&blink_timer_args, &blink_timer_));
  32. }
  33. SingleLed::~SingleLed() {
  34. esp_timer_stop(blink_timer_);
  35. if (led_strip_ != nullptr) {
  36. led_strip_del(led_strip_);
  37. }
  38. }
  39. void SingleLed::SetColor(uint8_t r, uint8_t g, uint8_t b) {
  40. r_ = r;
  41. g_ = g;
  42. b_ = b;
  43. }
  44. void SingleLed::TurnOn() {
  45. if (led_strip_ == nullptr) {
  46. return;
  47. }
  48. std::lock_guard<std::mutex> lock(mutex_);
  49. esp_timer_stop(blink_timer_);
  50. led_strip_set_pixel(led_strip_, 0, r_, g_, b_);
  51. led_strip_refresh(led_strip_);
  52. }
  53. void SingleLed::TurnOff() {
  54. if (led_strip_ == nullptr) {
  55. return;
  56. }
  57. std::lock_guard<std::mutex> lock(mutex_);
  58. esp_timer_stop(blink_timer_);
  59. led_strip_clear(led_strip_);
  60. }
  61. void SingleLed::BlinkOnce() {
  62. Blink(1, 100);
  63. }
  64. void SingleLed::Blink(int times, int interval_ms) {
  65. StartBlinkTask(times, interval_ms);
  66. }
  67. void SingleLed::StartContinuousBlink(int interval_ms) {
  68. StartBlinkTask(BLINK_INFINITE, interval_ms);
  69. }
  70. void SingleLed::StartBlinkTask(int times, int interval_ms) {
  71. if (led_strip_ == nullptr) {
  72. return;
  73. }
  74. std::lock_guard<std::mutex> lock(mutex_);
  75. esp_timer_stop(blink_timer_);
  76. blink_counter_ = times * 2;
  77. blink_interval_ms_ = interval_ms;
  78. esp_timer_start_periodic(blink_timer_, interval_ms * 1000);
  79. }
  80. void SingleLed::OnBlinkTimer() {
  81. std::lock_guard<std::mutex> lock(mutex_);
  82. blink_counter_--;
  83. if (blink_counter_ & 1) {
  84. led_strip_set_pixel(led_strip_, 0, r_, g_, b_);
  85. led_strip_refresh(led_strip_);
  86. } else {
  87. led_strip_clear(led_strip_);
  88. if (blink_counter_ == 0) {
  89. esp_timer_stop(blink_timer_);
  90. }
  91. }
  92. }
  93. void SingleLed::OnStateChanged() {
  94. auto& app = Application::GetInstance();
  95. auto device_state = app.GetDeviceState();
  96. switch (device_state) {
  97. case kDeviceStateStarting:
  98. SetColor(0, 0, DEFAULT_BRIGHTNESS);
  99. StartContinuousBlink(100);
  100. break;
  101. case kDeviceStateWifiConfiguring:
  102. SetColor(0, 0, DEFAULT_BRIGHTNESS);
  103. StartContinuousBlink(500);
  104. break;
  105. case kDeviceStateIdle:
  106. TurnOff();
  107. break;
  108. case kDeviceStateConnecting:
  109. SetColor(0, 0, DEFAULT_BRIGHTNESS);
  110. TurnOn();
  111. break;
  112. case kDeviceStateListening:
  113. case kDeviceStateAudioTesting:
  114. if (app.IsVoiceDetected()) {
  115. SetColor(HIGH_BRIGHTNESS, 0, 0);
  116. } else {
  117. SetColor(LOW_BRIGHTNESS, 0, 0);
  118. }
  119. TurnOn();
  120. break;
  121. case kDeviceStateSpeaking:
  122. SetColor(0, DEFAULT_BRIGHTNESS, 0);
  123. TurnOn();
  124. break;
  125. case kDeviceStateUpgrading:
  126. SetColor(0, DEFAULT_BRIGHTNESS, 0);
  127. StartContinuousBlink(100);
  128. break;
  129. case kDeviceStateActivating:
  130. SetColor(0, DEFAULT_BRIGHTNESS, 0);
  131. StartContinuousBlink(500);
  132. break;
  133. default:
  134. ESP_LOGW(TAG, "Unknown led strip event: %d", device_state);
  135. return;
  136. }
  137. }