Eine LED ist wahrscheinlich das bekannteste Bauteil für den Einstieg in die Mikrocontroller-Welt.
Warum?
Weil man sofort sieht, ob das Programm funktioniert.
Der ESP32 kann eine LED:
- einschalten
- ausschalten
- blinken lassen
- unterschiedlich schnell blinken lassen
- mehrere LEDs steuern
- dimmen
- abhängig von Sensoren oder Tastern schalten
Dabei lernen wir einige der wichtigsten Grundlagen der ESP32-Programmierung kennen.
In diesem Beitrag schauen wir uns deshalb die LED am ESP32 Schritt für Schritt an.
Ganz einfach erklärt.
Was ist eine LED?
LED bedeutet:
Light Emitting Diode
Auf Deutsch:
Leuchtdiode
Eine LED ist ein elektronisches Bauteil, das Licht erzeugt, wenn Strom in der richtigen Richtung hindurchfließt.
Das Wort Diode ist dabei wichtig.
Denn eine LED lässt den Strom nicht einfach in beide Richtungen fließen.
Deshalb muss sie richtig herum angeschlossen werden.
Plus und Minus bei einer LED
Eine normale bedrahtete LED besitzt zwei Anschlüsse:
Anode (+)
und
Kathode (-)
Bei vielen LEDs gilt:
langes Bein = Anode (+)
kurzes Bein = Kathode (-)
Zusätzlich besitzt das Kunststoffgehäuse häufig auf der Kathodenseite eine abgeflachte Stelle.
Newbiely beschreibt ebenfalls die Kathode als Minus-Anschluss und die Anode als den Anschluss, über den die LED gesteuert wird.
Was passiert, wenn die LED falsch herum angeschlossen wird?
Dann leuchtet sie normalerweise nicht.
Das ist ein häufiger Anfängerfehler.
Wenn eine LED trotz scheinbar richtigem Programm nicht leuchtet, sollte deshalb zuerst geprüft werden:
Ist die LED richtig herum eingebaut?
Warum braucht eine LED einen Widerstand?
Eine LED sollte normalerweise nicht einfach direkt zwischen einen GPIO und GND angeschlossen werden.
Der Grund:
Eine LED begrenzt ihren Strom nicht ausreichend selbst.
Ohne passenden Widerstand könnte zu viel Strom fließen.
Das kann die LED beschädigen und den Ausgang des ESP32 unnötig belasten.
Deshalb verwenden wir einen:
Vorwiderstand
Newbiely verwendet in seinem einfachen ESP32-LED-Aufbau beispielsweise einen 220-Ω-Widerstand und weist ebenfalls darauf hin, dass LEDs normalerweise einen Strombegrenzungswiderstand benötigen.
Wie wird der Widerstand angeschlossen?
Vereinfacht beispielsweise so:
ESP32 GPIO
│
│
Widerstand
│
│
LED
│
│
GND
Der Widerstand kann grundsätzlich auf der Anoden- oder Kathodenseite in Reihe zur LED sitzen.
Wichtig ist:
Der Strom muss durch den Widerstand und die LED fließen.
Welche Widerstandsgröße sollte verwendet werden?
Für einfache Experimente mit einer Standard-LED werden häufig Werte wie:
220 Ω
oder
330 Ω
verwendet.
Welcher Wert genau geeignet ist, hängt unter anderem von der LED-Farbe, ihrer Durchlassspannung und dem gewünschten Strom ab.
Für einen ersten Breadboard-Versuch ist ein Widerstand im Bereich einiger hundert Ohm eine gute, vorsichtige Wahl.
LED an den ESP32 anschließen
Für unser Beispiel verwenden wir:
GPIO 18
Die Schaltung sieht vereinfacht so aus:
GPIO 18
│
│
220 Ω
│
│
LED
│
│
GND
Damit können wir GPIO 18 verwenden, um die LED zu steuern.
GPIO als Ausgang einstellen
Bevor wir eine LED steuern können, müssen wir dem ESP32 sagen:
Dieser GPIO soll als Ausgang verwendet werden.
Dafür gibt es:
pinMode();
Zum Beispiel:
pinMode(18, OUTPUT);
Noch übersichtlicher wird es, wenn wir dem Pin einen Namen geben:
#define LED_PIN 18
Dann können wir schreiben:
pinMode(LED_PIN, OUTPUT);
LED einschalten
Jetzt kommt:
digitalWrite(LED_PIN, HIGH);
Vereinfacht bedeutet das:
Ausgang HIGH
und bei unserer Schaltung:
LED an
Newbiely verwendet genau dieses Prinzip ebenfalls: GPIO als OUTPUT konfigurieren und anschließend mit digitalWrite() zwischen HIGH und LOW wechseln.
LED ausschalten
Zum Ausschalten verwenden wir:
digitalWrite(LED_PIN, LOW);
Damit erhalten wir:
HIGH → LED an
LOW → LED aus
Unser erstes LED-Programm
#define LED_PIN 18
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
}
Nach dem Start bleibt die LED eingeschaltet.
Möchten wir sie ausschalten:
digitalWrite(LED_PIN, LOW);
Jetzt lassen wir die LED blinken
Ein echter Klassiker der Mikrocontroller-Programmierung ist:
Blink
Die LED soll:
AN
↓
warten
↓
AUS
↓
warten
↓
wieder von vorne
Dafür verwenden wir delay().
Was bedeutet delay()?
delay() hält das Programm für eine bestimmte Anzahl von Millisekunden an.
Zum Beispiel:
delay(1000);
bedeutet:
1000 Millisekunden warten
Also:
1 Sekunde
Das Blink-Programm
#define LED_PIN 18
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
Der Ablauf:
LED an
↓
1 Sekunde
↓
LED aus
↓
1 Sekunde
↓
LED an
↓
...
Damit blinkt die LED dauerhaft.
Blinkgeschwindigkeit verändern
Die Geschwindigkeit können wir sehr einfach verändern.
Schneller:
delay(200);
Langsamer:
delay(2000);
Zum Beispiel:
digitalWrite(LED_PIN, HIGH);
delay(200);
digitalWrite(LED_PIN, LOW);
delay(200);
Jetzt blinkt die LED deutlich schneller.
Blinkzeit als Variable speichern
Noch schöner wird unser Programm, wenn wir die Zeit nicht überall direkt eintragen.
Zum Beispiel:
int blinkTime = 500;
Dann:
#define LED_PIN 18
int blinkTime = 500;
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(blinkTime);
digitalWrite(LED_PIN, LOW);
delay(blinkTime);
}
Jetzt müssen wir nur noch:
int blinkTime = 500;
ändern.
Zum Beispiel:
int blinkTime = 100;
oder:
int blinkTime = 2000;
Das Programm bleibt ansonsten gleich.
Mehrere LEDs steuern
Jetzt können wir mehrere Ausgänge verwenden.
Zum Beispiel:
- rote LED
- gelbe LED
- grüne LED
Wir definieren:
#define RED_LED 18
#define YELLOW_LED 19
#define GREEN_LED 21
Im setup():
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
Damit kann jede LED einzeln gesteuert werden.
Eine einfache Ampel
Das Prinzip einer Ampel ist perfekt, um mehrere digitale Ausgänge kennenzulernen.
Wir benötigen:
- rote LED
- gelbe LED
- grüne LED
- je einen passenden Vorwiderstand
Newbiely behandelt eine ESP32-Ampel ebenfalls als Kombination mehrerer digitaler Ausgänge. Dort werden Rot, Gelb und Grün über getrennte GPIOs gesteuert.
Einfaches Ampelprogramm
#define RED_LED 18
#define YELLOW_LED 19
#define GREEN_LED 21
void setup() {
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
}
void loop() {
// Rot
digitalWrite(RED_LED, HIGH);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
delay(3000);
// Rot-Gelb
digitalWrite(RED_LED, HIGH);
digitalWrite(YELLOW_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
delay(1000);
// Grün
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
delay(3000);
// Gelb
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
delay(1000);
}
Damit haben wir schon einen kleinen automatischen Ablauf programmiert.
Aber delay() hat einen Haken
Für erste Übungen ist:
delay();
sehr praktisch.
Es gibt aber ein Problem.
Während:
delay(3000);
läuft, wartet das Programm.
Der ESP32 arbeitet während dieser Zeit unseren normalen Programmablauf nicht weiter ab.
Newbiely weist beim Blink-Beispiel ausdrücklich darauf hin, dass delay() andere Aufgaben blockiert und zeigt deshalb zusätzlich eine Variante mit millis().
Warum kann das problematisch sein?
Stellen wir uns vor, unsere Ampel soll gleichzeitig einen Taster erkennen.
Das Programm steht gerade hier:
delay(3000);
Jetzt wird der Taster gedrückt.
Unser Programm wartet aber noch.
Es schaut momentan gar nicht nach dem Taster.
Das ist ungefähr so, als würde jemand sagen:
Ich mache jetzt drei Sekunden lang gar nichts. Danach schaue ich wieder, was passiert ist.
Für einfache Blinkübungen ist das egal.
Für größere Programme wird es problematisch.
Die bessere Idee: Auf die Uhr schauen
Statt zu sagen:
Warte 1000 Millisekunden.
können wir sagen:
Schau auf die Uhr und prüfe, ob bereits 1000 Millisekunden vergangen sind.
Dafür gibt es beim ESP32:
millis();
Newbiely verwendet genau dieses Prinzip für „Blinken ohne Verzögerung“.
millis() einfach erklärt
millis() liefert die Zeit, die seit dem Start des Programms vergangen ist.
Vereinfacht beispielsweise:
Start
0 ms
↓
500 ms
↓
1000 ms
↓
1500 ms
↓
2000 ms
Das Programm kann also fragen:
Ist seit der letzten Aktion genug Zeit vergangen?
Wenn ja:
LED umschalten
Wenn nein:
einfach weiterarbeiten
Warum ist millis() besser?
Mit delay():
LED an
↓
WARTEN
↓
WARTEN
↓
WARTEN
↓
LED aus
Mit millis():
LED an
↓
Zeit prüfen
↓
Taster prüfen
↓
Sensor prüfen
↓
Zeit prüfen
↓
andere Aufgabe
↓
Zeit prüfen
Der ESP32 kann also zwischenzeitlich andere Aufgaben erledigen.
LED blinken ohne delay()
Ein vereinfachtes Beispiel:
#define LED_PIN 18
unsigned long previousMillis = 0;
const long interval = 1000;
bool ledState = false;
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
}
}
Das sieht zunächst komplizierter aus.
Das Prinzip ist aber einfach.
Was passiert hier?
Wir speichern:
previousMillis
also:
Wann wurde die LED zuletzt umgeschaltet?
Dann schauen wir:
currentMillis = millis();
Wie spät ist es jetzt?
Anschließend vergleichen wir:
currentMillis - previousMillis >= interval
Vereinfacht:
Ist seit der letzten Umschaltung mindestens eine Sekunde vergangen?
Wenn ja:
LED umschalten
Wenn nein:
nichts tun und loop() weiterlaufen lassen
Warum lohnt es sich, millis() zu lernen?
Weil fast jedes größere Mikrocontrollerprojekt mehrere Dinge gleichzeitig machen soll.
Zum Beispiel:
LED blinken
+
Taster prüfen
+
Temperatur messen
+
Display aktualisieren
+
WLAN bedienen
Mit vielen langen delay()-Befehlen wird das schwierig.
Mit zeitgesteuerten Abläufen über millis() bleibt das Programm wesentlich reaktionsfähiger.
Kann eine LED nur AN und AUS?
Nein.
Bis jetzt kennen wir:
0 %
oder
100 %
Aber eine LED kann auch gedimmt werden.
Zum Beispiel:
0 %
25 %
50 %
75 %
100 %
Dafür verwenden Mikrocontroller häufig:
PWM
Was ist PWM?
PWM bedeutet:
Pulse Width Modulation
Auf Deutsch:
Pulsweitenmodulation
Das klingt kompliziert.
Das Prinzip ist aber erstaunlich einfach.
Der ESP32 schaltet die LED sehr schnell:
AN
und:
AUS
So schnell, dass unser Auge die einzelnen Schaltvorgänge nicht mehr wahrnimmt.
Ein einfaches Beispiel
Die LED ist immer eingeschaltet:
AN AN AN AN AN AN AN AN
Sie wirkt sehr hell.
Jetzt:
AN AUS AN AUS AN AUS AN AUS
Sie ist nur ungefähr die Hälfte der Zeit eingeschaltet.
Für unser Auge wirkt sie:
dunkler
Noch weniger:
AN AUS AUS AUS AN AUS AUS AUS
Die LED wirkt noch dunkler.
Was ist das Tastverhältnis?
Das Verhältnis zwischen:
EIN-Zeit
und:
AUS-Zeit
wird häufig als:
Duty Cycle
oder:
Tastverhältnis
bezeichnet.
Zum Beispiel:
0 % → LED aus
25 % → eher dunkel
50 % → mittlere Helligkeit
75 % → hell
100 % → volle Helligkeit
Newbiely erklärt das Dimmen ebenfalls über ein PWM-Signal: Je größer das Tastverhältnis, desto heller erscheint die LED.
Warum wird die Spannung nicht einfach kleiner gemacht?
Der ESP32 erzeugt an einem normalen digitalen Ausgang grundsätzlich digitale Zustände.
Also vereinfacht:
LOW
oder
HIGH
PWM erzeugt die scheinbare Zwischenstufe durch sehr schnelles Umschalten.
Damit lassen sich nicht nur LEDs dimmen.
PWM wird beispielsweise auch für andere Steueraufgaben verwendet.
LED langsam heller und dunkler werden lassen
Ein schöner Effekt ist:
dunkel
↓
heller
↓
noch heller
↓
maximal hell
↓
dunkler
↓
noch dunkler
↓
aus
Dieser Effekt wird häufig als:
Fade
bezeichnet.
Newbiely hat dafür ein eigenes ESP32-Tutorial und zeigt dort sowohl Varianten mit delay() als auch mit millis().
Für den Einstieg reicht zunächst das Verständnis:
Die Helligkeit wird nicht nur mit HIGH und LOW gesteuert, sondern über ein PWM-Signal.
Kann jeder GPIO für LEDs verwendet werden?
Nicht automatisch.
Je nach verwendetem ESP32-Chip und Development Board können einzelne GPIOs besondere Funktionen oder Einschränkungen besitzen.
Deshalb gilt:
Vor dem Aufbau immer die Pinbelegung des konkret verwendeten ESP32-Boards prüfen.
Das gilt besonders dann, wenn später:
- PWM
- ADC
- I²C
- SPI
- UART
oder andere Spezialfunktionen verwendet werden.
Eingebaute LED oder externe LED?
Manche ESP32-Boards besitzen bereits eine LED auf der Platine.
Das ist praktisch für erste Tests.
Allerdings gilt:
Nicht jedes ESP32-Board besitzt dieselbe LED am selben GPIO.
Deshalb sollte die Dokumentation des konkreten Boards geprüft werden.
Für Lernprojekte ist eine externe LED oft sogar besser.
Warum?
Weil dabei gleichzeitig gelernt wird:
- Breadboard verwenden
- Polarität beachten
- Widerstand verwenden
- GPIO verbinden
- GND verbinden
LED und Taster kombinieren
Aus dem letzten Beitrag kennen wir bereits den Taster.
Jetzt können wir beide Bauteile kombinieren.
TASTER
↓
ESP32
↓
LED
Zum Beispiel:
#define BUTTON_PIN 21
#define LED_PIN 18
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
digitalWrite(LED_PIN, HIGH);
}
else {
digitalWrite(LED_PIN, LOW);
}
}
Jetzt gilt:
Taster drücken
↓
LED an
Taster loslassen:
LED aus
Damit verbinden wir einen digitalen Eingang mit einem digitalen Ausgang.
Sensor und LED kombinieren
Dasselbe Prinzip funktioniert später auch mit Sensoren.
Zum Beispiel:
Lichtsensor
↓
ESP32
↓
zu dunkel?
↓
JA
↓
LED an
Oder:
Bewegungsmelder
↓
ESP32
↓
Bewegung erkannt?
↓
JA
↓
LED an
Die LED ist deshalb nicht nur eine Lernübung.
Sie ist auch eine einfache Möglichkeit, Zustände sichtbar zu machen.
LEDs als Statusanzeige
In echten Projekten können LEDs beispielsweise anzeigen:
Grün
→ System läuft
Gelb
→ Verbindung wird aufgebaut
Rot
→ Fehler
Oder:
Blinken
→ WLAN-Verbindung wird gesucht
Damit kann eine einzelne LED bereits viele Informationen vermitteln.
Typische Anfängerfehler mit LEDs
Wenn eine LED nicht funktioniert, liegt es häufig an einem kleinen Fehler.
LED falsch herum
Anode und Kathode prüfen.
GND fehlt
Die Schaltung benötigt einen vollständigen Stromkreis.
Falscher GPIO
Im Programm:
#define LED_PIN 18
Die LED steckt aber an GPIO 21.
Programm und Hardware müssen zusammenpassen.
GPIO nicht als OUTPUT eingestellt
Es fehlt:
pinMode(LED_PIN, OUTPUT);
Vorwiderstand vergessen
Eine normale externe LED sollte mit einem geeigneten Strombegrenzungswiderstand verwendet werden.
HIGH und LOW verwechselt
Bei unserer Standardschaltung:
HIGH = LED an
LOW = LED aus
Bei anders aufgebauten Schaltungen kann sich diese Logik jedoch auch umkehren.
delay() blockiert das Programm
Bei einer einzelnen blinkenden LED ist das kein Problem.
Sobald mehrere Dinge gleichzeitig passieren sollen, sollte über Alternativen wie millis() nachgedacht werden.
Die wichtigsten LED-Befehle
GPIO als Ausgang:
pinMode(LED_PIN, OUTPUT);
LED einschalten:
digitalWrite(LED_PIN, HIGH);
LED ausschalten:
digitalWrite(LED_PIN, LOW);
Warten:
delay(1000);
Zeit seit Programmstart abfragen:
millis();
Mit diesen wenigen Grundlagen lassen sich bereits viele LED-Projekte umsetzen.
Das Wichtigste in 60 Sekunden
Eine LED besitzt:
Anode (+)
und:
Kathode (-)
Bei einer normalen LED wird ein geeigneter Vorwiderstand verwendet.
Eine einfache Schaltung:
GPIO
│
Widerstand
│
LED
│
GND
Den GPIO stellen wir auf Ausgang:
pinMode(LED_PIN, OUTPUT);
LED einschalten:
digitalWrite(LED_PIN, HIGH);
LED ausschalten:
digitalWrite(LED_PIN, LOW);
Mit:
delay();
können wir eine einfache Blinkschaltung programmieren.
Für größere Programme ist:
millis();
häufig besser geeignet, weil das Programm während der Wartezeit weiterarbeiten kann.
Und mit:
PWM
kann die wahrgenommene Helligkeit einer LED verändert werden.
Damit sind die wichtigsten Grundlagen für LEDs am ESP32 verstanden.
Wie geht es weiter?
Wir kennen jetzt:
- digitale Eingänge
- digitale Ausgänge
- Taster
- LEDs
- HIGH und LOW
digitalRead()digitalWrite()delay()millis()
Der nächste wichtige Schritt sind Werte, die nicht nur:
0 oder 1
kennen.
Im nächsten Beitrag geht es deshalb um:
ESP32 und analoge Werte
Dabei schauen wir uns an:
- was analog bedeutet
- Unterschied zwischen digital und analog
- was ein ADC ist
analogRead()- Potentiometer anschließen
- Messwerte im Serial Monitor anzeigen
- Werte verändern und vergleichen
- Grenzwerte verwenden
- LED abhängig vom Potentiometer steuern
- analoge Sensoren verstehen
Damit kommen wir von einfachen EIN/AUS-Signalen zu echten Messwerten.


Add your first comment to this post