So,
ich hab den Code nun mal so grob strukturiert. Was mir noch fehlt sind sämtliche animierten Geschichten. Da ich mich noch immer nicht für eine bestimmte LED-Streifen-Art entscheiden konnte, in wenigen Wochen aber der Rohbau beginnt, sollte ich langsam etwas Gas geben. Im Zweifelsfall werde ich WS2810B-Streifen kaufen, da weniger Verkabelungsaufwand.
Nun aber nochmals zu einer konkreten Frage zwecks Machbarkeit.
Zwei gleichzeitig zu berechnende Animationen via Videocrossfade einfach ineinanderzublenden wird in dem von mir angegebenen Fall leider nicht möglich sein. Dies möchte ich anhand einer Grafik verdeutlichen:
x-Achse = Zeit
y-Achse = Verteilung der Animationen über den kompletten LED-Streifen
Bei der roten Linie betritt jmd. die Treppe von unten, während bei der grünen Linie jmd. die Treppe von oben betritt.
Kurz bevor die zweite Person die Treppe betritt haben wir den Fall, dass es sowohl Bereiche gibt, in denen die BGD-Animation zu 100% auf den oberen LEDs zu sehen sein soll, während im unteren Bereich der Treppe bereits zu 100% die Layer-Animation zu sehen ist. Dies wäre mit einem einfachen Crossfade so nicht möglich, da sobald gefadet werden würde keiner der beiden Animationen 100% "Deckkraft" mehr erreichen könnte.
Wäre jedoch auch das mit den Möglichkeiten, die die FastLED-Library bietet, machbar und sind die WS2810Bs schnell genug um dies bei einer Anzahl von max. 200 LEDs ohne Ruckeln wiedergeben zu können?
Gruß Chris
Hier mal der bisherige Code inkl. einer Farbraumkonvertierung, die vermutlich wieder rausfliegen wird, da ja komplett in RGB "gearbeitet" werden kann und Umschaltmöglichkeiten für die in "BGD" und "Layer" implementierten Programme via zweier Taster:
#include "Bounce2.h"
#include "FastLED.h"
#define DATA_PIN 4 // Manuelle Eingabe!
#define ALL_LEDS 188 // Manuelle Eingabe!
#define REAL_LEDS 175 // Manuelle Eingabe!
#define BRIGHTNESS 64 // Manuelle Eingabe!
// Debugging
#define DEBUG Serial // Debugging
#ifdef DEBUG
#define debug(...) DEBUG.print(__VA_ARGS__)
#define debugln(...) DEBUG.println(__VA_ARGS__)
#define debugbegin(...) DEBUG.begin(__VA_ARGS__)
#else
#define debug(...)
#define debugln(...)
#define debugbegin(...)
#endif
// _Entprellung
#define INPUTMODE INPUT // INPUT oder INPUT_PULLUP
const byte butPin[] = { // Pin-Nummern der angeschlossenen Buttons
5, 6
};
#define NUMBUTTONS sizeof(butPin) // Die Anzahl der Tasten durch die Anzahl der Bytes des Arrays butPin ermitteln (wird automatisch definiert)
Bounce debouncer[NUMBUTTONS]; // Mehrere Bounce-Instanzen erstellen
byte buttonAction; // Gibt an, für welche Einzeltaste eine Aktion ausgelöst wird.
enum {
NOACTION,
BUT1PUSH, BUT2PUSH
};
// PIR-Sensor
const byte pir[] = {2, 3}; // PIR-Sensoren über Pulldown_Widerstand an Pin 2 und 3
const byte pirLed[] = {12, 13}; // PIR LEDs an Pin 12 und 13
// Modes
boolean mode = 0; // BGD oder Layer
enum {
BGD,
LAYER
};
byte bgdPattern = 0; // 0 = schwarz, 1 = Halloween, 2 = Sylvester, 3 = Partymode
byte layerPattern = 0; // 0 = weiß, 1 = rot, 2 = grün, 3 = blau
// LED-Arrays
byte stairs[] = {9, 9, 12, 13, 16, 16, 13, 13, 16, 16, 13, 12, 9, 9}; // Anzahl der LEDs pro Stufe
int gaps[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // Anzahl der übersprungenen LEDs zwischen jeder Stufe
CHSV hsvPix[ALL_LEDS]; // Sämtliche HSV-LED Daten
CRGB rgbPix[REAL_LEDS]; // Gemappte RGB-LED Daten
void setup()
{
for (int i = 0; i < NUMBUTTONS; i++) // Buttons
{
pinMode(butPin[i], INPUTMODE);
debouncer[i].attach(butPin[i]);
debouncer[i].interval(10);
}
for (boolean i = 0; i < sizeof(pir); i++) // PIR-Sensoren
{
pinMode(i, INPUT);
}
delay(500);
debugbegin(9600);
debugln("System bereit");
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(rgbPix, REAL_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
void loop()
{
eingabe(); // Taster und Sensoren auswerten
verarbeitung(); // Farbberechnungen
ausgabe(); // Verteilung und Ausgabe der Pixel
}
void eingabe()
{
bounce(); // Tastenentprellung
pirCheck(); // PIR-Sensoren auswerten
}
void bounce()
{
buttonAction = NOACTION;
for (int i = 0; i < NUMBUTTONS; i++)
{
debouncer[i].update(); // Status prüfen
if (debouncer[i].fell()) // Wenn die Taste gedrückt wird
{
buttonAction = i + 1; // Übergibt die passende buttonAction an den Sketch
}
}
}
void pirCheck()
{
static boolean oldPirState[sizeof(pir)]; // Zuletzt ermittelter Zustand
static boolean newPirState[sizeof(pir)]; // Aktuell ermittelter Zustand
for (boolean i = 0; i < sizeof(pir); i++)
{
newPirState[i] = digitalRead(pir[i]);
if (newPirState[i] != oldPirState[i]) // Wenn PIR_Zustandswechsel..
{
if (newPirState[i]) // PIR_Zustandswechsel auf 3.3V
{
debug("PIR an Pin ");
debug(pir[i]);
debugln(" hat Bewegung registriert");
digitalWrite(pirLed[i], newPirState[i]); // LED einschalten
}
if (!newPirState[i]) // PIR_Zustandswechsel auf 0V
{
digitalWrite(pirLed[i], newPirState[i]); // LED ausschalten
}
oldPirState[i] = newPirState[i];
}
}
}
void verarbeitung()
{
patternSwitch(); // Wechselt Pattern und Mode
patternRun(); // Erzeugt Werte für animierte Pattern
}
void patternSwitch()
{
switch (buttonAction)
{
case BUT1PUSH: // BGD-Taste
switch (mode)
{
case LAYER:
mode = BGD;
bgdPattern--;
case BGD:
bgdPattern++;
if (bgdPattern > 3) bgdPattern = 0;
for (int i = 0; i < ALL_LEDS; i++)
{
switch (bgdPattern)
{
case 0: // schwarz
hsvPix[i] = CHSV(0, 0, 0);
break;
case 1: // Halloween
break;
case 2: // Sylvester
break;
case 3: // Partymode
break;
}
}
}
break;
case BUT2PUSH: // Layer-Taste
switch (mode)
{
case BGD:
mode = LAYER;
layerPattern--;
case LAYER:
layerPattern++;
if (layerPattern > 3) layerPattern = 0;
for (int i = 0; i < ALL_LEDS; i++)
{
switch (layerPattern)
{
case 0:
hsvPix[i] = CHSV(0, 0, 255);
break;
case 1:
hsvPix[i] = CHSV(0, 255, 255);
break;
case 2:
hsvPix[i] = CHSV(96, 255, 255);
break;
case 3:
hsvPix[i] = CHSV(160, 255, 255);
break;
}
}
}
}
}
void patternRun() // Erzeugt Werte für animierte Pattern
{
switch (bgdPattern)
{
case 0: // schwarz
break;
case 1: // Halloween
break;
case 2: // Sylvester
break;
case 3: // Partymode
break;
}
}
void ausgabe()
{
ledMapping(); // Pixelmapping
FastLED.show(); // Sämtliche Pixel beschalten
}
void ledMapping() // Pixelmapping
{
byte i = 0;
byte stairsSum = stairs[0]; // Zwischensummenberechnung
byte gapsSum = gaps[0]; // Zwischensummenberechnung
for (byte j = 0; j < sizeof(stairs); j++) // Stufenberechnung
{
Serial.println("");
do
{
hsv2rgb_rainbow(hsvPix[i + gapsSum], rgbPix[i]); // Farbraumkonvertierung inkl. Mapping
Serial.print("rgbPix: ");
Serial.print(rgbPix[i]);
Serial.print(" = LED: ");
Serial.println(i);
i++;
}
while (i < (stairsSum));
stairsSum = stairsSum + stairs[j + 1];
gapsSum = gapsSum + gaps[j + 1];
}
}