Erste Schritte mit dem Microcontroller ESP32
https://oer-informatik.de/helloworld_esp32
tl/dr; (ca. 12 min Lesezeit): Keine neue Programmiersprache ohne ein “Hello World”, kein Microcontroller-Projekt ohne LED-Blinken. Hier geht es nur um die ersten Schritte mit dem ESP32-Board: Einrichtung und zwei kleine Beispielprogramme zur Nutzung der internen LED und Taster.
Treiber für den ESP32-Board installieren
Damit der Microcontroller auf dem ESP32 erkannt wird, muss zunächst ein Treiber in der Arduino-IDE nachinstalliert werden (oder geprüft werden, ob die Einstellungen bereits vorhanden sind).
Unter Datei/Einstellungen
(bzw. File/Preferences
) gibt es den Punkt “Additional boards manager URLs”

Es öffnet sich ein Fenster, in dem die folgende zusätzliche URL eingetragen werden muss:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Nach dem Klick auf “ok” wird die verlinkte JSON-Datei geladen. Dann KANN im Boardmanager der entsprechende Treiber geladen werden. Boardsmanager öffnen (Tools/Board/BoardsManager
):

Im Boards-Manager nach “ESP32” suchen und die Boards installieren:

Port und Board
Der häufigste Fehler bei der Programmierung in der Arduino-IDE ist die Auswahl eines falschen Boards / Ports. Immer, wenn Fehler beim Übertragen eines Programms auftauchen, sollte überprüft werden, ob die folgenden Einstellungen stimmen.
An welchem Port hängt mein ESP32?
Unter Windows-Systemen wird dem ESP32 ein COM-Port zugewiesen. Die zugewiesene Nummer weicht dabei ab, wenn unterschiedliche weitere Geräte angemeldet sind. Ein einfacher Weg, herauszufinden, welcher COM-Port zugewiesen wurde ist, das Board ein- und auszustecken und zu beobachten, welcher COM-Port betroffen ist.
In meinem Fall wurde dem Board COM4
zugewiesen. Falls hier kein Board erscheint muss ggf. der USB-Treiber noch nachinstalliert werden.
In der IDE wird der entsprechende Port über Tools/Port
eingetragen:

Wer unsicher ist, welcher COM-Port betroffen ist - oder auf Fehler stößt und zusätzliche Infos benötigt - der kann z.B. im Gerätemanager oder mit Hilfe der PowerShell nach angeschlossenen USB-Devices suchen:
Aus der zugehörigen Ausgabe geht auch hervor, welcher USB-Chip verwendet wird (hier: CP210x).
Class Name Description PNPDeviceID
----- ---- ----------- -----------
Ports Silicon Labs CP210x USB to UART Bridge (COM4) Silicon Labs CP210x USB to UART Bridge USB\VID_10C4&PID_EA60\0001
COM-Port zugewiesen? Super, Du kannst diesen Abschnitt überspringen und bei “Board” weiterlesen. Sollte dem ESP kein Port zugewiesen werden, dann ist möglicherweise der USB-Treiber für den verwendeten Chip nicht installiert (USB-zu UART-Bridge). Die Software ist schnell nachinstalliert - mit etwas Mut, denn die Herstellerseiten sind mitunter komplett chinesisch:
Am häufigsten sind CP210x-Chips verbaut. Die Treiber sind meistens bereits im System vorhanden. Falls nicht bietet deren Hersteller SiliconLabs auf dieser Internetseite die Treiber an.
Etwas seltener findet man CH340 oder ähnliche Chips. Deren Treiber müssen meistens noch installiert werden. Der Hersteller bietet sie auf dieser Seite (falls Darstellung chinesisch: unten CH341SER.EXE)
Neuere ESP benötigen gar keine expliziten USB-UART-Chips mehr, da diese ESP32 direkt per USB angesprochen werden können.
Falls das alles nicht hilft gibt es auf esp32.net eine gute Übersicht der verwendeten Chips.
Das Board eintragen
Das zugehörige (und eben installierte) Board wird ebenso unter Tools
eingetragen. Unter Tools/Board/esp32
öffnet sich eine lange Liste:

Aus dieser Liste - je nach verwendetem ESP32 - z.B. ESP32 Dev-Module
wählen.
Damit ist alles Startbereit für den ersten Sketch!
Microcontroller “Hello World” - Blinken!!!
Für ein erstes “Hello World” nutzen wir die intern verbauten LED und Taster des ESP32-Boards: Normalerweise ist eine (oft blaue) LED auf dem Microcontrollerboard mit dem Ausgang GPIO02
verschaltet.
Wir nutzen die Arduino-IDE, um diese interne LED anzusteuern. Ein Arduino-Sketch besteht im wesentlichen aus fünf Komponenten, von denen drei durch uns konfigurierbar sind:
Nach dem Start wird eine Funktion
init()
aufgerufen, die alle nötigen Bibliotheken lädt und konfiguriert. Diese Methode wird uns nicht angezeigt und ist nicht konfigurierbar.Danach kommt ein Bereich, in dem wir eigene Variablen erzeugen können, die wir in unserem Sketch benötigen. Das werden wir später nutzen.
Darauf folgt eine
setup
-Methode, in der wir alle Konfigurationen vornehmen können, die für unser Programm erforderlich sind. Diesetup()
-Methode wird genau einmal aufgerufen.Nach der
setup()
-Methode folgt eine Dauerschleife. Die Schleife selbst sehen wir nicht, wir wissen nur, dass in ihr eine weitere Methode aufgerufen wird:Die
loop()
-Methode befindet sich in der Dauerschleife. In derloop()
-Methode befindet sich die eigentliche Programmlogik - entweder direkt, oder in Form von Funktionsaufrufen.
Grafisch lässt sich das ganze als Programm-Ablaufplan (PAP) darstellen:1

Das Programm besteht aus wenigen Zeilen Code:
Zunächst legen wir die Variable fest für den General Purpose Input Output (GPIO), an dem die LED angeschlossen ist. Häufig gibt es zwei LED: eine, die signalisiert, wenn am seriellen Port (also über USB) Daten übertragen werden. Diese liegt am GPIO1
an. Manche Boards verfügen noch über eine zweite LED, die am GPIO2
angeschlossen ist.
/* Liste der Ein- und Ausgabeelemente
Datentyp |Name | Anschlusspin | Name, Verhalten*/
const int ONBOARD_LED = 1; // GPIO01 HIGH-Aktiv
In der setup()
-Methode werden alle Operationen aufgerufen, die genau ein einziges Mal beim Starten ausgeführt werden müssen. Hier wird konfiguriert, dass es sich bei dem an ONBOARD_LED
angeschlossenen Gerät um ein Ausgabedevice handelt:
In einer zweiten Methode, die in Arduino-Sketches immer vorkommt, werden alle Operationen aufgerufen, die in einer Dauerschleife laufen sollen. Hier wird an den Ausgabepin ONBOARD_LED
abwechselnd ein HIGH
- (3,3V) und ein LOW
-(0V) Potenzial angelegt. Die LED sollte also blinken.
void loop() {
digitalWrite(ONBOARD_LED, HIGH);
delay(200);
digitalWrite(ONBOARD_LED, LOW);
delay(800);
}
Das Potenzial wird kurz auf HIGH
und lange auf LOW
gelegt - wir erwarten also ein kurzes leuchten und eine lange Pause. So leuchtet die LED auch - in diesem Fall scheint sie also “HIGH”-aktiv zu sein.
Herzlichen Glückwunsch: der erste wichtige Schritt ist gemacht. Ein digitaler Ausgangspin wurde gezielt ein- und ausgeschaltet! Da dieser Pin normalerweise für die USB-Kommunikation mit dem Computer benötigt wird - beispielsweise auch, um Debugging-Informationen am PC auszugeben, werden wir später auf andere Pins ausweichen.
Schritt zwei: Taster-Zustand einlesen
Ohne weitere Bauteile können wir uns der zweiten großen Aufgabe stellen: digitale Signale einzulesen. Dazu nutzen wir eine weitere Komponente, die auf den meisten NodeMCU-Boards mit ESP32 verbaut ist: der Boot-Button. Er ist direkt mit dem digitalen Eingang GPIO0
verbunden und wird normalerweise genutzt, um den ESP beim Start in den Programmiermodus zu setzen.
Auch wenn uns die genaue Lage der Pins noch egal sein kann: hier liegen jeweils die verknüpften Pins:

Wir nutzen diesen Button nach dem Booten anderweitig:
Bei betätigtem Button soll sich die Geschwindigkeit des Blinkens ändern. Dazu brauchen wir zunächst in der Liste der Ein- und Ausgabeelemente eine zusätzliche Zeile für den Taster:
/* Liste der Ein- und Ausgabeelemente
Datentyp |Name | Anschlusspin | Name, Verhalten*/
const int ONBOARD_LED = 1; // GPIO01 HIGH-Aktiv
const int ONBOARD_BUTTON = 0; // GPIO00, Pullup
Den so festgelegten Pin müssen wir jetzt noch als Eingang deklarieren:
Und schließlich in der Programmschliefe den Zustand des Button-Pins abfragen (mit digitalRead()
). Wenn der Eingang des Pins LOW
ist, soll die LED schnell blinken. Andernfalls soll sie langsam blinken:
void loop() {
int miliSecondsLow=0;
if (digitalRead(ONBOARD_BUTTON)==LOW){
miliSecondsLow = 200;
}else{
miliSecondsLow = 1200;
}
digitalWrite(ONBOARD_LED, HIGH);
delay(200);
digitalWrite(ONBOARD_LED, LOW);
delay(miliSecondsLow);
}
Nach dem Hochladen kann man erkennen, dass die LED normalerweise langsam blinkt (der Pins also regulär HIGH
ist) und nur bei Betätigung des Buttons langsam wird (also LOW
). Dieses Verhalten liegt an einem intern verbauten “Pull-Up-Widerstand”. Dazu später mehr, wenn wir uns die Belegung von externen Tastern genauer anschauen.
Wo befinden sich die versteckten Programmbestandteile?
Für alle, die es genau wissen wollen (alle anderen können diesen Absatz getrost überspringen):
Eingangs wurde erwähnt, dass es über die beiden oben genannten Funktionen setup()
und loop()
hinaus noch weiteren Programmcode gibt, den die Arduino-IDE aber vor uns versteckt. Gibt es eine Möglichkeit danach zu forschen? Gibt es beispielsweise eine main()
-Methode, wie sie die Java und C/C++ Programmierer kennen?
Ja, die gibt es, man kann sie tief im Arduino-Ordner aufspüren, bei den 1.8.x-Versionen der Arduino-IDE in Windows liegt sie beispielsweise hier:
In dieser main.cpp
-Datei befindet sich die main()
-Methode des C++-Programms. Und darin befinden sich die eingangs erwähnten Methodenaufrufe (siehe Programmablaufplan oben) init()
, setup()
und loop()
, sowie die Dauerschleife (hier über for (;;) {
…}` umgesetzt):
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Für den ESP ist dieser Aufruf nicht ganz so einfach aufzuspüren - und das umgebende Programm etwas aufwändiger. Der Grundaufbau ist aber identisch: setup()
wird einmal aufgerufen, loop()
immer wieder.
Wie geht es weiter?
Weiter geht es im zweiten Teil, in dem digitale Ausgänge genutzt und externe LED angesteuert werden.
Weitere Literatur und Quellen
- Primärquelle ist immer das Datenblatt und die API-Dokumentation von Espressif (dem Chiphersteller)
Quellen und offene Ressourcen (OER)
Die Ursprungstexte (als Markdown), Grafiken und zugrunde liegende Diagrammquelltexte finden sich (soweit möglich in weiterbearbeitbarer Form) in folgendem git-Repository:
https://gitlab.com/oer-informatik/mcu/arduino-esp.
Sofern nicht explizit anderweitig angegeben sind sie zur Nutzung als Open Education Resource (OER) unter Namensnennung (H. Stein, oer-informatik.de) freigegeben gemäß der Creative Commons Namensnennung 4.0 International Lizenz (CC BY 4.0).
Grafik wurde erstellt mit dem PAP-Designer von Friedrich Folkmann: http://friedrich-folkmann.de/papdesigner/Hauptseite.html↩