Der Wireless-Tag WT32-ETH01 ist ein Mikrocontroller-Board mit einem Espressif Systems ESP32-WROOM-32 SoC und Microchip LAN8720A Ethernet-PHY. Zusammen mit WLAN, Bluetooth und weiteren I/O-Schnittstellen des ESP32 ergibt sich ein sehr kostengünstiges und flexibles Board für Netzwerkanwendungen.
Der WT32-ETH01 lässt sich mit dem Arduino Framework frei programmieren, um individuelle Funktionsweisen je nach Anforderung umsetzen zu können. Auf dieser Seite finden Sie alle notwendigen Informationen zur Programmierung des Boards mit Ethernet.
Hardware
Das ESP32-WROOM-32 SoC-Modul (der Eigenbau von Wireless-Tag heißt WT32-S1) beinhaltet den Espressif ESP32-D0WDQ6 Mikrocontroller. Der Mikrocontroller enthält neben vielen weiteren Peripherie-Schnittstellen auch einen 10/100 MBit/s Ethernet Media Access Controller (oft als EMAC bezeichnet), der konform mit dem Standard IEEE-802.3 von 2008 ist.
An den EMAC kann über das Reduced media-independent interface (RMII) und das Serial Management Interface (SMI) ein Ethernet-PHY (physical layer) angebunden werden, der dann den Anschluss eines Ethernet LAN-Ports mit RJ45 ermöglicht. Beim WT32-ETH01 wird der Microchip LAN8720A als Ethernet-PHY verwendet. MAC und PHY erhalten beide über einen externen 50 MHz Quarzoszillator ihr Referenz-Taktsignal.
Software
Entwicklungsumgebung
Um den WT32-ETH01 mit dem Arduino Framework programmieren können, muss zunächst die Entwicklungsumgebung eingerichtet werden.
Als erstes wird die Arduino IDE (integrated development environment) installiert. Sie beinhaltet einen Texteditor, Bibliothek-Manager und Compiler.
Als nächstes muss der ESP32 Arduino Core in der IDE heruntergeladen werden. Dazu unter „Datei“ ➔ „Einstellungen…“ ➔ „Zusätzliche Boardverwalter-URLs“ den Eintrag
https://espressif.github.io/arduino-esp32/package_esp32_index.json
hinzufügen (ein Eintrag pro Zeile). Anschließend in der linken Menüleiste die „Board-Verwaltung“ öffnen und nach „ESP32“ suchen. Installieren Sie „esp32 von Espressif Systems“.
Schlussendlich muss der WT32-ETH01 unter „Werkzeuge“ ➔ „Board“ ➔ „esp32“ ➔ „WT32-ETH01 Ethernet Module“ ausgewählt werden.
Beispielcode Ethernet
Der ESP32 Arduino Core enthält bereits eine Bibliothek zur Ansteuerung von Ethernet (ETH.h). Wichtig ist der Bibliothek die korrekte Hardwaredefinition des Ethernet-PHYs mitzuteilen wenn ETH.begin() aufgerufen wird.
Soll eine statische IP-Adresse verwendet werden, wird dies mit der Funktion ETH.config() eingestellt. Soll DHCP verwendet werden, kann die Funktion ohne Parameter aufgerufen werden oder komplett gelöscht werden. Die Funktion darf erst aufgerufen werden, wenn Ethernet gestartet wurde.
Eine Besonderheit bei Ethernet ist die Funktion ETH.setHostname()um den Hostname festzulegen. Diese darf ebenfalls erst aufgerufen werden, wenn Ethernet gestartet wurde, muss aber ausgeführt werden, bevor Ethernet verbunden ist! Daher werden Events in einer Callback-Funktion der Klasse „Network“ verwendet, um den korrekten Ablauf beizubehalten.
Eine Reihe von Funktionen ermöglicht das Auslesen von Ethernet-Informationen und Reagieren auf verschiedene Zustände. Im folgenden Beispielcode werden diese vorgeführt.
/* Libraries */
#include <ETH.h> //https://github.com/espressif/arduino-esp32
/* Ethernet hardware configuration */
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#define ETH_PHY_ADDR 1
#define ETH_PHY_POWER 16
#define ETH_PHY_MDC 23
#define ETH_PHY_MDIO 18
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
#define ETH_RMII_TX_EN 21
#define ETH_RMII_TX0 19
#define ETH_RMII_TX1 22
#define ETH_RMII_RX_ER 13
#define ETH_RMII_RX0 25
#define ETH_RMII_RX1 26
#define ETH_RMII_CRS_DV 27
/* Ethernet settings */
const char* ethernetHostname = "WT32-ETH01";
IPAddress ethernetStaticLocalIp(192, 168, 178, 10);
IPAddress ethernetStaticGateway(192, 168, 178, 1);
IPAddress ethernetStaticSubnet(255, 255, 0, 0);
IPAddress ethernetStaticPrimaryDns(8, 8, 8, 8); //DNS 1 optional
IPAddress ethernetStaticSecondaryDns(8, 8, 4, 4); //DNS 2 optional
/* Variables */
static bool ethernetConnected = false;
void setup() {
/* Initialize UART */
Serial.begin(115200);
/* Initialize Ethernet */
Network.onEvent(onNetworkEvent);
ETH.begin(ETH_PHY_TYPE,\
ETH_PHY_ADDR,\
ETH_PHY_MDC,\
ETH_PHY_MDIO,\
ETH_PHY_POWER,\
ETH_CLK_MODE);
//ETH.config(); //use DHCP
ETH.config(ethernetStaticLocalIp,\
ethernetStaticGateway,\
ethernetStaticSubnet,\
ethernetStaticPrimaryDns,\
ethernetStaticSecondaryDns); //use static IP
}
void loop() {
/* Print Ethernet information */
Serial.println("- - -");
Serial.print("Ethernet MAC: ");
Serial.println(ETH.macAddress());
Serial.print("Ethernet ");
Serial.println(ETH.connected() ? "connected" : "not connected");
Serial.print("Ethernet ");
Serial.println(ETH.linkUp() ? "link up" : "no link");
Serial.print("Ethernet ");
Serial.println(ETH.fullDuplex() ? "full duplex" : "half duplex");
Serial.print("Speed: ");
Serial.print(ETH.linkSpeed());
Serial.println(" MBit/s");
if (ETH.hasIP()) {
Serial.print("Ethernet local IP: ");
Serial.println(ETH.localIP());
}
else {
Serial.println("No Ethernet IP");
}
if (ethernetConnected) {
Serial.println(ETH);
}
delay(10000); //delay 10 s
}
// WARNING: function is called from another FreeRTOS task (thread)!
void onNetworkEvent(arduino_event_id_t event) {
switch (event) {
case ARDUINO_EVENT_ETH_START:
Serial.println("Event: Ethernet started");
ETH.setHostname(ethernetHostname);
break;
case ARDUINO_EVENT_ETH_CONNECTED:
Serial.println("Event: Ethernet connected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
Serial.println("Event: Ethernet got IP");
ethernetConnected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("Event: Ethernet lost IP");
ethernetConnected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("Event: Ethernet disconnected");
ethernetConnected = false;
break;
case ARDUINO_EVENT_ETH_STOP:
Serial.println("Event: Ethernet stopped");
ethernetConnected = false;
break;
default: break;
}
} Programmer
Um den Programmcode auf den WT32-ETH01 zu übertragen ist ein USB-Seriell-Wandler notwendig, der die Versorgungsspannung und das Logiksignal mit 3,3 V ausgibt. Häufig verwendete Wandler mit 5 V-Signal können den ESP32 irreparabel beschädigen.
Die Wandler haben typischerweise einen FT232R oder CH340 Chip und benötigen den jeweils passenden USB-Treiber. Empfehlen kann ich den „USB to TTL V0825“ Wandler mit FTDI-Chip und Jumpern für 1,8/2,5/3,3/5 V TTL-Pegel.
Die Signale RTS und DTR werden verwendet um den ESP32 automatisch in den Programmiermodus zu setzen und neu zu starten.
Hallo,
Sie schreiben über dem Bild :
Die Signale RTS und DTR werden verwendet um den ESP32 automatisch in den Programmiermodus zu setzen und neu zu starten.
Habe den ESP32-D0WD-V3 V3.1 ist das dort auch so ?
Hallo,
allgemein wird für alle ESP32-Chips mit GPIO0 und GPIO2 das Startverhalten nach einem Hardware-Reset festgelegt. Siehe Kapitel 3.1 Chip Boot Mode Control im Datenblatt des ESP32-D0WD.
Für den Programmiermodus muss GPIO0 einen Low-Pegel haben, während der Neustart über den Enable-Pin (EN bzw. CHIP_PU) durchgeführt wird.
Um die beiden Pins GPIO0 und CHIP_PU für den Programmiermodus automatisiert per Software vom PC aus steuern zu können, werden die Signalleitungen RTS und DTR der seriellen Schnittstelle genutzt.
Das ESP-Tool, das mit dem ROM-Bootloader kommuniziert und den Flashvorgang durchführt, steuert die Signalleitungen immer an, wenn diese Funktion nicht durch entsprechende Parameter unterdrückt wird (siehe Tool-Dokumentation).
Die Arduino IDE ruft im Hintergrund das ESP-Tool auf.
Fazit: Es lässt sich somit jeder ESP32-Mikrocontroller automatisch in den Programmiermodus setzen.
Hinweis: Viele Entwicklungsboards haben auch eine Auto-Reset-Schaltung, bestehend aus zwei Transistoren und deren Vorwiderständen, implementiert, die es dem USB-zu-UART-Chip auf dem Board erlauben die richtigen Steuersignale für einen Neustart und den Programmiermodus zu senden.

Beste Grüße und weiterhin viel Erfolg!
Hallo Sebastian,
danke für deinen Artikel. Ich habe das gleiche Board und versuche eine fixe IP per Ethernet zu konfigurieren. Da ist dein Code sehr hilfreich. Das Board ist auch unter der konfigurierten Adresse erreichbar. Nur der Hostname wird nicht zur Verfügung gestellt. Wenn ich die gleiche Bibliothek benutze und per DHCP konfiguriere, ist das Board unter dem Hostame erreichbar. Hast du einen hilfreichen Kommentar? Wie ist deine Erfahrung?
mit bestem Gruß,
Christian
Hallo Christian,
die Festlegung des Hostnamens scheint auch bei anderen Nutzern Probleme zu bereiten, wie man diversen Forenbeiträgen entnehmen kann.
Ich selbst kann mich nicht daran erinnern Probleme diesbezüglich gehabt zu haben. Meine Projekte mit dem WT32-ETH01 hatten aber auch deutlich umfangreicheren Code als dieses Beispiel, was die Funktionsweise beeinflusst haben kann.
Folgendes steht aber in der offiziellen Dokumentation zur Ethernet API, weshalb ich auch meinen Beispielcode hier genau so implementiert hatte:
// The hostname must be set after the interface is started, but needs
// to be set before DHCP, so set it from the event handler thread.
Das Timing, wann der Hostname festgelegt wird, scheint also entscheidend zu sein (laut Dokumentation im Event
ARDUINO_EVENT_ETH_START).Diese Diskussion auf GitHub liefert auch mehrere Lösungsansätze.
Darunter verschiedene Reihenfolgen der Befehle, mDNS zu nutzen, Zeitverzögerungen mit
delay(...);einzufügen oderWiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);bzw.ETH.config(...);aufzurufen.Bedenken Sie auch, dass sich viele Router (bzw. deren DNS-Server) Geräte im Netzwerk merken und die Geräteeigenschaften für längere Zeit nicht aktualisiert werden.
Ein Löschen des Caches oder ein Neustart des Routers kann daher auch sinnvoll sein, um alte Daten zu löschen.
Beste Grüße und weiterhin viel Erfolg!
Servus,
wollte nur noch anderen meine Erfahrungen zu dem Board dalassen, das hat nämlich ein bisschen gebraucht, bis es gelaufen ist.
1. Ich habe bei mir die Library von khoi-prog genutzt, die Beispiele darin sind sehr brauchbar und auch praxisnah. In meinem Fall MQTT.
2. Aber (!) bei mir ging es erst, nachdem ich die ESP32-Boards in Arduino auf v2.0.17 zurückgestellt habe. Mit 3.x hat die khoi-prog’sche Library nicht mehr funktioniert. Kann auch sein, dass ich irgendwas vergessen habe, aber seit ich die Update-Angebote auf 3.x ignoriere laufen die Dinger.
3. Das Programmieren ist etwas tricky, das hast du ja bereits beschrieben. Es gibt aber noch einen Fallstrick: Scheinbar bleiben beim Programmieren die Einstellungen im LAN8270 (oder wie das Ding heißt) drin. Der Reset am ESP32 hat auf den LAN8270 offenbar keinen Einfluss. Lösung: Nach dem Programmieren einmal den ESP32 zurücksetzen, damit er aus dem Programmiermodus rausgeht und dann einmal kurz vom Strom trennen. Dann geht auch die Ethernet-Verbindung wieder.
Ansonsten ist das ein nettes Teil, für 6 Euro gibt’s Ethernet, WLAN, Bluetooth und einen einigermaßen potenten Controller, der sich mit Arduino relativ einfach bespaßen lässt.
Hallo Korbinian!
Danke für Deinen Erfahrungsbericht und den Hinweis zum vollständigen Reset des Boards, damit sich keine alten Daten mehr in den Chip-Registern befinden.
Man könnte den Programmcode auch um einem manuellen Reset des Ethernet-PHYs vor
ETH.begin()ergänzen:pinMode(ETH_PHY_POWER, OUTPUT);
digitalWrite(ETH_PHY_POWER, LOW);
delay(1); // min. 100 µs
digitalWrite(ETH_PHY_POWER, HIGH);
Ich kenne die Bibliotheken von Khoi Hoang (khoih-prog).
Man muss dabei jedoch wissen, dass diese nicht von ihm stammen, sondern jeweils ein Fork anderer Repositories sind! Der Hauptunterschied zu den Originalen ist, dass seine Version im Bibliotheksmanager der Arduino IDE zu finden ist, was bei den Originalen leider nicht immer der Fall ist. Das macht die Nutzung von Khoi Hoangs Bibliotheken sehr einfach, während die Originale manuell über GitHub heruntergeladen und dann in der Arduino IDE importiert werden müssen.
Es gibt jedoch ein Problem, Khoi Hoangs Bibliotheken entsprechen nur genau dem Stand des ursprünglichen Programmcodes als der Fork erzeugt wurde. Alle Änderungen, Optimierungen und neue Funktionen die seither eingeflossen sind fehlen. Wie du selbst beschrieben hast entsteht dadurch eine große Inkompatibilität z.B. muss der ESP32 Arduino Core von der alten Version 2.x sein (V2.0.17 ist die letzte Version der V2-Reihe).
Alle Repositories von Khoi Hoang sind seit 2023 außerdem im Status „archiviert“, d.h. diese werden nicht mehr weiterentwickelt, es gibt keinen Support, sie bleiben genauso wie sie jetzt sind!
Meine ersten Versuche mit dem WT32-ETH01-Board starteten auch mit Khoi Hoangs Bibliotheken (eben weil viele alte Artikel und Forenbeiträge darauf verweisen) und ich bin ebenfalls sehr schnell auf Probleme gestoßen.
Tatsächlich war genau das der Grund, weshalb ich diesen Artikel auf meinem Blog veröffentlicht habe, um ein Beispiel bereitzustellen, wie die Ethernet-Ansteuerung ohne zusätzliche Bibliotheken (direkt mit dem aktuellen ESP32 Arduino Core) funktioniert. Alle weiteren Funktionen des ESP32 (z.B. MQTT) sind identisch zu anderen ESP32-Boards und ausreichend dokumentiert. Es ist keine spezielle Anpassung an das WT32-ETH01-Board notwendig.
Meine klare Empfehlung ist auf die Verwendung der „speziellen Versionen“ von Khoi Hoangs Bibliotheken zu verzichten und stattdessen mit den Originalen zu arbeiten, die auf dem neuesten Stand sind, besonders auch Sicherheitslücken geschlossen haben, neue Funktionen bieten und zum gesamten Arduino und ESP32 Ökosystem kompatibel sind.
Beste Grüße!
Hallo Sebastian, danke für dein wertvolles Feedback. Das hilft mir auch zu verstehen, was passiert ist.
Die verwendeten Libs sind die WebServer_WT32_ETH01.h (v1.5.1) und AsyncMqtt_Generic.h (v1.8.1).
Sehr interessant. Aktuell teste ich gerade die Langzeitstabilität des mechanisch-elektrischen Aufbaus. Falls ich nochmal Zeit und Muße habe, schreibe ich den Code vielleicht noch auf „ohne spezielle Libs“ um. Das Projekt ist nicht direkt ans Internet angeschlossen. Wenn es dazu käme, dann würde ich den Code entsprechend anpassen. Sicherheitslücken sind natürlich eine kritische Angelegenheit, da gebe ich dir vollkommen recht.