ESP32 Native version of Blinky, featureful controller code for WS2811/WS2812/NeoPixels
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

103 Zeilen
2.9KB

  1. static const char *TAG = "leds";
  2. #include <esp_log.h>
  3. #include "leds.hpp"
  4. #include "utils.hpp"
  5. static inline uint8_t mix(int l, int r, Fixed x) {
  6. return ((l << shift) + (x * (r - l))) >> shift;
  7. }
  8. Color Gradient::at(Fixed x) const {
  9. int i_left = (x * n_colors) >> shift;
  10. int i_right = i_left < n_colors - 1 ? i_left + 1 : 0;
  11. Fixed ratio = (x * n_colors) - (i_left << shift);
  12. //ESP_LOGI(TAG, "at(%d) = %d between %d and %d", x, ratio, i_left, i_right);
  13. Color cl = colors[i_left];
  14. Color cr = colors[i_right];
  15. Color color = {
  16. mix(cl.r, cr.r, ratio),
  17. mix(cl.g, cr.g, ratio),
  18. mix(cl.b, cr.b, ratio)
  19. };
  20. /*ESP_LOGI(TAG, "(%d, %d, %d) %f (%d, %d, %d) -> (%d, %d, %d)",
  21. cl.r, cl.g, cl.b,
  22. ratio / (float)factor,
  23. cr.r, cr.g, cr.b,
  24. color.r, color.g, color.b
  25. );*/
  26. return color;
  27. }
  28. void GradientPattern::step(Color pixels[], int len, Pattern::State *_state) const {
  29. GradientPattern::State *state = (GradientPattern::State*)_state;
  30. int64_t now_us = time_us();
  31. int64_t duration_us = state->last_us == 0 ? 0 : now_us - state->last_us;
  32. state->last_us = now_us;
  33. //ESP_LOGI(TAG, "duration %d", duration_us);
  34. /*
  35. int period_us = 1000000 / 60;
  36. int n_skipped = (duration_us - period_us / 2) / period_us;
  37. if (n_skipped) {
  38. ESP_LOGW(TAG, "Skipped %d frames", n_skipped);
  39. }
  40. */
  41. // Don't make a major animation jump if it's been terribly long
  42. if (duration_us > 100000) duration_us = 100000;
  43. int offset_delta = (duration_us << shift) / (cycle_time_ms * 1000);
  44. if (reverse) state->offset += offset_delta; else state->offset -= offset_delta;
  45. Fixed off = march ?
  46. (((int)state->offset * cycle_length) & ~((1 << shift) - 1)) / cycle_length :
  47. state->offset;
  48. //ESP_LOGI(TAG, "cycle time %d, delta %d, offset %d, off %d", cycle_time_ms, offset_delta, offset, off);
  49. for (int i = 0; i < len; ++i) {
  50. pixels[i] = gradient->at(off + ((i << shift) / cycle_length));
  51. }
  52. }
  53. LEDStrip::LEDStrip(int _length) :
  54. length(_length), pattern(NULL),
  55. pixels(new Color[_length]),
  56. state(NULL)
  57. {}
  58. void LEDStrip::update_state() {
  59. if (state) delete state;
  60. if (pattern) state = pattern->start(length);
  61. else state = NULL;
  62. }
  63. void LEDStrip::setLength(int _length) {
  64. length_changing(_length);
  65. delete[] pixels;
  66. length = _length;
  67. pixels = new Color[_length];
  68. update_state();
  69. }
  70. void LEDStrip::step() {
  71. if (pattern) pattern->step(pixels, length, state);
  72. }
  73. static std::string termcolor(Color c) {
  74. return "\x1b[48;2;" +
  75. std::to_string((int)c.r) + ";" +
  76. std::to_string((int)c.g) + ";" +
  77. std::to_string((int)c.b) + "m";
  78. }
  79. void TerminalLEDs::show() {
  80. std::string line;
  81. for (int i = 0; i < length; i++) {
  82. line += termcolor(pixels[i]) + " ";
  83. }
  84. line += "\x1b[0m";
  85. ESP_LOGI(TAG, "%s", line.c_str());
  86. }