Wemos D1 R32 en formato UNO

FunduinoÚltima actualización el

Ein ESP32 in der Bauform des Arduino UNO – Pinbelegung, WiFi und Bluetooth

Das Wemos D1 R32 sieht aus wie ein Arduino UNO, ist aber ein ESP32: deutlich schneller, mit mehr Speicher und mit WiFi und Bluetooth LE an Bord. Shields im UNO-Format passen mechanisch darauf.

Diese Anleitung ist eine Übersicht über das Board: Du richtest es in der Arduino IDE ein und gehst danach seine Schnittstellen durch – I2C, SPI, digitale und analoge Pins, die Touch-Eingänge sowie WiFi und Bluetooth. Zu jedem Bereich gehört ein kleines Beispielprogramm zum Ausprobieren.

Schwarze Platine im Arduino-UNO-Format mit ESP32-WROOM-32-Modul
Das Wemos D1 R32 im UNO-Format

Was das Wemos D1 R32 kann

Auf dem Wemos D1 R32 sitzt ein ESP32-WROOM-32 von Espressif, untergebracht auf einer Platine im Format des Arduino UNO. Shields für den UNO passen damit mechanisch auf das Board.

Das Board bietet:

  • digitale Ein- und Ausgänge
  • analoge Eingänge mit 12 Bit Auflösung
  • berührungsempfindliche Touch-Pins
  • die Bussysteme I2C und SPI
  • WiFi
  • Bluetooth LE (BLE)

Viele Pins sind mehrfach belegt: Die I2C-, SPI- und Touch-Pins lassen sich auch als einfache digitale Pins verwenden.

Das UNO-Format bedeutet nicht, dass der Pin mit der Aufschrift „D13“ auch GPIO 13 ist. Die Aufdrucke folgen der UNO-Nummerierung, im Sketch sprichst du dagegen die GPIO-Nummern des ESP32 an. Richte dich daher nach den Pinbelegungsgrafiken in den nächsten Schritten.

Schwarze Platine im Arduino-UNO-Format mit ESP32-WROOM-32-Modul
Das Wemos D1 R32 im UNO-Format

Board in der Arduino IDE installieren

Damit die Arduino IDE den ESP32 kennt, trägst du unter Datei → Einstellungen eine zusätzliche Boardverwalter-URL ein:

https://espressif.github.io/arduino-esp32/package_esp32_index.json

Danach gehst du so vor:

  • Das Symbol für den Boardverwalter anklicken oder Werkzeuge → Board → Boardverwalter öffnen
  • Nach esp32 suchen
  • Das Paket „esp32 by Espressif Systems“ installieren

In älteren Anleitungen steht noch die Adresse dl.espressif.com/dl/package_esp32_index.json. Sie funktioniert nicht mehr zuverlässig – nutze die oben genannte Adresse.

Einstellungsdialog der Arduino IDE mit dem Feld für Boardverwalter-URLs
Die zusätzliche Boardverwalter-URL wird in den Einstellungen eingetragen
Boardverwalter der Arduino IDE mit dem ESP32-Paket
Im Boardverwalter nach ESP32 suchen und installieren
1 / 2

Board und Port auswählen

Wird das Wemos D1 R32 nicht automatisch erkannt, klicke in der Auswahlliste oben auf „Wähle ein anderes Board und einen anderen Port“ und suche nach esp32-wroom.

Den passenden Port wählst du daneben aus. Je nach Betriebssystem heißt er anders – unter Windows zum Beispiel COM3, unter macOS und Linux beginnt er mit /dev/.

Board-Auswahldialog der Arduino IDE
Über „Wähle ein anderes Board und einen anderen Port“ lässt sich das Board manuell einstellen
Board-Auswahldialog mit dem Suchbegriff esp32-wroom
Suche nach esp32-wroom und wähle den passenden Port aus
1 / 2

I2C-Pins

Der I2C-Bus (Inter-Integrated Circuit) wurde ursprünglich von Philips entwickelt, damit ein Controller – hier das Wemos D1 R32 – mit mehreren Peripheriegeräten über nur zwei Leitungen kommunizieren kann. Die beiden Anschlüsse heißen SDA (Daten) und SCL (Takt).

  • GPIO 21 → SDA
  • GPIO 22 → SCL

Diese Bauteile werden über I2C angesteuert:

Pinbelegungsgrafik des Wemos D1 R32 mit hervorgehobenen I2C-Pins
Lage der I2C-Pins SDA und SCL

SPI-Pins

Auch der SPI-Bus (Serial Peripheral Interface) verbindet den Controller mit Peripheriegeräten. Er braucht zwei Datenleitungen und zwei Steuerleitungen:

  • COPI (Controller Out, Peripheral In) – Daten vom Controller zum Peripheriegerät
  • CIPO (Controller In, Peripheral Out) – Daten vom Peripheriegerät zum Controller
  • CS (Chip Select) – der Controller wählt das Gerät aus, mit dem er sprechen will
  • SCK (Serial Clock) – die vom Controller erzeugte Taktfrequenz

Am Wemos D1 R32 liegen sie auf diesen Pins:

  • GPIO 23 → COPI/SDO
  • GPIO 19 → CIPO/SDI
  • GPIO 18 → SCK
  • GPIO 5 → CS

In älterer Literatur und in vielen Bibliotheken heißen diese Leitungen noch MOSI (Master Out Slave In, heute COPI) und MISO (Master In Slave Out, heute CIPO). Mehrere Initiativen arbeiten an der Ablösung der alten Bezeichnungen – unter anderem SparkFun, die OSHWA und die Arduino-Dokumentation.

Pinbelegungsgrafik des Wemos D1 R32 mit hervorgehobenen SPI-Pins
Lage der SPI-Pins

Digitale Pins

Als digitale Ein- und Ausgänge stehen dir diese GPIOs zur Verfügung: 2, 4, 5, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32 und 33.

Die GPIOs 34, 35, 36 und 39 sind ebenfalls digitale Pins, lassen sich aber ausschließlich als Eingang (INPUT) verwenden – als Ausgang funktionieren sie nicht.

Als Beispiel schaltest du eine LED mit einem Taster: Die LED leuchtet, solange der Taster gedrückt wird.

Die GPIOs 15, 32 und 33 sind auf dem Board nicht auf die üblichen Buchsenleisten geführt. Um sie sicher zu nutzen, muss dort eine Stiftleiste angelötet werden.

Pinbelegungsgrafik des Wemos D1 R32 mit hervorgehobenen digitalen Pins
Lage der digitalen Pins
Steckplatine mit LED und Taster am Wemos D1 R32
Aufbau: LED an Pin 13, Taster an Pin 12
1 / 2
Sketch: LED mit einem Taster schalten
int LED = 13;
int Taster = 12;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(Taster, INPUT_PULLUP);
}

void loop()
{
  // Durch INPUT_PULLUP liegt der Pin im Ruhezustand auf HIGH.
  // Gedrueckt wird er mit GND verbunden und damit LOW.
  if (digitalRead(Taster) == LOW) digitalWrite(LED, HIGH);
  else digitalWrite(LED, LOW);
}

Touch-Pins

Der menschliche Körper und leitfähige Gegenstände können elektrische Ladung speichern. Der ESP32 nutzt das aus: Berührst du einen der Touch-Pins, verändert sich sein Messwert deutlich – ganz ohne zusätzliches Bauteil.

Verfügbare Touch-Pins (in Klammern die Bezeichnung im Datenblatt):

  • GPIO 4 (T0)
  • GPIO 12 (T5)
  • GPIO 14 (T6)
  • GPIO 15 (T3)
  • GPIO 27 (T7)
  • GPIO 32 (T9)
  • GPIO 33 (T8)

Zum Ausprobieren schließt du ein einzelnes Kabel an GPIO 14 (T6) an und berührst das offene Kabelende mit dem Finger. Wenn es nicht auf Anhieb funktioniert, feuchte den Finger ein wenig an.

Auch hier gilt: GPIO 15, 32 und 33 sind nur mit angelöteter Stiftleiste sicher nutzbar. Der Schwellenwert 25 im Sketch ist ein Erfahrungswert – lies dir die Zahlen erst im Seriellen Monitor an und passe ihn an deinen Aufbau an.

Pinbelegungsgrafik des Wemos D1 R32 mit hervorgehobenen Touch-Pins
Lage der Touch-Pins
Foto des Wemos D1 R32 mit einem angeschlossenen Kabel am Touch-Pin
Ein einzelnes Kabel am Touch-Pin 14 genügt als Sensor
Serieller Monitor mit Touch-Messwerten
Ausgabe im Seriellen Monitor: der Messwert fällt deutlich, sobald das Kabelende berührt wird
1 / 3
Sketch: Touch-Pin auslesen
void setup()
{
  // Serielle Kommunikation starten
  Serial.begin(9600);
  delay(1000);
}

void loop()
{
  // Messwert nur einmal pro Durchlauf lesen und zwischenspeichern
  int Messwert = touchRead(14);

  Serial.print("Wert: ");
  Serial.print(Messwert);

  // Kleiner Wert -> Pin wurde beruehrt
  if (Messwert < 25) Serial.println(" -> Pin beruehrt");

  // Bei groesseren Werten wurde der Pin nicht beruehrt
  else Serial.println(" -> Pin nicht beruehrt");

  delay(1000);
}

Analoge Pins

Der ESP32 hat zwei Analog-Digital-Wandler (ADC1 und ADC2) mit je 12 Bit Auflösung. Ein Messwert liegt daher zwischen 0 und 4095 – beim Arduino UNO sind es nur 0 bis 1023.

Auf dem Wemos D1 R32 sind die analogen Eingänge so verteilt:

  • ADC1: GPIO 32, 33, 34, 35, 36 und 39
  • ADC2: unter anderem GPIO 2, 4, 12, 13, 14, 25, 26 und 27

Als Beispiel liest du ein Potentiometer an GPIO 35 aus. Die Ausgabe lässt sich im Seriellen Monitor verfolgen – noch anschaulicher wird sie im Seriellen Plotter, der den Wert als Kurve zeichnet.

Sobald WiFi aktiv ist, wird ADC2 vom Funkmodul belegt. Analoge Messungen sind dann nur noch über ADC1 möglich, also über GPIO 32 bis 39. Plane deine Anschlüsse von Anfang an so, wenn dein Projekt später ins WLAN soll.

Pinbelegungsgrafik des Wemos D1 R32 mit hervorgehobenen analogen Pins
Lage der analogen Eingänge
Steckplatine mit Potentiometer am Wemos D1 R32
Aufbau: Potentiometer am analogen Eingang GPIO 35
Serieller Plotter mit ansteigender und abfallender Kurve
Ausgabe im Seriellen Plotter beim Drehen des Potentiometers
1 / 3
Sketch: Potentiometer auslesen
// Potentiometer an GPIO 35
int Potentiometer = 35;

// Variable fuer den gelesenen Wert
int GelesenerWert = 0;

void setup()
{
  Serial.begin(9600);
  delay(1000);
}

void loop()
{
  // Analogen Wert lesen (0 bis 4095)
  GelesenerWert = analogRead(Potentiometer);
  Serial.println(GelesenerWert);
  delay(500);
}

WiFi: einen kleinen Webserver bauen

Der ESP32 kann sich nicht nur mit einem WLAN verbinden, sondern darin auch selbst als Server auftreten. Das folgende Programm liefert eine kleine Webseite mit sechs Zufallszahlen aus, die sich jede Minute selbst aktualisiert.

Trage vor dem Hochladen SSID und Passwort deines Routers in den Sketch ein. Nach dem Start zeigt der Serielle Monitor die IP-Adresse an, die das Board per DHCP bekommen hat. Diese Adresse gibst du im Browser ein.

Der Router vergibt die Adresse per DHCP – sie kann sich nach einem Neustart ändern. Soll das Board dauerhaft unter derselben Adresse erreichbar sein, vergib im Router eine feste IP für seine MAC-Adresse.

Serieller Monitor mit der IP-Adresse des Wemos D1 R32
Im Seriellen Monitor erscheint die per DHCP zugewiesene IP-Adresse
Browserfenster mit der Überschrift Zufallszahlen und einer Reihe von Zahlen
Die vom Board ausgelieferte Seite mit den Zufallszahlen im Browser
1 / 2
Sketch: Webserver mit Zufallszahlen
#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);
  delay(1000);

  // 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 des Boards anzeigen - diese Adresse gibst du im Browser ein
  Serial.println(WiFi.localIP());

  // Zufallsgenerator mit dem Rauschen an einem offenen Analogpin starten
  randomSeed(analogRead(35));
}

void loop()
{
  Client = Server.available();
  if (!Client) return;

  // Solange der Client verbunden ist ...
  while (Client.connected())
  {
    if (!Client.available()) continue;

    // Anforderung vom Client lesen ...
    char Zeichen = Client.read();

    // ... und erst nach dem Zeilenumbruch antworten
    if (Zeichen != '\n') continue;

    /*
      HTML-Seite aufbauen.
      Die folgenden Anweisungen muessen mit print oder println
      gesendet werden. println "verschoenert" den Quelltext,
      es erzeugt einen Zeilenumbruch im Quelltext.
    */
    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
    Client.println("<meta http-equiv=\"refresh\" content=\"60\">");

    // Ueberschrift und horizontale Linie
    Client.println("<h2>Zufallszahlen</h2>");
    Client.println("<hr>");

    // Sechs Zufallszahlen anzeigen.
    // random() liefert Werte bis Maximum - 1, deshalb Maximum + 1.
    for (int i = 0; i < 6; i++)
    {
      int Zahl = random(Minimum, Maximum + 1);
      Client.print(Zahl);
      Client.print(" ");
    }
    Client.println("<hr>");

    // IP-Adressen anzeigen
    Client.print("IP dieses Boards (Server): ");
    Client.print(WiFi.localIP());
    Client.print("<br>IP des aufrufenden Geraets: ");
    Client.print(Client.remoteIP());

    // Seite schliessen
    Client.println("</body>");
    Client.println("</html>");

    // HTTP-Antwort endet mit einer neuen Zeile
    Client.println();
    break;
  }

  // Verbindung beenden
  delay(1);
  Client.stop();
}

Bluetooth LE: die interne LED per App schalten

Installiere zuerst die Bibliothek ArduinoBLE über Sketch → Bibliothek einbinden → Bibliotheken verwalten oder über das entsprechende Symbol in der linken Leiste.

Das Programm schaltet die interne LED des Boards: Eine 1 schaltet sie ein, eine 0 wieder aus. Geschrieben wird dieser Wert von einer App auf dem Smartphone.

Dafür eignet sich die kostenlose App LightBlue, die es für iOS und Android gibt. Verbinde dich dort mit dem Gerät „LED schalten“ und schreibe den Wert 1 oder 0 in die Characteristic.

Service und Characteristic brauchen jeweils eine eigene UUID. Nutzt du für beide dieselbe, verhalten sich manche Apps unvorhersehbar. Eigene UUIDs erzeugst du kostenlos mit einem Online-Generator wie uuidgenerator.net.

Bibliotheksverwalter der Arduino IDE mit der ArduinoBLE-Bibliothek
Die Bibliothek „ArduinoBLE“ im Bibliotheksverwalter
Sketch: interne LED per Bluetooth LE schalten
#include "ArduinoBLE.h"

/*
  Eindeutige UUIDs bestimmen:
  https://www.guidgenerator.com/online-guid-generator.aspx
  https://www.uuidgenerator.net/
  BLERead | BLEWrite | BLENotify -> lesen, schreiben, Info
  Service und Characteristic brauchen jeweils eine eigene UUID.
*/

// Name des BLE-Service
BLEService LEDSchalten("19b10000-e8f2-537e-4f6c-d104768a1214");

BLEUnsignedCharCharacteristic Auswahl("19b10001-e8f2-537e-4f6c-d104768a1214", BLERead | BLEWrite | BLENotify);

// interne LED
int LED = 2;

void setup()
{
  Serial.begin(9600);

  // pinMode festlegen
  pinMode(LED, 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 zuweisen
  BLE.setLocalName("LED schalten");
  BLE.setAdvertisedService(LEDSchalten);

  // Auswahl als Platzhalter fuer den in der App gewaehlten Wert
  LEDSchalten.addCharacteristic(Auswahl);

  // Service LEDSchalten hinzufuegen
  BLE.addService(LEDSchalten);

  // Startwert fuer die Kommunikation schreiben
  Auswahl.writeValue(0);

  // Sichtbar werden
  BLE.advertise();
}

void loop()
{
  // Auf die Verbindung zu Geraeten warten
  BLEDevice Verbindung = BLE.central();

  // Wenn der ESP32 mit einem Geraet verbunden ist ...
  if (Verbindung)
  {
    Serial.println("Verbunden ... ");

    // Solange der Controller mit einem Geraet verbunden ist ...
    while (Verbindung.connected())
    {
      if (Auswahl.written())
      {
        // LED einschalten
        if (Auswahl.value() == 1)
        {
          Serial.print(Auswahl.value());
          Serial.println(" -> LED ein");
          digitalWrite(LED, HIGH);
        }

        // LED ausschalten
        if (Auswahl.value() == 0)
        {
          Serial.print(Auswahl.value());
          Serial.println(" -> LED aus");
          digitalWrite(LED, LOW);
        }
      }
    }
  }
}
Calificar la guía

Comentarios

Haz una pregunta o comparte tu experiencia

Schreib uns, wenn etwas nicht funktioniert. Nenne dabei dein Board und die Fehlermeldung.

Revisamos cada comentario antes de publicarlo. Tu dirección de correo electrónico permanece con nosotros.