static const char *TAG = "leds"; #include #include "leds.hpp" #include "utils.hpp" static inline uint8_t mix(int l, int r, Fixed x) { return ((l << shift) + (x * (r - l))) >> shift; } Color Gradient::at(Fixed x) const { int i_left = (x * n_colors) >> shift; int i_right = i_left < n_colors - 1 ? i_left + 1 : 0; Fixed ratio = (x * n_colors) - (i_left << shift); //ESP_LOGI(TAG, "at(%d) = %d between %d and %d", x, ratio, i_left, i_right); Color cl = colors[i_left]; Color cr = colors[i_right]; Color color = { mix(cl.r, cr.r, ratio), mix(cl.g, cr.g, ratio), mix(cl.b, cr.b, ratio) }; /*ESP_LOGI(TAG, "(%d, %d, %d) %f (%d, %d, %d) -> (%d, %d, %d)", cl.r, cl.g, cl.b, ratio / (float)factor, cr.r, cr.g, cr.b, color.r, color.g, color.b );*/ return color; } void Pattern::step(Color pixels[], int len, int64_t &last_us, Fixed &offset) const { int64_t now_us = time_us(); int64_t duration_us = last_us == 0 ? 0 : now_us - last_us; last_us = now_us; //ESP_LOGI(TAG, "duration %d", duration_us); int offset_delta = (duration_us << shift) / (cycle_time_ms * 1000); if (reverse) offset -= offset_delta; else offset += offset_delta; Fixed off = march ? (((int)offset * cycle_length) & ~((1 << shift) - 1)) / cycle_length : offset; //ESP_LOGI(TAG, "cycle time %d, delta %d, offset %d, off %d", cycle_time_ms, offset_delta, offset, off); for (int i = 0; i < len; ++i) { pixels[i] = gradient.at(off + ((i << shift) / cycle_length)); } } LEDStrip::LEDStrip(int _length) : length(_length), pattern(NULL), pixels(new Color[_length]), last_us(0), offset(0) {} void LEDStrip::setLength(int _length) { length_changing(_length); delete[] pixels; length = _length; pixels = new Color[_length]; } void LEDStrip::step() { if (pattern) pattern->step(pixels, length, last_us, offset); } static std::string termcolor(Color c) { return "\x1b[48;2;" + std::to_string((int)c.r) + ";" + std::to_string((int)c.g) + ";" + std::to_string((int)c.b) + "m"; } void TerminalLEDs::show() const { std::string line; for (int i = 0; i < length; i++) { line += termcolor(pixels[i]) + " "; } line += "\x1b[0m"; ESP_LOGI(TAG, "%s", line.c_str()); } void TerminalLEDs::length_changing(int new_len) { ESP_LOGI(TAG, "Length changing: %d->%d", length, new_len); }