/* * LEDStripManager.cpp * * Created on: 19.06.2026 * Author: FSmilari */ #include "LEDStripManager.h" /* * Constructor */ LEDStripManager::LEDStripManager(uint16_t numLeds, uint8_t pin, ConfigManager &configManager) : strip(numLeds, pin, NEO_GRBW + NEO_KHZ800), configManager(configManager) { } /* * Destructor */ LEDStripManager::~LEDStripManager() { } void LEDStripManager::begin() { pinMode(LED_STRIP_POWER_PIN, OUTPUT); pinMode(LED_STRIP_DATA_PIN, OUTPUT); digitalWrite(LED_STRIP_POWER_PIN, HIGH); // LED zunächst EIN digitalWrite(LED_STRIP_DATA_PIN, HIGH); Config cfg = configManager.getConfig(); if (cfg.version != CONFIG_VERSION) { // Initalize cfg with defaults cfg = configManager.setToDefaultConfig(); configManager.loadConfig(); cfg = configManager.getConfig(); } strip.begin(); // Initialisiert den NeoPixel-Streifen strip.clear(); strip.show(); // Setzt alle LEDs auf "aus" switch (cfg.mode) { case LM_SINGLE_COLOR: this->setBrightness(cfg.brightness); setAll(cfg.singleColor.r, cfg.singleColor.g, cfg.singleColor.b, cfg.singleColor.w); return; case LM_SEGMENTS: this->setBrightness(cfg.brightness); setSegments(); return; default: // Setzt die erste LED (Index 0) auf rotes Licht (Rot, Grün, Blau, Weiss) strip.setPixelColor(0, strip.Color(255, 0, 0, 0)); // Setzt die zweite LED auf grün strip.setPixelColor(1, strip.Color(0, 255, 0, 0)); strip.setPixelColor(2, strip.Color(0, 0, 255, 0)); strip.setPixelColor(3, strip.Color(0, 0, 0, 255)); // Schickt die Farbinformationen zum LED-Streifen show(); return; } } void LEDStripManager::clear() { strip.clear(); } void LEDStripManager::show() { strip.show(); } void LEDStripManager::on() { Serial.println("LEDStripManager LED ON"); begin(); } void LEDStripManager::off() { Serial.println("LEDStripManager LED OFF"); clear(); show(); delay(50); digitalWrite(LED_STRIP_POWER_PIN, LOW); // LED zunächst AUS digitalWrite(LED_STRIP_DATA_PIN, LOW); } void LEDStripManager::setBrightness(uint8_t brightness) { strip.setBrightness(brightness); strip.show(); } void LEDStripManager::setPixel(uint16_t index, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { if (index >= strip.numPixels()) { return; } strip.setPixelColor(index, strip.Color(red, green, blue, white)); strip.show(); } void LEDStripManager::setAll(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(red, green, blue, white)); } strip.show(); } void LEDStripManager::onModeChange(LEDModes mode) { Config cfg = configManager.getConfig(); cfg.mode = mode; configManager.saveConfig(cfg); // Handle only single action modes here. For Animations use loop functions with nonblocking timers switch (mode) { case LM_SINGLE_COLOR: this->setBrightness(cfg.brightness); setAll(cfg.singleColor.r, cfg.singleColor.g, cfg.singleColor.b, cfg.singleColor.w); return; case LM_SEGMENTS: this->setBrightness(cfg.brightness); setSegments(); return; default: return; } } void LEDStripManager::onColorChange(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { Config cfg = configManager.getConfig(); cfg.singleColor.r = red; cfg.singleColor.g = green; cfg.singleColor.b = blue; cfg.singleColor.w = white; configManager.saveConfig(cfg); this->setAll(red, green, blue, white); } void LEDStripManager::onBrightnessChange(uint8_t brightness) { Config cfg = configManager.getConfig(); cfg.brightness = brightness; configManager.saveConfig(cfg); this->setBrightness(brightness); } void LEDStripManager::setSegments() { Config cfg = configManager.getConfig(); RGBWColor c1 = cfg.segmentColor1; RGBWColor c2 = cfg.segmentColor2; RGBWColor c3 = cfg.segmentColor3; int nbrPixel = strip.numPixels(); int third = nbrPixel / 3; for (int i = 0; i < nbrPixel; i++) { if (i < third) setPixel(i, c1.r, c1.g, c1.b, c1.w); else if (i < 2 * third) setPixel(i, c2.r, c2.g, c2.b, c2.w); else setPixel(i, c3.r, c3.g, c3.b, c3.w); } show(); } uint32_t LEDStripManager::wheel(uint8_t pos) { pos = 255 - pos; if (pos < 85) { return strip.Color(255 - pos * 3, 0, pos * 3); } if (pos < 170) { pos -= 85; return strip.Color(0, pos * 3, 255 - pos * 3); } pos -= 170; return strip.Color(pos * 3, 255 - pos * 3, 0); } void LEDStripManager::rainbow() { Config cfg = configManager.getConfig(); const uint32_t delay = cfg.rainbowDelay; static uint32_t lastUpdate = 0; if (digitalRead(LED_STRIP_POWER_PIN) == HIGH) { if (millis() - lastUpdate < delay) return; lastUpdate = millis(); for (uint16_t i = 0; i < strip.numPixels(); i++) { uint32_t pixelHue = firstPixelHue + (i * 65536L / strip.numPixels()); strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue))); } strip.show(); firstPixelHue = (firstPixelHue + 256) % 65536; } } void LEDStripManager::doSpectral() { Config cfg = configManager.getConfig(); static uint16_t hue = 0; static uint32_t lastUpdate = 0; const uint16_t hueStep = 65536 / 6; // Abstand der Hauptfarben const uint32_t stepTime = cfg.spectralStepTime; // Zeit bis zur nächsten Farbe if (digitalRead(LED_STRIP_POWER_PIN) == HIGH) { uint32_t now = millis(); if (now - lastUpdate >= 20) { lastUpdate = now; hue += (uint32_t) hueStep * 20 / stepTime; uint32_t color = strip.gamma32(strip.ColorHSV(hue)); for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, color); } strip.show(); } } } void LEDStripManager::fade() { static const uint8_t colors[][3] = { { 255, 0, 0 }, // Rot { 255, 32, 0 }, // Orange { 255, 110, 0 }, // Gelb { 0, 255, 0 }, // Grün { 0, 255, 255 }, // Cyan { 0, 0, 255 }, // Blau { 255, 0, 255 } // Violett }; enum State { HOLD, FADE_OUT, FADE_IN }; Config cfg = configManager.getConfig(); static State state = HOLD; static uint8_t currentColor = 0; static uint32_t stateStart = millis(); const uint32_t holdTime = cfg.fadingHoldTime; const uint32_t fadeTime = cfg.fadingFadeTime; if (digitalRead(LED_STRIP_POWER_PIN) == HIGH) { uint32_t now = millis(); uint32_t elapsed = now - stateStart; float brightness = 1.0f; float maxBrightness = float(cfg.brightness) / 255; switch (state) { case HOLD: brightness = maxBrightness; if (elapsed >= holdTime) { state = FADE_OUT; stateStart = now; } break; case FADE_OUT: brightness = maxBrightness - (float) elapsed / fadeTime; if (brightness < 0.0f) brightness = 0.0f; if (elapsed >= fadeTime) { currentColor = (currentColor + 1) % (sizeof(colors) / sizeof(colors[0])); state = FADE_IN; stateStart = now; } break; case FADE_IN: brightness = (float) elapsed / fadeTime; if (brightness > maxBrightness) brightness = maxBrightness; if (elapsed >= fadeTime) { state = HOLD; stateStart = now; } break; } uint8_t r = colors[currentColor][0] * brightness; uint8_t g = colors[currentColor][1] * brightness; uint8_t b = colors[currentColor][2] * brightness; for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(r, g, b)); } strip.show(); } } void LEDStripManager::flash() { Config cfg = configManager.getConfig(); static const uint32_t onMillis = cfg.flashOnTime; static const uint32_t offMillis = cfg.flashOffTime; static bool ledOn = false; static uint32_t lastChange = 0; if (digitalRead(LED_STRIP_POWER_PIN) == HIGH) { Config cfg = configManager.getConfig(); uint32_t now = millis(); if (ledOn) { if (now - lastChange >= onMillis) { // LEDs ausschalten clear(); show(); ledOn = false; lastChange = now; } } else { if (now - lastChange >= offMillis) { // LEDs einschalten setAll(cfg.singleColor.r, cfg.singleColor.g, cfg.singleColor.b, cfg.singleColor.w); ledOn = true; lastChange = now; } } } }