/* ========================================
* Leuchtfeuer für Leuchtturm Blavand Fyr
* Arduino Nano V3 + WS2812E LED-Matrix
* ========================================
*
* HARDWARE-ANSCHLUSS:
* Arduino GND → LED-Streifen GND UND Netzteil (-)
* Arduino D13 → [150Ω Widerstand] → LED-Streifen D_in
* Externes Netzteil 5V/5A:
* Netzteil (+) → LED-Streifen +5V
* Netzteil (-) → LED-Streifen GND UND Arduino GND (gemeinsame Masse!)
*
* BIBLIOTHEK:
* Adafruit NeoPixel (installieren über Arduino IDE: Tools → Manage Libraries)
*/
#include <Adafruit_NeoPixel.h>
// ========================================
// EINSTELLUNGEN - Hier kannst du Werte ändern!
// ========================================
// LED-Matrix Dimensionen
const int BREITE = 28; // Anzahl LEDs horizontal (umlaufend)
const int HOEHE = 5; // Anzahl LEDs vertikal (übereinander)
// Leuchtfeuer Eigenschaften
const int LICHTBREITE = 5; // Breite des Lichtstrahls (in LEDs)
const int HELLIGKEIT = 255; // 0 = aus, 255 = maximale Helligkeit
// TIPP: Starte mit 50 für Tests, dann hochregeln!
// Fading-Effekt: Helligkeitswerte für jede Spalte des Lichtstrahls
// Spalte 1 (außen) → Spalte 2 → Spalte 3 (Mitte) → Spalte 4 → Spalte 5 (außen)
const float HELLIGKEITSSTUFEN[5] = {0.2, 0.6, 1.0, 0.6, 0.2};
// 0.2 = 20% Helligkeit (außen)
// 0.6 = 60% Helligkeit
// 1.0 = 100% Helligkeit (Mitte)
// Du kannst diese Werte anpassen für stärkeren/schwächeren Fading!
const int GESCHWINDIGKEIT = 140; // Wartezeit in Millisekunden (ms)
// Kleiner = schneller, Größer = langsamer
// TIPP: 140ms = ca. 5 Sekunden pro Umdrehung
// Farbe des Lichts (Hex-Format: 0xRRGGBB)
const uint32_t LICHTFARBE = 0xFFFFFF; // Weiß
// Andere Beispiele:
// 0xFFFF00 = Gelb
// 0xFFAA00 = Warmes Weiß/Orange
// 0xFF0000 = Rot
// 0x00FF00 = Grün
// 0x0000FF = Blau
// Hardware Pin
const int LED_PIN = 13; // Datenleitung an Arduino Pin D13
// ========================================
// SYSTEM-VARIABLEN (nicht ändern)
// ========================================
const int ANZAHL_LEDS = BREITE * HOEHE; // Gesamt: 140 LEDs
// LED-Streifen initialisieren
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ANZAHL_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// ========================================
// SETUP - Wird einmal beim Start ausgeführt
// ========================================
void setup()
{
strip.begin(); // LED-Streifen starten
strip.setBrightness(HELLIGKEIT); // Helligkeit einstellen
strip.clear(); // Alle LEDs ausschalten
strip.show(); // Änderungen übertragen
// Optional: Serielle Kommunikation für Debugging
// Serial.begin(9600);
// Serial.println("Leuchtfeuer gestartet!");
}
// ========================================
// HAUPTSCHLEIFE - Läuft endlos
// ========================================
void loop()
{
// Einmal komplett um den Leuchtturm rotieren (28 Schritte)
for(int schritt = 0; schritt < BREITE; schritt++)
{
// Schritt 1: Alle LEDs um eine Position weiter schieben
verschiebeAllesUmEinePosition();
// Schritt 2: Neue LEDs am Anfang einschalten (Lichtstrahl "nachfüllen")
// Jetzt mit Fading-Effekt: Jede Spalte bekommt eigene Helligkeit
if (schritt < LICHTBREITE) {
schalteErsteSpalteEinMitFading(schritt);
}
// Schritt 3: Änderungen sichtbar machen
strip.show();
// Schritt 4: Kurz warten (steuert Rotationsgeschwindigkeit)
delay(GESCHWINDIGKEIT);
}
}
// ========================================
// HILFSFUNKTIONEN
// ========================================
/* Schaltet die erste Spalte aller Zeilen ein - MIT FADING-EFFEKT
* Parameter: aktuellerSchritt = welche Spalte im Lichtstrahl wird gerade gefüllt (0-4)
* Dies erzeugt neue LEDs für den Lichtstrahl mit angepasster Helligkeit
*/
void schalteErsteSpalteEinMitFading(int aktuellerSchritt)
{
// Helligkeit für diese Spalte aus dem Array holen
float helligkeitsFaktor = HELLIGKEITSSTUFEN[aktuellerSchritt];
// Farbe mit angepasster Helligkeit berechnen
uint32_t gedimmteFarbe = dimmeRGBFarbe(LICHTFARBE, helligkeitsFaktor);
// Erste Spalte aller Zeilen mit der gedimmten Farbe einschalten
for(int zeile = 0; zeile < HOEHE; zeile++)
{
int led_position = zeile * BREITE; // Position 0, 28, 56, 84, 112
strip.setPixelColor(led_position, gedimmteFarbe);
}
}
/* Dimmt eine RGB-Farbe um einen bestimmten Faktor
* farbe: Original-Farbe im Format 0xRRGGBB
* faktor: 0.0 (dunkel) bis 1.0 (volle Helligkeit)
* Gibt die gedimmte Farbe zurück
*/
uint32_t dimmeRGBFarbe(uint32_t farbe, float faktor)
{
// Farbe in R, G, B Komponenten zerlegen
uint8_t rot = (farbe >> 16) & 0xFF; // Extrahiere Rot
uint8_t gruen = (farbe >> 8) & 0xFF; // Extrahiere Grün
uint8_t blau = farbe & 0xFF; // Extrahiere Blau
// Jede Komponente mit dem Faktor multiplizieren
rot = (uint8_t)(rot * faktor);
gruen = (uint8_t)(gruen * faktor);
blau = (uint8_t)(blau * faktor);
// Zurück zu einer Farbe zusammensetzen
return strip.Color(rot, gruen, blau);
}
/* Verschiebt alle LEDs um eine Position nach rechts
* Beispiel: LED[0] → LED[1], LED[1] → LED[2], etc.
* LED[27] → LED[0] (läuft im Kreis)
*/
void verschiebeAllesUmEinePosition()
{
// Von rechts nach links durchgehen (damit wir nichts überschreiben)
for(int spalte = BREITE - 1; spalte > 0; spalte--)
{
// Jede Zeile einzeln bearbeiten
for(int zeile = 0; zeile < HOEHE; zeile++)
{
// Aktuelle LED-Position berechnen
int aktuelle_position = spalte + (zeile * BREITE);
int vorherige_position = aktuelle_position - 1;
// Farbe von vorheriger LED kopieren
uint32_t farbe = strip.getPixelColor(vorherige_position);
strip.setPixelColor(aktuelle_position, farbe);
}
}
// Erste Spalte löschen (wird im nächsten Schritt neu gefüllt)
for(int zeile = 0; zeile < HOEHE; zeile++)
{
strip.setPixelColor(zeile * BREITE, 0); // 0 = schwarz/aus
}
}
// ========================================
// ZUSÄTZLICHE TIPPS ZUM EXPERIMENTIEREN:
// ========================================
/*
* GESCHWINDIGKEIT ÄNDERN:
* - Wert bei GESCHWINDIGKEIT anpassen (z.B. 70 = doppelt so schnell)
* - Formel: Zeit pro Umdrehung ≈ GESCHWINDIGKEIT × 28 ÷ 1000 Sekunden
*
* HELLIGKEIT ANPASSEN:
* - Start mit niedrigen Werten (30-50) zum Testen
* - Hohe Werte (>150) brauchen viel Strom!
*
* FARBE ÄNDERN:
* - Hex-Werte bei LICHTFARBE eintragen
* - Online Farbwähler nutzen und RGB zu Hex konvertieren
*
* LICHTBREITE VARIIEREN:
* - LICHTBREITE = 1: Schmaler Strahl (ohne Fading)
* - LICHTBREITE = 5: Mit Fading-Effekt (aktuelle Einstellung)
* - LICHTBREITE = 7 oder mehr: Array HELLIGKEITSSTUFEN erweitern!
*
* FADING-EFFEKT ANPASSEN:
* Beispiele für HELLIGKEITSSTUFEN[5]:
* - Sanftes Fading: {0.3, 0.6, 1.0, 0.6, 0.3}
* - Starkes Fading: {0.1, 0.4, 1.0, 0.4, 0.1}
* - Asymmetrisch: {0.5, 0.8, 1.0, 0.7, 0.2}
* - Kein Fading: {1.0, 1.0, 1.0, 1.0, 1.0}
* - Nur Mitte hell: {0.0, 0.3, 1.0, 0.3, 0.0}
*
* FÜR 7 SPALTEN (LICHTBREITE = 7):
* const float HELLIGKEITSSTUFEN[7] = {0.15, 0.3, 0.6, 1.0, 0.6, 0.3, 0.15};
*/