Der ESP32 ist angeschlossen, die Arduino IDE ist installiert und das erste Programm wurde auf den Mikrocontroller übertragen.
Aber was passiert eigentlich im Programm?
Was bedeuten Begriffe wie:
setup()
loop()
Serial.begin()
oder
Serial.println()?
Genau darum geht es in diesem Beitrag.
Keine Sorge: Für den Einstieg müssen keine komplizierten Programmiersprachen gelernt werden.
Wir schauen uns nur die wichtigsten Grundlagen an, die für fast jedes ESP32-Projekt benötigt werden.
Wie denkt ein ESP32?
Ein ESP32 macht im Grunde etwas sehr Einfaches:
Er arbeitet Befehle ab.
Ein Programm könnte beispielsweise sagen:
LED einschalten
↓
eine Sekunde warten
↓
LED ausschalten
↓
eine Sekunde warten
↓
wieder von vorne
Der ESP32 führt diese Befehle nacheinander aus.
Und zwar sehr schnell.
Damit der ESP32 weiß, welche Befehle er ausführen soll, schreiben wir ein Programm.
Bei Arduino und ESP32 wird dieses Programm häufig als Sketch bezeichnet.
Die Grundstruktur eines ESP32-Programms
Fast jedes einfache ESP32-Programm besitzt zwei wichtige Bereiche:
void setup() {
}
void loop() {
}
Diese beiden Bereiche heißen:
setup()
und
loop()
Wer diese beiden Funktionen verstanden hat, hat bereits einen der wichtigsten Schritte beim ESP32-Programmieren geschafft.
setup() einfach erklärt
Das Wort setup bedeutet ungefähr:
Einrichtung
oder
Vorbereitung
Alles, was innerhalb von setup() steht, wird beim Start des ESP32 einmal ausgeführt.
Newbiely beschreibt setup() ebenfalls als den Bereich, der nach dem Einschalten oder Zurücksetzen einmal ausgeführt wird. Dort werden beispielsweise Pins eingerichtet oder Variablen vorbereitet.
Ein Beispiel:
void setup() {
pinMode(21, OUTPUT);
}
Hier teilen wir dem ESP32 mit:
GPIO 21 soll als Ausgang verwendet werden.
Diese Einstellung muss der ESP32 nur einmal kennen.
Deshalb gehört sie in setup().
Was gehört typischerweise in setup()?
In setup() stehen häufig Dinge wie:
- Pins vorbereiten
- Serial Monitor starten
- Sensoren starten
- Displays starten
- WLAN-Verbindung vorbereiten
- Bibliotheken initialisieren
Zum Beispiel:
void setup() {
Serial.begin(115200);
pinMode(21, OUTPUT);
}
Der ESP32 führt beim Start also aus:
1. Serielle Kommunikation starten
2. GPIO 21 als Ausgang einstellen
Danach ist setup() fertig.
loop() einfach erklärt
Jetzt kommt der zweite wichtige Bereich:
void loop() {
}
loop bedeutet:
Schleife
Alles innerhalb von loop() wird immer wieder ausgeführt.
Newbiely beschreibt die loop()-Funktion als den Teil, der nach setup() beginnt und danach endlos wiederholt wird.
Das bedeutet:
loop startet
↓
Programm ausführen
↓
Ende erreicht
↓
wieder von vorne
Und das passiert solange der ESP32 läuft.
Ein einfaches Beispiel
Wir lassen eine LED blinken.
#define LED_PIN 21
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
Jetzt schauen wir uns an, was der ESP32 tatsächlich macht.
Schritt 1: Einen Namen für den Pin vergeben
Ganz oben steht:
#define LED_PIN 21
Damit sagen wir:
Wenn im Programm LED_PIN steht, ist GPIO 21 gemeint.
Wir könnten auch überall direkt die Zahl 21 verwenden.
Zum Beispiel:
digitalWrite(21, HIGH);
Aber:
digitalWrite(LED_PIN, HIGH);
ist deutlich verständlicher.
Man erkennt sofort:
Hier wird die LED gesteuert.
Schritt 2: Den Pin vorbereiten
Im setup() steht:
pinMode(LED_PIN, OUTPUT);
pinMode() bestimmt, wie ein Anschluss verwendet werden soll.
OUTPUT bedeutet:
Ausgang
Der ESP32 weiß damit:
Über diesen GPIO möchte ich etwas steuern.
Schritt 3: LED einschalten
Jetzt beginnt loop().
Die erste Zeile lautet:
digitalWrite(LED_PIN, HIGH);
Vereinfacht bedeutet:
LED einschalten
HIGH kann man sich für den Anfang als:
EIN
merken.
Schritt 4: Warten
Danach steht:
delay(1000);
delay() bedeutet:
Warte.
Die Zeit wird in Millisekunden angegeben.
Dabei gilt:
1000 Millisekunden = 1 Sekunde
Der ESP32 wartet also eine Sekunde.
Schritt 5: LED ausschalten
Danach kommt:
digitalWrite(LED_PIN, LOW);
LOW bedeutet vereinfacht:
AUS
Die LED wird ausgeschaltet.
Anschließend wartet der ESP32 erneut:
delay(1000);
Und dann?
Jetzt ist loop() am Ende angekommen.
Was passiert?
Der ESP32 springt automatisch wieder an den Anfang von loop().
Also:
LED EIN
↓
1 Sekunde warten
↓
LED AUS
↓
1 Sekunde warten
↓
LED EIN
↓
1 Sekunde warten
↓
LED AUS
↓
...
Die LED blinkt dauerhaft.
Was sind Befehle?
Ein Programm besteht aus vielen einzelnen Anweisungen.
Zum Beispiel:
digitalWrite(LED_PIN, HIGH);
Diese Zeile ist ein Befehl.
Der ESP32 arbeitet die Befehle normalerweise von oben nach unten ab.
Zum Beispiel:
Befehl 1;
Befehl 2;
Befehl 3;
Befehl 4;
Erst Befehl 1.
Dann Befehl 2.
Dann Befehl 3.
Dann Befehl 4.
Warum steht hinter vielen Befehlen ein Semikolon?
Vielleicht ist bereits aufgefallen:
Viele Programmzeilen enden mit:
;
Beispiel:
delay(1000);
Das Semikolon sagt vereinfacht:
Dieser Befehl ist hier zu Ende.
Man kann sich das Semikolon wie einen Punkt am Satzende vorstellen.
Fehlt das Semikolon, meldet die Arduino IDE häufig einen Fehler.
Was bedeuten die geschweiften Klammern?
Im Programm erscheinen immer wieder:
{
}
Diese Klammern markieren einen zusammengehörenden Bereich.
Zum Beispiel:
void setup() {
pinMode(21, OUTPUT);
}
Alles zwischen { und } gehört zu setup().
Oder:
void loop() {
digitalWrite(21, HIGH);
}
Alles innerhalb der Klammern gehört zu loop().
Kommentare: Notizen im Programm
Programme werden schnell länger.
Dann ist es praktisch, Notizen direkt in den Code zu schreiben.
Dafür gibt es Kommentare.
Zum Beispiel:
// LED einschalten
digitalWrite(LED_PIN, HIGH);
Alles hinter:
//
ist ein Kommentar.
Der ESP32 ignoriert diesen Text.
Kommentare sind nur für Menschen gedacht.
Ein komplettes Programm könnte also so aussehen:
#define LED_PIN 21
void setup() {
// LED-Pin als Ausgang festlegen
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// LED einschalten
digitalWrite(LED_PIN, HIGH);
// eine Sekunde warten
delay(1000);
// LED ausschalten
digitalWrite(LED_PIN, LOW);
// eine Sekunde warten
delay(1000);
}
Gerade beim Lernen sind Kommentare sehr hilfreich.
Variablen: Kleine Speicherboxen
Ein Programm muss häufig Werte speichern.
Zum Beispiel:
- Temperatur
- Tastenzustand
- Helligkeit
- Geschwindigkeit
- Anzahl
- Zeit
Dafür gibt es Variablen.
Eine Variable kann man sich wie eine kleine beschriftete Box vorstellen.
Zum Beispiel:
int temperatur = 22;
Die Box heißt:
temperatur
Darin befindet sich:
22
Was bedeutet int?
int ist ein Datentyp.
Er wird für Ganzzahlen verwendet.
Zum Beispiel:
int alter = 16;
int temperatur = 22;
int messwert = 500;
Damit weiß der ESP32:
In dieser Variable wird eine ganze Zahl gespeichert.
Eine Variable verändern
Variablen können ihren Wert ändern.
Zum Beispiel:
int zaehler = 0;
Später:
zaehler = 1;
Dann:
zaehler = 2;
Oder einfacher:
zaehler++;
Das bedeutet:
Erhöhe den Wert um 1.
Aus:
0
wird:
1
danach:
2
danach:
3
und so weiter.
Entscheidungen mit if
Ein Mikrocontroller wird besonders interessant, wenn er Entscheidungen treffen kann.
Dafür gibt es:
if
if bedeutet:
wenn
Ein einfaches Beispiel:
if (temperatur > 30) {
digitalWrite(LED_PIN, HIGH);
}
Das kann man fast wie einen normalen Satz lesen:
WENN die Temperatur größer als 30 ist, DANN schalte die LED ein.
else bedeutet ansonsten
Zusätzlich gibt es:
else
Das bedeutet:
ansonsten
Beispiel:
if (temperatur > 30) {
digitalWrite(LED_PIN, HIGH);
}
else {
digitalWrite(LED_PIN, LOW);
}
Übersetzt:
WENN Temperatur größer als 30
→ LED einschalten
ANSONSTEN
→ LED ausschalten
Damit können wir bereits einfache automatische Steuerungen programmieren.
Vergleiche im Programm
Bei if werden häufig Werte miteinander verglichen.
Dafür gibt es verschiedene Zeichen.
| Zeichen | Bedeutung |
|---|---|
| == | ist gleich |
| != | ist nicht gleich |
| > | größer als |
| < | kleiner als |
| >= | größer oder gleich |
| <= | kleiner oder gleich |
Zum Beispiel:
if (temperatur > 30)
bedeutet:
Ist die Temperatur größer als 30?
Achtung: = und == sind nicht dasselbe
Das ist einer der klassischen Anfängerfehler.
Ein einzelnes:
=
weist einen Wert zu.
Beispiel:
temperatur = 25;
Das bedeutet:
Speichere 25 in temperatur.
Zwei Gleichheitszeichen:
==
vergleichen Werte.
Beispiel:
if (temperatur == 25)
Das bedeutet:
Ist temperatur gleich 25?
Also:
= Wert speichern
== Werte vergleichen
Das sollte man sich merken.
Jetzt wird der Serial Monitor wichtig
Bis jetzt arbeitet unser ESP32 unsichtbar.
Das ist beim Programmieren manchmal unpraktisch.
Woher wissen wir:
- welchen Messwert ein Sensor liefert?
- ob ein Taster erkannt wurde?
- welchen Wert eine Variable besitzt?
- ob ein bestimmter Programmteil ausgeführt wurde?
Dafür gibt es den Serial Monitor.
Newbiely führt den seriellen Monitor direkt bei den ESP32-Grundlagen auf, weil damit Daten zwischen ESP32 und Computer sichtbar gemacht werden können.
Serial Monitor starten
Zuerst müssen wir im Programm die serielle Kommunikation starten.
Das geschieht in setup():
Serial.begin(115200);
Unser Programm sieht dann beispielsweise so aus:
void setup() {
Serial.begin(115200);
}
void loop() {
}
115200 ist die sogenannte Baudrate.
Vereinfacht gesagt bestimmt sie, wie schnell die Daten übertragen werden.
Wichtig ist vor allem:
Die Baudrate im Programm und im Serial Monitor müssen zusammenpassen.
Text ausgeben
Jetzt können wir etwas an den Computer schicken:
Serial.println("Hallo ESP32!");
Das komplette Programm:
void setup() {
Serial.begin(115200);
Serial.println("Hallo ESP32!");
}
void loop() {
}
Im Serial Monitor erscheint:
Hallo ESP32!
Das ist unser einfachstes „Hello World“.
Ein solches erstes Programm gehört auch bei Newbiely zu den Grundlagen des ESP32-Einstiegs.
Serial.print() und Serial.println()
Es gibt zwei häufig verwendete Befehle:
Serial.print()
und
Serial.println()
Der Unterschied ist einfach.
Serial.print()
Bleibt in derselben Zeile.
Serial.print("Temperatur: ");
Serial.print(22);
Ergebnis:
Temperatur: 22
Serial.println()
Beginnt danach eine neue Zeile.
Serial.println("Hallo");
Serial.println("ESP32");
Ergebnis:
Hallo
ESP32
Das zusätzliche ln steht vereinfacht für:
line
also eine neue Zeile.
Variablen im Serial Monitor anzeigen
Jetzt wird der Serial Monitor richtig nützlich.
Wir können eine Variable anzeigen.
int temperatur = 22;
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.print("Temperatur: ");
Serial.println(temperatur);
delay(1000);
}
Im Serial Monitor erscheint:
Temperatur: 22
Temperatur: 22
Temperatur: 22
Temperatur: 22
Warum immer wieder?
Weil die Ausgabe in loop() steht.
Und loop() wird ständig wiederholt.
Ein kleiner Zähler
Probieren wir etwas anderes.
int zaehler = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println(zaehler);
zaehler++;
delay(1000);
}
Der Serial Monitor zeigt:
0
1
2
3
4
5
6
7
...
Was passiert?
Zuerst:
int zaehler = 0;
Der Zähler startet bei 0.
Dann:
Serial.println(zaehler);
Der aktuelle Wert wird angezeigt.
Danach:
zaehler++;
Der Wert wird um 1 erhöht.
Dann wartet der ESP32 eine Sekunde.
Danach beginnt loop() wieder von vorne.
Warum ist der Serial Monitor so wichtig?
Der Serial Monitor ist nicht nur für Textausgaben gedacht.
Er ist eines der wichtigsten Werkzeuge zur Fehlersuche.
Angenommen, ein Taster funktioniert nicht.
Dann könnten wir den Zustand anzeigen:
Serial.println(buttonState);
Oder wir möchten wissen, welchen Wert ein Sensor liefert:
Serial.println(sensorValue);
So sehen wir direkt:
Welche Informationen sieht der ESP32 eigentlich?
Das macht Fehlersuche deutlich einfacher.
Ein komplettes kleines Beispiel
Hier verbinden wir einige der bisherigen Grundlagen.
int temperatur = 25;
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.print("Temperatur: ");
Serial.println(temperatur);
if (temperatur > 30) {
Serial.println("Es ist zu warm!");
}
else {
Serial.println("Temperatur ist in Ordnung.");
}
delay(1000);
}
Im Serial Monitor erscheint:
Temperatur: 25
Temperatur ist in Ordnung.
Ändern wir:
int temperatur = 35;
erscheint:
Temperatur: 35
Es ist zu warm!
Damit haben wir bereits mehrere wichtige Programmiergrundlagen miteinander kombiniert.
Häufige Anfängerfehler
Beim Programmieren passieren Fehler.
Das ist völlig normal.
Einige Fehler treten besonders häufig auf.
Semikolon vergessen
Falsch:
int temperatur = 22
Richtig:
int temperatur = 22;
Klammer vergessen
Falsch:
void setup() {
Serial.begin(115200);
Hier fehlt:
}
Groß- und Kleinschreibung
Beim Programmieren ist Groß- und Kleinschreibung wichtig.
Richtig:
Serial.println();
Falsch:
serial.println();
= und == verwechselt
Wert zuweisen:
wert = 5;
Werte vergleichen:
wert == 5
Baudrate stimmt nicht
Im Programm:
Serial.begin(115200);
Dann sollte auch der Serial Monitor entsprechend eingestellt sein.
Code steht an der falschen Stelle
Steht eine Ausgabe in:
setup()
wird sie nur einmal ausgeführt.
Steht sie in:
loop()
wird sie immer wieder ausgeführt.
Das ist ein wichtiger Unterschied.
setup() oder loop()? Eine einfache Regel
Für den Einstieg hilft diese Faustregel:
setup()
Alles, was nur einmal vorbereitet werden muss.
Zum Beispiel:
Serial.begin();
pinMode();
loop()
Alles, was immer wieder passieren soll.
Zum Beispiel:
Sensor lesen
Taster prüfen
LED schalten
Messwert anzeigen
Vereinfacht:
setup() = vorbereiten
loop() = arbeiten
Muss man den ganzen Code verstehen?
Nein.
Beim Einstieg wirkt ein Programm manchmal wie eine Fremdsprache.
Das ist normal.
Wichtiger ist zunächst, einige wiederkehrende Bausteine zu erkennen:
setup()
einmal beim Start
loop()
immer wieder
pinMode()
Pin vorbereiten
digitalWrite()
Ausgang schalten
digitalRead()
Eingang lesen
if()
Entscheidung treffen
Serial.println()
Information anzeigen
Wer diese Bausteine versteht, kann bereits viele einfache ESP32-Programme lesen und verändern.
Das Wichtigste in 60 Sekunden
Ein ESP32-Programm besitzt normalerweise zwei Hauptbereiche:
void setup() {
}
void loop() {
}
setup() wird beim Start einmal ausgeführt.
loop() läuft danach immer wieder.
Variablen speichern Werte:
int temperatur = 22;
Mit if kann der ESP32 Entscheidungen treffen:
if (temperatur > 30) {
}
Mit:
Serial.println();
können Informationen im Serial Monitor angezeigt werden.
Damit sind bereits die wichtigsten Grundlagen vorhanden, um einfache Programme zu verstehen und selbst zu verändern.
Wie geht es weiter?
Nachdem die Programmstruktur verstanden ist, lohnt sich der Schritt von der Theorie zur echten Elektronik.
Im nächsten Beitrag geht es deshalb um:
ESP32 GPIO einfach erklärt: Eingänge, Ausgänge, HIGH, LOW und die ersten Schaltungen
Dabei schauen wir uns genauer an:
- was GPIO bedeutet
- welche Pins verwendet werden können
- was INPUT und OUTPUT bedeutet
- was HIGH und LOW bedeutet
- wie eine LED angeschlossen wird
- wie ein Taster angeschlossen wird
- warum GND so wichtig ist
- warum der ESP32 mit 3,3 Volt arbeitet
Damit verbindet sich der Programmcode erstmals richtig mit der Außenwelt.
Alle Beiträge dieser Serie
- Teil 1: ESP32 kennenlernen
- Teil 2: ESP32 programmieren (Aktuell)
- Teil 3: GPIO verstehen
- Teil 4: Taster anschließen und entprellen
- Teil 5: LEDs steuern
- Teil 6: Analoge Werte und ADC


Add your first comment to this post