ESP32: Neuer IoT-Chip von Espressif

Der Pragmatische Architekt  –  2 Kommentare
Anzeige

Der ESP8266 aus dem Hause Espressif ist nicht nur bei Arduino-Makern beliebt. Der Chip integriert WLAN, einen schnellen Prozessor, und viele weitere Merkmale zu einem unschlagbaren Preis. Er lässt sich als Arduino-kompatibles Board oder als Kommunikationskomponente für einen existierenden Arduino-Host betreiben. Der jüngst erschienene Nachfolger ESP32 enthält zusätzlich Bluetooth und offeriert Leistungsmerkmale, die die vieler Arduino-Boards weit übertreffen. Also Grund genug, einen ersten Blick auf den ESP32 zu werfen.

Der Blog macht Winterpause

Da der Autor dieses Blogs eine ausgiebige Auszeit benötigt, legt der Blog eine künstlerische Pause bis Mitte Januar 2017 ein.

Auch in 2017 warten wieder spannende Themen. Geplant sind unter anderem Beiträge zu

  • Mechatronik/Robotik
  • Arduino @ Cloud
  • Arduino-Simulatoren,
  • Audio/Synthesizer-Shields,
  • weiteren Microcontroller Boards,
  • zu Boards mit Embedded Linux wie z.B. Udoo Neo, BeagleBone und Raspberry Pi,
  • redpitaya's FPGA-basierten Messinstrumenten,
  • FPGA-Boards für Einsteiger,Sensorik/Aktorik-Projekten

Selbstverständlich können Sie auch jederzeit Vorschläge per Mail an mich senden. Konstruktive Kritik ist ebenfalls willkommen.

Vom ESP8266 hatte dieser Blog bereits in zwei Folgen berichtet. Die kleinen Module mit dem Chip haben bei Makern eine große Fangemeinde, bieten sie doch zu einem konkurrenzlosen Preis MCU- und WiFi-Funktionalität. Mit einfachen Mitteln lässt sich ein Arduino mit einem ESP8266 um WiFi erweitern. Schon bald ersetzten einige Maker die integrierte Firmware des ESP8266 mit eigener Firmware, sodass Entwickler ESP8266-Boards wie Arduino-Boards programmieren konnten. Der ESP32 geht nun einen Schritt weiter und ist in jeder Beziehung leistungsfähiger als der ESP8266. Zudem implementiert er Bluetooth-Logik.

Um den Leistungsumfang des ESP32 zu verstehen, habe ich im folgenden alle Daten zusammengestellt. Da sind einige sehr technische Details dabei, deren tieferes Verständnis nicht unbedingt notwendig erscheint. Nichtsdestoweniger ist es hilfreich, ein Gefühl für die Möglichkeiten des neuen Chips zu erhalten.

Ein ESP32 bietet eine ganze Menge an Schnittstellen (Bild: http://sparkfun.com)

Gehen wir also in medias res:

Ein ESP32 verfügt über einen 240-MHz-Zweikern-Mikroprozessor des Typs Tensilica LX6 mit einer Performanz von 600 DMIPS. Neben 520 KByte SRAM befinden sich 16 MByte Flashspeicher an Board. Betrieben wird der Chip mit 2,2 bis 3,6 V Spannung. Mit einer möglichen Umgebungstemperatur von -40°C bis 125°C erweist sich der ESP32 als industrietauglich. Im Tiefschlaf verbraucht der ESP32 laut Herstellerangabe 2,5 µA. Für den niedrigen Stromverbrauch sorgt speziell ein ULP-Prozessor (Ultra-Low-Power). Dabei lassen sich bis zu 8 KByte an Daten und Programme in das SRAM der RTC (Real-Time Clock) auslagern, sodass auch im Tiefschlafmodus ein Zugriff auf Timer, Interrupts, Peripherie möglich ist.

Zur Kommunikation mit der Außenwelt enthält das SoC (System on a Chip) die 802.11-b/g/n-WiFi-Komponente HT40 und Bluetooth-Funktionalität. Letzteres sowohl für "classic" Bluetooth als auch für Bluetooth Low Energy (Version <= 4.2). Neben der integrierten PCB-Antenne lässt sich eine externe Komponente mittels IPEX-Konnektor anschließen.

WiFi ist in den Betriebsarten Sniffer, Station, Access Point, Soft Access Point und im direkten Modus möglich. Als Datenraten gibt Espressif an (in Klammern sind die maximalen Übertragungsenergien spezifiziert)

150 Mbps@11n HT40 (15,5 dBm)
72 Mbps@11n HT20 (11,5 dBm)
54 Mbps@11g (16,5 dBm)
11 Mbps@11b (19,5 dBm)

An Netzwerkdurchsatz sind damit über UDP-Protokoll nachhaltig 135 Mbps erreichbar.

Die minimale Empfindlichkeit des Empfängers liegt bei -98 dBm.

Für Kommunikationsicherheit sorgen die Protokolle WEP, WPA/WPA2 PSK/Exterprise, wobei Hardware-beschleunigte Verschlüsselung über AES, SHA2, Elliptical Curve Cryptography und RSA-4096 vorliegt.

Als Sensoren bietet der ESP32 einen Hall-Sensor, eine zehnfache, kapazitive Touch-Schnittstelle, einen analogen Verstärker für niedrige Signale, und einen 32-kHz-Kristallquartz. Es ist zwar auch ein Temperatursensor eingebaut, der aber aufgrund der Umgebungstemperatur für andere Zwecke vermutlich nur schlecht nutzbar sein dürfte.

Blockdiagramm des leistungsfähigen ESP32

32 allgemein verwendbare Ein- und Ausgänge (GPIOs) stehen, wie im obigen Diagramm ersichtlich, insgesamt zur Verfügung, darunter drei UARTs mit Flusssteuerung über Hardware, drei SPI-Schnittstellen, ein CAN-Bus-2.0-Controller, zwei I2S- und zwei I2C-Schnittstellen, zudem 12 analoge Eingänge mit Analog-Digital-Umwandler bei einer Auflösung von 12 Bit, und zwei analoge Ausgänge mit Digital-Analog-Umwandler und 10 Bit Auflösung. Jeder GPIO-Port verfügt dabei über Pulsweitenmodulation und Timer-Logik.

Des Weiteren unterstützt der Chip den Anschluss von:

  • Debugging-Logik über eine OpenOCD-Schnittstelle (On-Chip-Debugger) mit 32 kB TRAX Pufferspeicher,
  • Hardwarekomponenten über eine SDIO Master/Slave-Schnittstelle mit 50 MHz,
  • externen SPI-Flashspeichern mit bis zu 16 MByte und
  • SD-Karten-Hardware.

Wer noch mehr Details erfahren möchte: Weitere Informationen zum ESP32 findet sich auch in diesem Make:-Artikel.

Zum Experimentieren mit dem ESP32 ist ein nackter ESP32-Baustein nur für Hardware-Nerds geeignet, die das SoC in aller Breite und Tiefe kennen lernen wollen. Wer dazu keine Lust hat und sich mehr für eine Plug-and-Play-Ansatz interessiert, kann auf voll bestückte Boards diverser Hersteller zugreifen. Der Autor hat zwei Optionen getestet und mit einer zusätzlichen Option ein wenig experimentiert.

Das ESP32 Thing von SparkFun basiert auf dem ESP32-SoC von Espressif. Mit dem "Thing" im Namen möchte der Hersteller den Fokus des Boards als Gerät für das Internet der Dinge verdeutlichen. Zusätzlich zum ESP32 enthält das Board unter anderem eine FTDI-FT231x-USB-Schnittstelle, die Arduino-Entwicklern vertraut sein dürfte. Wer allerdings noch keine Arduino-Boards am Entwicklungsrechner genutzt hat, muss unter Umständen Treiber für den FTDI-Baustein installieren. Als Add-on integriert das Board eine Komponente zum Laden von LiPo-Akkus. In den USA schlägt die Hardware bei SparkFun mit $ 17,96 zu Buche. In Deutschland bietet zum Beispiel exp-tech das Board für 21,60 an.

sparkfun ESP32 Thing beheimatet den ESP32 Chip

Das Board von Watterott ist zum Espressif Core Board (DevKitC) kompatibel, was einige Vorteile für die ersten Gehversuche mit sich bringt, weil dafür schon Software von Espressif zur Verfügung steht. Der Anschluss des Boards an den Entwicklungsrechner funktioniert mittels microUSB. Als USB-UART-Bridge fungiert ein Silabs-CP2102N-Baustein, der spezielle Treiber benötigt. Maker erhalten das Board für € 17,95 bei Watterott. "WROOM" kommt übrigens von den ESP32-Modulen des ESP32-Herstellers Espressif. Das WROOM-02-Board ist kleiner als das WROOM-32-Board. Dafür führt letzteres alle Pins des ESP32 nach außen.

Watterott's ESP32-Breakout-Board (Bild: watterott.com)

Außer Konkurrenz soll der pycom WyPy 2.0 Erwähnung finden, über den der Blog-Autor in Zukunft etwas ausführlicher berichten möchte. pycom bietet mit diesem Modul nicht einfach ein weiteres ESP32-Board an. Das Board ragt insbesondere deshalb aus der Konkurrenz heraus, weil es eine MicroPython-Firmware auf Basis von Python besitzt. Es lässt sich aber auch mit anderer Firmware bespielen. Unter Python ist auch Multi-Threading möglich. Dieses Produkt bieten unter anderem exp-tech und Watterott für unter € 24 an.

Pycom WiPy v2 enthält eine Firmware auf Basis von Micro Python (Bild: watterott.com)

Um ESP32-Boards wie die genannten nahtlos im Arduino-Ökosystem zu nutzen, bedarf es spezieller Firmware und Werkzeuge. Die Firmware ESP32 Arduino Core sorgt dafür, dass Entwickler ein ESP32-Board so innerhalb der Arduino IDE programmieren können wie ein Arduino- oder Teensy-Board.

Neben einer Git-Installation ist als Vorbereitung eine Python-2.7-Laufzeitumgebung notwendig. Ich gehe davon aus, dass die Arduino IDE bereits in einer aktuellen Version auf dem Rechner vorliegt.

Sie finden die unteren Anweisungen übrigens auch auf der Webseite des Arduino ESP32 Core Projekts auf GitHub.

Als Erstes sollten Sie in das Verzeichnis wechseln, in dem sich Arduino-Sketches, Bibliotheken, und Hardwaredefinitionen befinden. Meistens liegt das Verzeichnis Arduino unterhalb des benutzerspezifischen Dokumentenordners. Dort geben Sie in einer Konsole bzw. einem Terminal folgende Kommandos ein. Kann gut sein, dass es bereits ein Unterverzeichnis hardware gibt, sodass sich das mkdir hardware-Kommando als nicht notwendig erweist:

mkdir hardware
cd hardware
mkdir espressif
cd espressif
git clone https://github.com/espressif/arduino-esp32.git esp32

Nun müssen Sie innerhalb des neu erzeugten esp32-Verzeichnisses das Python-Skript get.py aufrufen:

python get.py

Das Skript lädt die Xtensa GNU Tools und das ESP32 Software Development Kit herunter. Nach Schließen und Neuöffnen der Arduino IDE sehen Sie in der IDE im Tools | Boards-Menü die nun zusätzlich verfügbaren Boards.

Nach der Installation des ESP32 Arduino Core stehen in der Arduino IDE ESP32-Boards zur Verfügung

Für die Entwicklung mit den ESP32-Boards von SparkFun und Watterott eignet sich das ESP32 Dev Module als Board-Einstellung.

Alle Funktionalitäten der Arduino-ESP32-Core-Firmware funktionieren zwar im Moment noch nicht komplett, zumindest aber die folgenden:

  • pinMode
  • digitalRead/digitalWrite
  • attachInterrupt/detachInterrupt
  • Serial (die globale Serial-Schnittstelle liegt standardmäßig an Pins 1 und 3. Die anderen zwei seriellen Schnittstellen können Maker an beliebigen Pins betreiben)
  • SPI (das globale SPI ist standardmäßig über die VSPI angeschlossen, und HSPI lässt sich an beliebigen anderen Pins realisieren)
  • Wire (der globale I2C-Bus funktioniert standardmäßig über Pins 21 und 22, und den anderen I2C Bus können Maker beliebigen Pins zuweisen)
  • WiFi (zu 99% identisch zum ESP8266)

Hier das unvermeidliche, weil triviale Blink-Beispiel mit an Pin 13 angeschlossener LED und seriellem Monitor. Beim sparkfun ESP32 Thing müssen Sie die Taster RST betätigen, falls die blaue On-Board LED an Pin 5 nur schwach leuchtet und sich auch sonst nichts rührt. Danach geht die Post ab. Beim ESP32-WROOM-Breakout-Board von Watterott betätigen Sie stattdessen den Taster EN.

Mit der an der Arduino IDE eingestellten Upload-Geschwindigkeit von 921600 Baud funktioniert das Programmieren der Boards im Übrigen angenehm flott.

int ledPin = 13;                                                                                                   
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
}

void loop()
{
digitalWrite(ledPin, HIGH);
Serial.println("an");
delay(500);
digitalWrite(ledPin, LOW);
Serial.println("aus");
delay(500);
}

Hauptmerkmal des ESP32 ist seine Kommunikationsfähigkeit. Der nachfolgende Sketch zeigt die Verbindung über WLAN und das Holen eine Webseite (heise.de). Am Pin 13 ist über 220-Ohm-Widerstand eine LED angeschlossen.

Geben Sie im Code ihre eigenen Zugangsdaten an. Die Ausgaben erfolgen über den seriellen Monitor mit 115200 Baud.

/////////////////////////////////////////////////////////
//
// Demo-Programm zum Webzugriff über
// ESP32-Breakout-Board
//
/////////////////////////////////////////////////////////


#include <WiFi.h> // WiFi-Bibliothek nutzen

// WLAN Zugangsdaten
const char * ssid = "StalWLAN";
const char * pswd = "........";

// Zu holende Seite:
const char * link = "heise.de";
const int port = 80;

// LED an Pin 13
const int LED = 13;


/////////////////////////////////////////////////////////
//
// setup
// Verbindungsaufbau mit WLAN
// & LED deklarieren
//
/////////////////////////////////////////////////////////

void setup()
{
// Hardware initialisieren
Serial.begin(115200);
pinMode(LED, OUTPUT);

digitalWrite(LED, LOW);
// Zum Netz verbinden
Serial.println("Verbindungsaufbau");
connectWLAN(ssid, pswd);
}

/////////////////////////////////////////////////////////
//
// loop
// Alle 10 Sekunden Webseite http://<link>:<port> lesen
//
/////////////////////////////////////////////////////////

void loop()
{
readPage(link, port);
delay(10000);
}

/////////////////////////////////////////////////////////
//
// connectWLAN
// Mit WLAN <ssid> und Passwort <pswd> verbinden
//
/////////////////////////////////////////////////////////

void connectWLAN(const char * ssid, const char * pswd)
{
Serial.println("Verbinden mit " + String(ssid));

WiFi.begin(ssid, pswd);

while (WiFi.status() != WL_CONNECTED);

Serial.println();
Serial.println("Verbunden");
Serial.print("Eigene IP Adresse: ");
Serial.println(WiFi.localIP());
}


/////////////////////////////////////////////////////////
//
// printPage
// Seite über Verbindung <client> lesen
//
/////////////////////////////////////////////////////////

void printPage(WiFiClient client) {
while (client.available())
{
String line = client.readStringUntil('\r');
Serial.print(line);
}
}

/////////////////////////////////////////////////////////
//
// createGetCommand
// HTTP GET Kommando für Seite <link> kreieren
//
/////////////////////////////////////////////////////////

String createGetCommand(const char * link) {
return (String)"GET / HTTP/1.1\r\n" +
"Host: " + String(link) + "\r\n" +
"Connection: close\r\n\r\n";
}

/////////////////////////////////////////////////////////
//
// getPage: Seite <link> über Verbindung <client>
// mit HTTP GET holen
//
/////////////////////////////////////////////////////////

void getPage(WiFiClient client, const char * link) {
client.print(createGetCommand(link));
unsigned long timeout = millis();
while (client.available() == 0) // maximal 5 Sekunden
{
if (millis() - timeout > 5000)
{
Serial.println("*** Client Zeitüberschreitung ***");
client.stop();
return;
}
}
Serial.println();
}

/////////////////////////////////////////////////////////
//
// readPage
// Seite http://<link>:<port> lesen
//
/////////////////////////////////////////////////////////

void readPage(const char * link, uint8_t port)
{
Serial.println("Verbinden mit URL: " + String(link));

// TCP-Verbindung erzeugen
WiFiClient client;
if (!client.connect(link, port)) // verbinden
{
Serial.println("*** Verbindung fehlgeschlagen ***");
return; // in die nächste Runde
}
// Verbindungsaufbau ist jetzt gestartet:
digitalWrite(LED, HIGH); // LED an
Serial.println("Verbindung steht");

getPage(client, link); // Seite holen
printPage(client); // Seite ausgeben

Serial.println("Schließen der Verbindung");

digitalWrite(LED, LOW); // LED aus
client.stop(); // Verbindung schließen
}

Eine Beispielausgabe am seriellen Monitor könnte folgendermaßen aussehen:

WiFi-Verbindung mit dem ESP32

Da es im Augenblick nur wenig Funktionalität gibt, die der Programmierer direkt von der Arduino IDE aus nutzen kann, lohnt sich ein Blick auf ESP-IDF oder ausführlich Espressif IoT Development Framework. Dieses lässt sich unter Windows (-> Installationsanweisungen), MacOS (-> Installationsanweisungen) oder Linux (-> Installationsanweisungen) installieren. IDF verwendet als Betriebssystem bzw. als Firmware FreeRTOS.

Die Entwicklung erfolgt dort auf der Kommandozeile über make.

  • make menuconfig erlaubt die Festlegung von App-spezifischen Einstellungen wie den Port, über den das ESP32-Board angeschlossen ist:
make menuconfig erlaub die Konfiguration der Systemparameter
  • make stößt die Erzeugung des Programms an:
make erlaubt das Übersetzen der ESP32-Anwendung
  • make clean entfernt die erzeugten Artefakte.
  • make flash überspielt das Image auf das ESP32-Board:
Flashen einer Anwendung funktioniert in IDF über make flash

Das obligatorische Blink-Programm gestaltet sich dort wie folgt (das Listing stammt aus dem examples-Verzeichnis der esp-idf-Installation):

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

/* Can run 'make menuconfig' to choose the GPIO to blink,
or you can edit the following line and set a number here.
*/

#define BLINK_GPIO CONFIG_BLINK_GPIO

void blink_task(void *pvParameter)
{
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/

gpio_pad_select_gpio(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
while(1) {
/* Blink off (output low) */
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(1000 / portTICK_RATE_MS);
/* Blink on (output high) */
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(1000 / portTICK_RATE_MS);
}
}

void app_main()
{
nvs_flash_init();
xTaskCreate(&blink_task, "blink_task", 512, NULL, 5, NULL);
}

Ausgaben am seriellen Monitor verfolgt der Entwickler über Terminalprogramme wie putty, screen, teraterm.

Wer es bequemer haben möchte, kann IDF auch in Eclipse CDT integrieren. Wie das funktioniert, ist ausführlich auf dieser Webseite beschrieben. Der folgende Screenshot zeigt das Flashen eines Beispielsprogramms auf das ESP32-Board aus der Eclipse IDE heraus.

IDF deluxe: Flashen aus der Eclipse-IDE

Für die Experimentierfreudigen: Im genannten Beispielsverzeichnis finden sich auch komplexere Beispiele wie eine Anwendung mit Bluetooth-Anbindung.

In dieser letzten Blog-Folge vor der Winterpause haben wir den ESP32 von Espressif und zugehörige Breakout-Boards kennengelernt. Schwerpunkt war dabei der Einsatz der Boards autonom mit Arduino ESP32 Core als Firmware. In späteren Folgen kommen noch weitere Funktionalitäten des ESP32 zur Sprache, ebenso wie die Nutzung als WiFi/Bluetooth-Komponente eines Arduino-Hosts. Es ist davon auszugehen, dass bis dahin auch die Unterstützung des ESP32 in der Firmware ESP32 Arduino Core reift. Ebenso ist mit dem Erscheinen zahlreicher Bibliotheken für den Chip zu rechnen.

Allerdings dürfte schon an dieser Stelle feststehen, dass ein ESP32-Breakout-Board von der Leistungsfähigkeit sowohl technisch als auch preislich eine echte Alternative zu Arduino-Boards darstellt. Da erscheint es fast schon zu schade, die Möglichkeiten des leistungsstarken SoC nicht zu verwenden, sondern es ausschließlich als Arbeitssklaven eines Arduino einzusetzen. Speziell für IoT-Anwendungen mit ihrem Kommunikationsbedarf eignet sich der ESP32 schließlich hervorragend. Daher dürfte der ESP32 diesen Blog auch in Zukunft beschäftigen.

In diesem Sinne wünsche ich Ihnen allen frohe, besinnliche Feiertage und einen guten Rutsch ins neue Jahr.

Anzeige