Das Board Nano ESP32 stellt neben dem Mikrocontroller auch ein ESP32-Modul bereit. Damit können Verbindungen zu WLAN-Netzwerken und anderen Bluetooth-Geräten aufgebaut werden.
Pinbelegung

Alle mit D bezeichneten Pins können als Ein- und Ausgabepins (⇒digitalRead/digitalwrite) verwendet werden, alle mit A beschrifteten Pins können mit ⇒analogRead/analogWrite eingesetzt werden.
Die Pins A4 (SCL) und A5 (SDA) bedienen den I²C-Bus.
Alle analogen und alle digitalen Pins können mit der ⇒Pulsweitenmodulation angesprochen werden.
Board installieren:

- Icon für den Boardverwalter anklicken oder Werkzeuge-> Board -> Boardverwalter
- nach dem Board Arduino ESP32 suchen
- Board installieren
Board auswählen

Bluetooth BLE
Das Programm
Zunächst musst du die Bibliothek ArduinoBLE installieren:

Das Programm schaltet die Farbe blau der internen RGB-LED.
Besonderheit: LOW -> einschalten, HIGH -> ausschalten
1 -> einschalten, 0 -> ausschalten:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include “ArduinoBLE.h” /* eindeutige UUID bestimmen: https://www.guidgenerator.com/online-guid-generator.aspx https://www.uuidgenerator.net/ BLERead | BLEWrite | BLENotify -> schreiben, lesen, Info */ // Name BLE-Service BLEService LEDSchalten(“19b10000-e8f2-537e-4f6c-d104768a1214”); BLEUnsignedCharCharacteristic Auswahl(“19b10000-e8f2-537e-4f6c-d104768a1214”, BLERead | BLEWrite | BLENotify); void setup() { Serial.begin(9600); // pinMode festlegen pinMode(LED_BLUE, OUTPUT); // BLE starten if (!BLE.begin()) Serial.println(“Bluetooth-Modul konnte nicht gestartet werden!”); else Serial.println(“Bluetooth-Modul erfolgreich gestartet!”); // Name festlegen (wird in der App angezeigt) und den Service (LEDSchalten) zuweisen BLE.setLocalName(“LED schalten”); BLE.setAdvertisedService(LEDSchalten); // Auswahl als Platzhalter für den in der App gewählten Wert LEDSchalten.addCharacteristic(Auswahl); // Service LEDSchalten hinzufügen BLE.addService(LEDSchalten); // Startwert für die Kommunikation schreiben Auswahl.writeValue(0); // Zuweisung starten BLE.advertise(); } void loop() { // auf die Verbindung zu Geräten warten BLEDevice Verbindung = BLE.central(); // wenn der ESP32 mit einem Gerät verbunden ist … if (Verbindung) { Serial.println(“Verbunden … ”); // solange der Controller mit einem Gerät verbunden ist … while (Verbindung.connected()) { if (Auswahl.written()) { // LED einschalten if (Auswahl.value() == ‘1’) { Serial.print(char(Auswahl.value())); Serial.println(“ -> LED ein”); digitalWrite(LED_BLUE, LOW); } // LED ausschalten if (Auswahl.value() == ‘0’) { Serial.print(char(Auswahl.value())); Serial.println(F(“ -> LED aus”)); digitalWrite(LED_BLUE, HIGH); } } } } } |
Smartphone-Apps
BluetoothLE (iOS)
![]() | ![]() | ![]() | ![]() |
BLE Terminal (Android: Innovators Den)
![]() | ![]() | ![]() |
LightBlue (iOS Android)
![]() | ![]() | ![]() |
| Android zeigt als Name LED schalten | ||
![]() | ![]() | ![]() |
BLE Terminal (iOS)
![]() | ![]() |
Zeit mit der Bibliothek time.h anzeigen
ESP32-Mikrocontroller können mit der Standardbibliothek Datum und Zeit anzeigen.

Beispiel: ⇒Anzeige von Datum und Zeit auf einem OLED-Display
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include “WiFi.h” #include “time.h” char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; // NTP-Server aus dem Pool #define Zeitserver “de.pool.ntp.org” /* Liste der Zeitzonen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv Zeitzone CET = Central European Time ‑1 -> 1 Stunde zurück CEST = Central European Summer Time von M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr */ #define Zeitzone “CET-1CEST,M3.5.0/02,M10.5.0/03” // time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr time_t aktuelleZeit; /* Struktur tm tm_hour -> Stunde: 0 bis 23 tm_min -> Minuten: 0 bis 59 tm_sec -> Sekunden 0 bis 59 tm_mday -> Tag 1 bis 31 tm_wday -> Wochentag (0 = Sonntag, 6 = Samstag) tm_mon -> Monat: 0 (Januar) bis 11 (Dezember) tm_year -> Jahre seit 1900 tm_yday -> vergangene Tage seit 1. Januar des Jahres tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time) */ tm Zeit; WiFiServer Server(80); WiFiClient Client; void setup() { // Zeitzone: Parameter für die zu ermittelnde Zeit configTzTime(Zeitzone, Zeitserver); Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); // WiFi starten WiFi.begin(Router, Passwort); Serial.println(“————————”); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(Router); Serial.print(“IP über DHCP: ”); Serial.println(WiFi.localIP()); } void loop() { // aktuelle Zeit holen time(&aktuelleZeit); // localtime_r -> Zeit in die lokale Zeitzone setzen localtime_r(&aktuelleZeit, &Zeit); Serial.println(“————————”); // es kann bis zu 30 Sekunden dauern // bis die Zeit ermittelt wird // Name des Wochentages 0–6 switch (Zeit.tm_wday) { case 0: Serial.print(“Sonntag”); break; case 1: Serial.print(“Montag”); break; case 2: Serial.print(“Dienstag”); break; case 3: Serial.print(“Mittwoch”); break; case 4: Serial.print(“Donnerstag”); break; case 5: Serial.print(“Freitag”); break; case 6: Serial.print(“Samstag”); break; } Serial.print(“,”); if (Zeit.tm_mday < 10) Serial.print(“0”); Serial.print(Zeit.tm_mday); Serial.print(“.”); // Monat: führende 0 ergänzen // Zählung beginnt mit 0 -> +1 if ((Zeit.tm_mon + 1) < 10) Serial.print(“0”); Serial.print(Zeit.tm_mon + 1); Serial.print(“.”); // Anzahl Jahre seit 1900 Serial.print(Zeit.tm_year + 1900); Serial.print(“ ”); // Stunde: wenn Stunde < 10 -> 0 davor setzen if (Zeit.tm_hour < 10) Serial.print(“0”); Serial.print(Zeit.tm_hour); Serial.print(“:”); // Minuten if (Zeit.tm_min < 10) Serial.print(“0”); Serial.print(Zeit.tm_min); Serial.print(“:”); // Sekunden if (Zeit.tm_sec < 10) Serial.print(“0”); Serial.print(Zeit.tm_sec); Serial.println(); Serial.println(“Tage seit dem 1.1. ” + String(Zeit.tm_yday)); // Normalzeit/Sommerzeit if(Zeit.tm_isdst > 0) Serial.println(“MESZ = Mitteleuropäische Sommerzeit”); else Serial.println(“MEZ = Mitteleuropäische Zeit”); delay(5000); } |
Webserver
Beispiel: Das Programm zeigt im Browser 6 Zufallszahlen an.
Im Seriellen Monitor wird die IP des Nano ESP32 angezeigt.

Diese Adresse musst du in einem Browser deiner Wahl eingeben

Client-Methode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include “WiFi.h” // SSID und Passwort des Routers char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; WiFiServer Server(80); WiFiClient Client; // Minimum und Maximum der Zufallszahlen int Minimum = 1; int Maximum = 49; void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); // WiFi starten WiFi.begin(Router, Passwort); // Verbindung herstellen while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Server.begin(); // SSID des Routers anzeigen Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(WiFi.SSID()); // IP anzeigen Serial.println(WiFi.localIP()); // Zufallsgenerator mit dem Signal an A0 starten randomSeed(analogRead(A0)); } void loop() { Client = Server.available(); if (Client) { // Seite aufbauen wenn SeiteAufbauen true ist boolean SeiteAufbauen = true; // solange der Client verbunden ist … while (Client.connected()) { if (Client.available()) { // Anforderung vom Clienten lesen … char Zeichen = Client.read(); // return (\n) gesendet if (Zeichen == ‘\n’) { // wenn SeiteAufbauen den Wert true hat if (SeiteAufbauen) { /* HTML-Seite aufbauen die folgenden Anweisungen müssen mit print oder println gesendet werden println “verschönert” den Quelltext (erzeugt einen Zeilenumbruch im Quelltext) */ // HTML-Seite aufbauen Client.println(“HTTP/1.1 200 OK”); Client.println(“Content-type:text/html”); // Leerzeile zwingend erforderlich Client.println(); Client.println(“<!doctype html>”); Client.println(“<html>”); Client.println(“<body>”); // alle 60 Sekunden aktualisieren mit meta-Tag Client.println(“<meta http-equiv=\“refresh\” content=\“60\”>”); // <h2> Überschrift H2 Client.println(“<h2>Zufallszahlen</h2>”); // <hr> horizontale Linie Client.println(“<hr>”); // Zufallszahlen anzeigen for (int i = 0; i < 7; i++ ) { int Zahl = random(Minimum, Maximum); Client.println(Zahl); Client.println(“ ”); } Client.print(“<hr>”); // IPs anzeigen Client.print(“Eigene IP (Server): ”); Client.print(Client.remoteIP()); // <br> break = neue Zeile Client.print(“<br>IP Adresse Klient DHCP ”); Client.print(WiFi.localIP()); // Seite schließen Client.println(“</body>”); Client.println(“</html>”); // HTTP-Antwort endet mit neuer Zeile Client.println(); // Seite vollständig geladen -> loop verlassen break; } // wenn new line (\n) gesendet wurde -> Seite aufbauen if (Zeichen == ‘\n’) SeiteAufbauen = true; else if (Zeichen != ‘\r’) SeiteAufbauen = false; delay(1); Client.stop(); } } } } } |
Server.on-Methode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | #include “WiFi.h” #include “WebServer.h” // SSID und Passwort des Routers char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; WebServer Server(80); // Minimum und Maximum der Zufallszahlen int Minimum = 1; int Maximum = 49; // statischeIP = false -> IP-Adresse über DHCP vergeben // statischeIP = true -> statische IP festlegen bool statischeIP = false; // ip und gateway müssen an das lokale Netz angepasst werden IPAddress ip(192, 168, 1, 100); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); // WiFi starten WiFi.begin(Router, Passwort); // statische IP vergeben if (statischeIP) { WiFi.config(ip, gateway, subnet); Serial.print(“Verbunden mit ”); Serial.println(Router); // IP anzeigen Serial.print(“Statische IP: ”); } // IP über DHCP ermitteln else { while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(Router); Serial.print(“IP über DHCP: ”); } // IP anzeigen Serial.println(WiFi.localIP()); // Zufallsgenerator mit dem Signal an A0 starten randomSeed(analogRead(A0)); Server.begin(); Server.on(“/”, SeiteBauen); } void loop() { Server.handleClient(); } void SeiteBauen() { // Seite zusammenbauen // Kopf der HTML-Seite: aktualisierung alle 60 Sekunden // kann angepasst werden String Nachricht = “<head><meta http-equiv=\“refresh\” content=\“60\”></head>”; Nachricht += “<h1>Zufallszahlen</h1>”; Nachricht += “<hr>”; // Zufallszahlen anzeigen for (int i = 0; i < 7; i++) { int Zahl = random(Minimum, Maximum); Nachricht += String(Zahl) + ” “; } Nachricht += “<hr>”; // Nachricht senden -> Seite anzeigen Server.send(200, “text/html”, Nachricht); } |
RGB-LED
Auf dem Board befindet sich eine RGB-LED. Sie wird mit den festen Namen LED_BLUE, LED_GREEN und LED_RED angesprochen.
Eine Besonderheit ist, dass LOW die jeweilige Farbe einschaltet, HIGH schaltet sie wieder aus.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | void setup() { pinMode(LED_BLUE, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_RED, OUTPUT); } void loop() { digitalWrite(LED_BLUE, LOW); delay(1000); digitalWrite(LED_BLUE, HIGH); delay(1000); digitalWrite(LED_RED, LOW); delay(1000); digitalWrite(LED_RED, HIGH); delay(1000); digitalWrite(LED_GREEN, LOW); delay(1000); digitalWrite(LED_GREEN, HIGH); delay(1000); } |
Bootloader zurücksetzen

GND und B1 mit Kabel überbrücken
Kontrollieren, ob das richtige Board ausgewählt wurde und als Programmer Esptool gesetzt ist:

Sketch -> mit Programmer hochladen

Reset-Knopf drücken
Fehlermeldungen (Linux)
No DFU capable USB device available
Die Berechtigungen für das udev-Subsystem müssen angepasst werden. Ich habe dazu dieses 🔗Script (abgerufen am 04.12.24) verwendet. Außerdem muss das Programm dfu-util installiert werden.
Failed to connect to ESP32: No serial data received
No module named ’serial’
Die Python-Erweiterung python-pyserial muss installiert werden.
Letzte Aktualisierung:














