Веселка на кільці WS2812: HSV-кольори і гамма-корекція
Адресні світлодіоди WS2812 (NeoPixel) керуються одним дротом, і кожен світиться своїм кольором. Запускаємо «біжучу веселку» на кільці з 16 світлодіодів: колірне коло HSV, gamma32 для природних кольорів, живлення й захист стрічки.
Про проєкт
У кожному світлодіоді WS2812B сидить мікросхема: вона бере свої 24 біти кольору з потоку даних і передає решту далі по ланцюжку. Тож стрічку на сотні пікселів можна вести одним сигнальним дротом. Запустимо на кільці з 16 світлодіодів веселку, що плавно обертається.
Що знадобиться
- ESP32 DevKit
- Кільце WS2812B на 16 світлодіодів (або відрізок стрічки)
- Резистор 330–470 Ом на лінію даних і конденсатор 470–1000 мкФ на живлення (для стрічок)
- Бібліотека Adafruit NeoPixel
Схема
| Кільце | ESP32 |
|---|---|
| 5V (VCC) | 5V (VIN) |
| GND | GND |
| DIN (DI) | GPIO16 (через 330 Ом) |
- Струм. Один піксель на повній білій яскравості бере ~60 мА. Для 16 пікселів це до 1 А, для метра стрічки на 60 пікселів — 3.6 А. USB і вивід 5V плати розраховані приблизно на 500 мА, тому більші стрічки живлять від окремого блока 5 В, а землю з'єднують з ESP32.
- Рівні. WS2812 при 5 В формально чекає на вході ≥ 3.5 В, а ESP32 дає 3.3. На коротких проводах зазвичай працює. Якщо кольори «глючать», поставте перетворювач рівнів (74AHCT125) або живіть перший піксель трохи нижчою напругою.
HSV замість RGB
Щоб зробити веселку в RGB, довелося б вручну «перетікати» між каналами. У моделі HSV колір задається відтінком (hue) на колі, насиченістю і яскравістю. Adafruit NeoPixel використовує hue від 0 до 65535 на повне коло. Розподіляємо 16 пікселів рівномірно по колу і щокадру зсуваємо початок:
колір(i) = ColorHSV(hue + i × 65536 / 16)
gamma32() виправляє нелінійність сприйняття. Без неї веселка виглядає «блідою», з надто широкими білуватими переходами.
Код
// Веселка, що обертається на кільці WS2812 з 16 світлодіодів
#include <Adafruit_NeoPixel.h>
const int PIN = 16;
const int COUNT = 16;
Adafruit_NeoPixel ring(COUNT, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
ring.begin();
ring.setBrightness(80); // ~30 %: і очі, і блок живлення скажуть дякую
}
void loop() {
static uint16_t hue = 0;
for (int i = 0; i < COUNT; i++) {
ring.setPixelColor(i, ring.gamma32(ring.ColorHSV(hue + i * 65536L / COUNT)));
}
ring.show(); // передати кольори в кільце
hue += 512; // зсув відтінку — швидкість обертання
delay(20);
}
Корисно знати
65536L— суфіксLробить обчислення вlong, щобi × 65536не переповнилося на платах з 16-бітнимint.setBrightness()масштабує всі кольори й зберігає струм. Викликайте його один раз уsetup(), а не для анімації яскравості: це погіршує точність кольору.NEO_GRB— порядок кольорів у WS2812B. Якщо червоний і зелений переплутані, спробуйтеNEO_RGB.- Перший піксель згорів — не світить уся стрічка. Резистор на DIN і конденсатор на живлення захищають від стрибків при підключенні.
Що далі
Додайте PIR-датчик і фоторезистор, і кільце стане нічником, який вмикається від руху в темряві. Це окрема стаття на сайті.