/*
LED_Knob_Detailed.ino
Erweiterter und sehr ausführlich kommentierter Quellcode für ein Arduino-Projekt
Funktion: Ein Drehpotentiometer (Analoger Eingang A0) steuert, welche von 4 LEDs eingeschaltet wird.
- Originalverhalten beibehalten
- Robustheit verbessert (Out-of-bounds-Vermeidung, Glättung/Hysterese, flexiblere Reset-Funktion)
- Detaillierte Kommentare erklären jede Zeile und Design-Entscheidung
Hinweise:
- analogRead() liefert Werte im Bereich 0..1023 (bei 10‑Bit ADC).
- map() kann theoretisch Werte außerhalb des Zielbereichs liefern, deshalb wird constrain() verwendet.
- Ein kleiner Hysterese-/Änderungscheck verhindert unnötiges Flackern bei feinen Potentiometer‑Positionen.
*/
#define KNOB A0 // Drehpotentiometer am analogen PIN A0
// Definieren der LEDs (besser als "magic numbers" im Code)
#define LED_1 4 // LED1 rot
#define LED_2 5 // LED2 grün
#define LED_3 6 // LED3 blau
#define LED_4 7 // LED4 gelb
// Alle vier LEDs zu einem Array zusammenfassen
// Dies ist für das Mapping später von Vorteil und macht den Code skalierbar
int leds[] = {LED_1, LED_2, LED_3, LED_4};
// Anzahl der LEDs automatisch aus der Array-Größe ableiten
const int NUM_LEDS = sizeof(leds) / sizeof(leds[0]);
// Hysterese / Stabilitätsparameter
// Wenn der berechnete Ziel-LED-Index sich nicht ändert, wird keine Aktion durchgeführt.
// Das reduziert Flackern bei analogem Rauschen oder genau zwischen zwei LED-Grenzen.
int lastLed = -1; // Merkt sich welche LED zuletzt eingeschaltet war
void setup() {
Serial.begin(9600); // Serielle Ausgabe für Debug/Monitoring
// Setzen der LEDs als Ausgang
// Wir verwenden eine Schleife statt viermal pinMode() aufzurufen.
for (int i = 0; i < NUM_LEDS; i++) {
pinMode(leds[i], OUTPUT);
// Alle LEDs beim Start sicherheitshalber ausschalten
digitalWrite(leds[i], LOW);
}
// Kurze Info beim Start
Serial.println("System gestartet: Potentiometer steuert 4 LEDs");
}
void loop() {
// Lesen des aktuellen Wertes am analogen Pin A0
// analogRead liefert Integer 0..1023 (für AVR-basiertes Arduino)
int value = analogRead(KNOB);
Serial.print("analoger Wert: ");
Serial.println(value);
// Mappen des Wertes vom Drehpotentiometer auf einen Wert zwischen 0 und NUM_LEDS-1.
// WICHTIG: map() selbst kann bei Extremen Werte außerhalb des Zielbereichs liefern,
// deshalb begrenzen wir das Ergebnis mit constrain().
int ledIndex = map(value, 0, 1023, 0, NUM_LEDS - 1);
ledIndex = constrain(ledIndex, 0, NUM_LEDS - 1); // Sicherheits-Constraint
Serial.print("berechneter LED-Index: ");
Serial.println(ledIndex);
// Hysterese: nur wenn sich der Index ändert, LEDs aktualisieren
if (ledIndex != lastLed) {
// Zurücksetzen der LEDs (alle ausschalten)
resetLEDs();
// Aktivieren der ausgewählten LED. Safety-Check: Index validieren.
if (ledIndex >= 0 && ledIndex < NUM_LEDS) {
digitalWrite(leds[ledIndex], HIGH);
Serial.print("LED eingeschaltet (Pin): ");
Serial.println(leds[ledIndex]);
} else {
// Sollte nicht vorkommen, aber zur Laufzeit-Fehlerdiagnose nützlich
Serial.println("Fehler: berechneter LED-Index außerhalb des gültigen Bereichs");
}
// Letzten Zustand aktualisieren
lastLed = ledIndex;
}
// Kleine Pause: reduziert serielle Flut und gibt Zeit für die Hardware
delay(75); // 75 ms ist ein guter Kompromiss zwischen Reaktionsgeschwindigkeit und Stabilität
}
// Funktion um die LEDs wieder zurückzusetzen.
// Statt jede LED einzeln zu adressieren, wird das Array verwendet — skalierbar und weniger fehleranfällig.
void resetLEDs(){
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(leds[i], LOW);
}
}