← До всіх проєктів
Освітлення Початковий

Веселка на кільці WS2812: HSV-кольори і гамма-корекція

Адресні світлодіоди WS2812 (NeoPixel) керуються одним дротом, і кожен світиться своїм кольором. Запускаємо «біжучу веселку» на кільці з 16 світлодіодів: колірне коло HSV, gamma32 для природних кольорів, живлення й захист стрічки.

Складність
Початковий
Час
30 min
Категорія
Освітлення
Оновлено

Про проєкт

У кожному світлодіоді 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-датчик і фоторезистор, і кільце стане нічником, який вмикається від руху в темряві. Це окрема стаття на сайті.