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 ergibts 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.

Wireless-Tag WT32-ETH01 Mikrocontroller-Board

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.

Funktionales Blockdiagram ESP32 Mikrocontroller

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.

WT32-ETH01 Ethernet Blockschaltbild

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.