gpio_led.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #include "gpio_led.h"
  2. #include "application.h"
  3. #include <esp_log.h>
  4. #define TAG "GpioLed"
  5. #define DEFAULT_BRIGHTNESS 50
  6. #define HIGH_BRIGHTNESS 100
  7. #define LOW_BRIGHTNESS 10
  8. #define IDLE_BRIGHTNESS 5
  9. #define SPEAKING_BRIGHTNESS 75
  10. #define UPGRADING_BRIGHTNESS 25
  11. #define ACTIVATING_BRIGHTNESS 35
  12. #define BLINK_INFINITE -1
  13. // GPIO_LED
  14. #define LEDC_LS_TIMER LEDC_TIMER_1
  15. #define LEDC_LS_MODE LEDC_LOW_SPEED_MODE
  16. #define LEDC_LS_CH0_CHANNEL LEDC_CHANNEL_0
  17. #define LEDC_DUTY (4096)
  18. #define LEDC_FADE_TIME (1000)
  19. // GPIO_LED
  20. GpioLed::GpioLed(gpio_num_t gpio, int output_invert) {
  21. // If the gpio is not connected, you should use NoLed class
  22. assert(gpio != GPIO_NUM_NC);
  23. /*
  24. * Prepare and set configuration of timers
  25. * that will be used by LED Controller
  26. */
  27. ledc_timer_config_t ledc_timer = {};
  28. ledc_timer.duty_resolution = LEDC_TIMER_13_BIT; // resolution of PWM duty
  29. ledc_timer.freq_hz = 4000; // frequency of PWM signal
  30. ledc_timer.speed_mode = LEDC_LS_MODE; // timer mode
  31. ledc_timer.timer_num = LEDC_LS_TIMER; // timer index
  32. ledc_timer.clk_cfg = LEDC_AUTO_CLK; // Auto select the source clock
  33. ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
  34. ledc_channel_.channel = LEDC_LS_CH0_CHANNEL,
  35. ledc_channel_.duty = 0,
  36. ledc_channel_.gpio_num = gpio,
  37. ledc_channel_.speed_mode = LEDC_LS_MODE,
  38. ledc_channel_.hpoint = 0,
  39. ledc_channel_.timer_sel = LEDC_LS_TIMER,
  40. ledc_channel_.flags.output_invert = output_invert & 0x01,
  41. // Set LED Controller with previously prepared configuration
  42. ledc_channel_config(&ledc_channel_);
  43. // Initialize fade service.
  44. ledc_fade_func_install(0);
  45. // When the callback registered by ledc_cb_degister is called, run led ->OnFadeEnd()
  46. ledc_cbs_t ledc_callbacks = {
  47. .fade_cb = FadeCallback
  48. };
  49. ledc_cb_register(ledc_channel_.speed_mode, ledc_channel_.channel, &ledc_callbacks, this);
  50. esp_timer_create_args_t blink_timer_args = {
  51. .callback = [](void *arg) {
  52. auto led = static_cast<GpioLed*>(arg);
  53. led->OnBlinkTimer();
  54. },
  55. .arg = this,
  56. .dispatch_method = ESP_TIMER_TASK,
  57. .name = "Blink Timer",
  58. .skip_unhandled_events = false,
  59. };
  60. ESP_ERROR_CHECK(esp_timer_create(&blink_timer_args, &blink_timer_));
  61. ledc_initialized_ = true;
  62. }
  63. GpioLed::~GpioLed() {
  64. esp_timer_stop(blink_timer_);
  65. if (ledc_initialized_) {
  66. ledc_fade_stop(ledc_channel_.speed_mode, ledc_channel_.channel);
  67. ledc_fade_func_uninstall();
  68. }
  69. }
  70. void GpioLed::SetBrightness(uint8_t brightness) {
  71. duty_ = brightness * LEDC_DUTY / 100;
  72. }
  73. void GpioLed::TurnOn() {
  74. if (!ledc_initialized_) {
  75. return;
  76. }
  77. std::lock_guard<std::mutex> lock(mutex_);
  78. esp_timer_stop(blink_timer_);
  79. ledc_fade_stop(ledc_channel_.speed_mode, ledc_channel_.channel);
  80. ledc_set_duty(ledc_channel_.speed_mode, ledc_channel_.channel, duty_);
  81. ledc_update_duty(ledc_channel_.speed_mode, ledc_channel_.channel);
  82. }
  83. void GpioLed::TurnOff() {
  84. if (!ledc_initialized_) {
  85. return;
  86. }
  87. std::lock_guard<std::mutex> lock(mutex_);
  88. esp_timer_stop(blink_timer_);
  89. ledc_fade_stop(ledc_channel_.speed_mode, ledc_channel_.channel);
  90. ledc_set_duty(ledc_channel_.speed_mode, ledc_channel_.channel, 0);
  91. ledc_update_duty(ledc_channel_.speed_mode, ledc_channel_.channel);
  92. }
  93. void GpioLed::BlinkOnce() {
  94. Blink(1, 100);
  95. }
  96. void GpioLed::Blink(int times, int interval_ms) {
  97. StartBlinkTask(times, interval_ms);
  98. }
  99. void GpioLed::StartContinuousBlink(int interval_ms) {
  100. StartBlinkTask(BLINK_INFINITE, interval_ms);
  101. }
  102. void GpioLed::StartBlinkTask(int times, int interval_ms) {
  103. if (!ledc_initialized_) {
  104. return;
  105. }
  106. std::lock_guard<std::mutex> lock(mutex_);
  107. esp_timer_stop(blink_timer_);
  108. ledc_fade_stop(ledc_channel_.speed_mode, ledc_channel_.channel);
  109. blink_counter_ = times * 2;
  110. blink_interval_ms_ = interval_ms;
  111. esp_timer_start_periodic(blink_timer_, interval_ms * 1000);
  112. }
  113. void GpioLed::OnBlinkTimer() {
  114. std::lock_guard<std::mutex> lock(mutex_);
  115. blink_counter_--;
  116. if (blink_counter_ & 1) {
  117. ledc_set_duty(ledc_channel_.speed_mode, ledc_channel_.channel, duty_);
  118. } else {
  119. ledc_set_duty(ledc_channel_.speed_mode, ledc_channel_.channel, 0);
  120. if (blink_counter_ == 0) {
  121. esp_timer_stop(blink_timer_);
  122. }
  123. }
  124. ledc_update_duty(ledc_channel_.speed_mode, ledc_channel_.channel);
  125. }
  126. void GpioLed::StartFadeTask() {
  127. if (!ledc_initialized_) {
  128. return;
  129. }
  130. std::lock_guard<std::mutex> lock(mutex_);
  131. esp_timer_stop(blink_timer_);
  132. ledc_fade_stop(ledc_channel_.speed_mode, ledc_channel_.channel);
  133. fade_up_ = true;
  134. ledc_set_fade_with_time(ledc_channel_.speed_mode,
  135. ledc_channel_.channel, LEDC_DUTY, LEDC_FADE_TIME);
  136. ledc_fade_start(ledc_channel_.speed_mode,
  137. ledc_channel_.channel, LEDC_FADE_NO_WAIT);
  138. }
  139. void GpioLed::OnFadeEnd() {
  140. std::lock_guard<std::mutex> lock(mutex_);
  141. fade_up_ = !fade_up_;
  142. ledc_set_fade_with_time(ledc_channel_.speed_mode,
  143. ledc_channel_.channel, fade_up_ ? LEDC_DUTY : 0, LEDC_FADE_TIME);
  144. ledc_fade_start(ledc_channel_.speed_mode,
  145. ledc_channel_.channel, LEDC_FADE_NO_WAIT);
  146. }
  147. bool GpioLed::FadeCallback(const ledc_cb_param_t *param, void *user_arg) {
  148. if (param->event == LEDC_FADE_END_EVT) {
  149. auto led = static_cast<GpioLed*>(user_arg);
  150. led->OnFadeEnd();
  151. }
  152. return true;
  153. }
  154. void GpioLed::OnStateChanged() {
  155. auto& app = Application::GetInstance();
  156. auto device_state = app.GetDeviceState();
  157. switch (device_state) {
  158. case kDeviceStateStarting:
  159. SetBrightness(DEFAULT_BRIGHTNESS);
  160. StartContinuousBlink(100);
  161. break;
  162. case kDeviceStateWifiConfiguring:
  163. SetBrightness(DEFAULT_BRIGHTNESS);
  164. StartContinuousBlink(500);
  165. break;
  166. case kDeviceStateIdle:
  167. SetBrightness(IDLE_BRIGHTNESS);
  168. TurnOn();
  169. // TurnOff();
  170. break;
  171. case kDeviceStateConnecting:
  172. SetBrightness(DEFAULT_BRIGHTNESS);
  173. TurnOn();
  174. break;
  175. case kDeviceStateListening:
  176. if (app.IsVoiceDetected()) {
  177. SetBrightness(HIGH_BRIGHTNESS);
  178. } else {
  179. SetBrightness(LOW_BRIGHTNESS);
  180. }
  181. // TurnOn();
  182. StartFadeTask();
  183. break;
  184. case kDeviceStateSpeaking:
  185. SetBrightness(SPEAKING_BRIGHTNESS);
  186. TurnOn();
  187. break;
  188. case kDeviceStateUpgrading:
  189. SetBrightness(UPGRADING_BRIGHTNESS);
  190. StartContinuousBlink(100);
  191. break;
  192. case kDeviceStateActivating:
  193. SetBrightness(ACTIVATING_BRIGHTNESS);
  194. StartContinuousBlink(500);
  195. break;
  196. default:
  197. ESP_LOGE(TAG, "Unknown gpio led event: %d", device_state);
  198. return;
  199. }
  200. }