Von den WS2812B-Modulen für RGB-LEDs gibt es etliche Bauformen, sowie auch den hier beschriebenen vollen Ring aus insgesamt 241 Einzel-LEDs aufgeteilt auf 9 unterschiedliche Unterringe.
Wie ein oder mehrere WS2812B-Module angesteuert und programmiert werden, kann man im Beitrag
RGB-LED-Modul WS2812B nachlesen. Dort findet man auch einen Sketch
für einen Funktions-Test der eigenen Module.
Im folgenden Aufbau sind neben dem WS2812B-Ring noch ein Mikrotaster zur Wahl des Modus (statisch oder
animiert) sowie drei Potentiometer zu sehen, die verschiedene Funktionen erfüllen.
Das die 241 WS2812B-LEDs vor allem mit zunehmender Helligkeit eine beachtliche Stromstärke aufnehmen, sollte
immer eine entsprechende Spannungsquelle verwendet werden, damit der Arduino keinen Schaden nimmt.
Der folgende Sketch verwendet die Library Adafruit_NeoPixel, welche die Ansteuerung der WS2812B-Module recht einfach macht. Der statische Modus ermöglicht es, mit den Potentiometern die Farben rot, grün und blau individuell in ihrer Helligkeit zu steuern. Im Animations-Modus werden verschiedene Programme mit dem ersten Potentiometer durchgewählt. Für jedes Programm können noch zusätzlich die Helligkeit und die Geschwindigkeit des Programms gewählt werden. (Bei extremen Helligkeitswerten können die Farben etwas unvorhergesehen reagieren)
/**
Arduino-Sketch for driving WS2812B-LED-Rings with different programs
(c) 2020 Christian Grieger
GNU GENERAL PUBLIC LICENSE
Usage:
Button: Switch between static and animation mode
1st Potentiometer:
- static mode: brightness of color red
- animation mode: toggle animation program
2nd Potentiometer:
- static mode: brightness of color green
- animation mode: animation speed
3rd Potentiometer:
- static mode: brightness of color blue
- animation mode: overall brightness of LEDs (not available for all animation programs)
*/
/********* BEGIN customizable values *********/
#define PIN_POTI_RED A0
#define PIN_POTI_GREEN A1
#define PIN_POTI_BLUE A2
#define PIN_BUTTON 8
#define PIN_LED 9
#define AMOUNT_LEDS 241
#define AMOUNT_RINGS 9
const byte ledRings[AMOUNT_RINGS][2] = {
{ 0, 60}, // 60 LEDs
{ 60, 108}, // 48 LEDs
{108, 148}, // 40 LEDs
{148, 180}, // 32 LEDs
{180, 204}, // 24 LEDs
{204, 220}, // 16 LEDs
{220, 232}, // 12 LEDs
{232, 240}, // 8 LEDs
{240, 241} // 1 LED
};
/********* END customizable values ***********/
#define MODE_STATIC 0
#define MODE_ANIMATION 1
#define AMOUNT_PROGRAMS 5
#define lmillis() ((long)millis())
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel led = Adafruit_NeoPixel(AMOUNT_LEDS, PIN_LED, NEO_GRB + NEO_KHZ800);
void setup()
{
randomSeed(analogRead(A5));
pinMode(PIN_BUTTON, INPUT_PULLUP);
pinMode(PIN_POTI_RED, INPUT);
pinMode(PIN_POTI_GREEN, INPUT);
pinMode(PIN_POTI_BLUE, INPUT);
led.begin();
setAllLeds(led.Color(0, 0, 0));
}
void loop()
{
static long lastClick = lmillis();
static byte displayMode;
if (displayMode == MODE_ANIMATION) {
checkAnimation();
} else {
checkStatic();
}
if (lmillis() - lastClick >= 0 && digitalRead(PIN_BUTTON) == LOW) {
lastClick = lmillis() + 250;
displayMode++;
displayMode %= 2;
setAllLeds(led.Color(0, 0, 0));
}
}
void checkStatic()
{
static uint8_t rgb[3] = {0, 0, 0};
bool hasChanged = false;
uint8_t r = map(analogRead(PIN_POTI_RED), 0, 1023, 0, 255);
uint8_t g = map(analogRead(PIN_POTI_GREEN), 0, 1023, 0, 255);
uint8_t b = map(analogRead(PIN_POTI_BLUE), 0, 1023, 0, 255);
if (abs(rgb[0] - r) > 10) {
rgb[0] = r;
hasChanged = true;
}
if (abs(rgb[1] - g) > 10) {
rgb[1] = g;
hasChanged = true;
}
if (abs(rgb[2] - b) > 10) {
rgb[2] = b;
hasChanged = true;
}
if (hasChanged) {
setAllLeds(led.Color(rgb[0], rgb[1], rgb[2]));
}
}
void checkAnimation()
{
static int pVal = 0;
static byte activeProgram = 0;
static byte brightness = 1;
static byte delayFactor = 1;
delayFactor = map(analogRead(PIN_POTI_GREEN), 0, 1023, 1, 250);
brightness = map(analogRead(PIN_POTI_BLUE), 0, 1023, 1, 255);
int v = analogRead(PIN_POTI_RED);
if (abs(pVal - v) > 100) {
pVal = v;
activeProgram++;
activeProgram %= AMOUNT_PROGRAMS;
setAllLeds(led.Color(0, 0, 0));
}
switch (activeProgram) {
case 4:
showRingRotation(brightness, delayFactor);
break;
case 3:
showRandomColors(brightness, delayFactor);
break;
case 2:
showRingSun(brightness, delayFactor);
break;
case 1:
showSingleFlash(brightness, delayFactor);
break;
case 0:
default:
showRoulette(brightness, delayFactor);
break;
}
}
void setAllLeds(uint32_t ledColor)
{
for (uint8_t i = 0; i < AMOUNT_LEDS; i++) {
led.setPixelColor(i, ledColor);
}
led.show();
}
void showSingleFlash(byte brightness, byte delayFactor)
{
byte ledIndex = random(0, AMOUNT_LEDS);
led.setPixelColor(ledIndex, led.Color(brightness, brightness, brightness));
led.show();
delay(delayFactor * 2); // delay between 4ms and 1000ms
led.setPixelColor(ledIndex, led.Color(0, 0, 0));
led.show();
}
void showRoulette(byte brightness, byte delayFactor)
{
static byte ledIndex = 0;
ledIndex++;
ledIndex %= AMOUNT_LEDS;
led.setPixelColor(ledIndex, led.Color(brightness, 0, 0));
led.show();
delay(delayFactor * 4); // delay between 4ms and 1000ms
led.setPixelColor(ledIndex, led.Color(0, 0, 0));
led.show();
}
void showRingSun(byte brightness, byte delayFactor)
{
static byte ringNo = 0;
ringNo++;
ringNo %= AMOUNT_RINGS;
for (byte i = ledRings[ringNo][0]; i < ledRings[ringNo][1]; i++) {
led.setPixelColor(i, led.Color(brightness, (byte)(brightness * 0.25), 0));
}
led.show();
delay(delayFactor * 4); // delay between 4ms and 1000ms
for (byte i = ledRings[ringNo][0]; i < ledRings[ringNo][1]; i++) {
led.setPixelColor(i, led.Color(0, 0, 0));
}
led.show();
}
void showRandomColors(byte brightness, byte delayFactor)
{
for (byte i = 0; i < AMOUNT_LEDS; i++) {
led.setPixelColor(i, led.Color(random(0, brightness), random(0, brightness), random(0, brightness)));
}
led.show();
delay(delayFactor * 4); // delay between 4ms and 1000ms
}
void showRingRotation(byte brightness, byte delayFactor)
{
static byte ringIndex[AMOUNT_RINGS];
for (byte i = 0; i < AMOUNT_RINGS; i++) {
led.setPixelColor(ringIndex[i], led.Color(0, 0, 0));
}
led.show();
for (byte r = 0; r < AMOUNT_RINGS; r++) {
ringIndex[r]++;
if (ringIndex[r] >= ledRings[r][1]) {
ringIndex[r] = ledRings[r][0];
}
led.setPixelColor(ringIndex[r], led.Color(brightness, (byte)(brightness * 0.5), 0));
}
led.show();
delay(delayFactor); // delay between 1ms and 250ms
}
zurück