Versuch 2: Wetterabfrage mit esp32

1 Einleitung

1.1 Motivation

Die Idee hinter diesem Projekt entstand aus dem Wunsch, alltägliche Informationen wie das Wetter technisch greifbar und visuell erlebbar zu machen. Wetterdaten gehören zu den am häufigsten genutzten Informationen im Alltag, sei es zur Planung des Tages, für die Landwirtschaft oder für industrielle Anwendungen. Statt die Daten nur auf dem Smartphone abzulesen, wollten wir sie auf kreative Weise selbst abrufen, interpretieren und darstellen.

1.2 Projektentscheidung

Unsere Entscheidung, mit dem ESP32 zu arbeiten, fiel bewusst. Der Mikrocontroller ist nicht nur kostengünstig und vielseitig einsetzbar, sondern bringt auch eine integrierte WLAN-Schnittstelle mit, was ihn besonders geeignet für IoT-Projekte (Internet of Things) macht. Dadurch konnten wir direkt auf Online-Dienste wie die OpenWeatherAPI zugreifen, eine Schnittstelle, die weltweite Wetterdaten bereitstellt.

Besonders interessant war für uns die Kombination aus mehreren Aspekten:

  • Hardware (ESP32, LEDs, Touch-Sensor)
  • Software (WLAN-Verbindung, HTTP-Requests, JSON-Verarbeitung)
  • Datenquellen aus dem Internet

1.3 Zielsetzung

Durch diese Kombination konnten wir ein praxisnahes und lernintensives Projekt umsetzen, das viele Themenbereiche aus der Welt der Mikrocontroller, Netzwerktechnik und Datenvisualisierung vereint. Gleichzeitig bietet es einen Einstieg in moderne Anwendungen wie Smart Homes oder Umweltsensorik.

Ziel des Projekts war es, ein System zu bauen, das

  • aktuelle Wetterdaten aus dem Internet abruft,
  • verschiedene Wetterzustände erkennt (zum Beispiel Regen, Temperatur oder Luftfeuchtigkeit),
  • und diese Informationen auf einfache Weise visuell darstellt.

Das Projekt soll zeigen, wie sich mit wenig Hardware und grundlegender Programmierung nützliche Anwendungen entwickeln lassen, die reale Datenquellen sinnvoll nutzen.

2 Theoretische Grundlagen

2.1 Bauteile: Aufbau, Vorteile, Nachteile, Submodule

2.1.1 ESP32 Mikrocontroller

Der ESP32 ist ein Mikrocontroller der Firma Espressif Systems, der sich besonders für IoT-Projekte eignet. Er verfügt über integriertes WLAN und Bluetooth sowie über zwei 32-Bit-Prozessorkerne. Damit ist er deutlich leistungsfähiger als der klassische Arduino Uno und erlaubt den Zugriff auf Online-Dienste wie z.B. Wetter-APIs.

Vorteile:

  • Integrierte WLAN- und Bluetooth-Funktionalität
  • Dual-Core-Prozessor für parallele Verarbeitung
  • Zahlreiche GPIO-Pins für Sensoren und Aktoren
  • Energieeffizient mit verschiedenen Sleep-Modi
  • Unterstützt viele Programmierumgebungen (z. B. Arduino IDE, MicroPython, ESP-IDF)

Nachteile:

  • Höherer Stromverbrauch im Vergleich zu einfacheren Mikrocontrollern bei aktiver WLAN-Nutzung
  • Komplexere Einrichtung und Konfiguration
  • Betriebsspannung 3,3 V (Vorsicht bei 5 V Komponenten)

Aufbau und wichtige Module:

  • USB-Anschluss zur Stromversorgung und Programmierung
  • Flash-Speicher für Programme
  • Antenne für WLAN- und Bluetooth-Kommunikation
  • Spannungsregler (für 3,3 V Betrieb)
  • GPIOs für digitale und analoge Ein-/Ausgabe

GPIO-Funktionen im Überblick:

  • Digitale Ein-/Ausgänge (Input/Output): Steuerung von Komponenten wie Tastern, LEDs, Relais oder Lesen von Sensorsignalen.
  • PWM – Pulse Width Modulation: Simulation von analogen Ausgangswerten, z. B. zur Helligkeitssteuerung von LEDs oder Drehzahlregelung von Motoren.
  • ADC – Analog-Digital-Wandler: Wandelt analoge Signale (z. B. Spannungen von Sensoren) in digitale Werte, die im Programm verarbeitet werden können.
  • I²C – Inter-Integrated Circuit: Serielles Kommunikationsprotokoll, um mehrere Sensoren oder Module über nur zwei Leitungen (SDA, SCL) anzuschließen.
  • SPI – Serial Peripheral Interface: Schnelles serielles Protokoll zur Kommunikation mit z. B. Displays, Speichermodulen oder schnellen Sensoren. Nutzt in der Regel vier Leitungen (MOSI, MISO, SCK, SS).

2.1.2 LED-Leuchte (Standard 5 mm Rundkopf, sortiert)

In diesem Projekt verwenden wir klassische 5 mm LEDs aus einem Sortiment (z. B. Rot, Grün, Blau, Gelb), die zur visuellen Ausgabe von Wetterinformationen eingesetzt werden. Eine LED besteht aus einem Halbleiterkristall, der bei Stromdurchfluss Licht emittiert. Zur Steuerung wird jeweils ein Vorwiderstand verwendet, um die LED vor zu hoher Stromstärke zu schützen.

Vorteile:

  • Geringer Stromverbrauch
  • Einfache Ansteuerung über GPIO-Pins
  • Klare visuelle Rückmeldung (z. B. zur Temperaturanzeige)
  • Große Farbauswahl

Nachteile:

  • Keine Darstellung komplexer Informationen möglich
  • Helligkeit kann in heller Umgebung schwer erkennbar sein
  • Einzelne LEDs benötigen jeweils einen eigenen GPIO

Aufbau:

  • Zwei Beinchen: Anode (+) und Kathode (–)
  • Anschluss über Vorwiderstand (typisch: 220–330 Ω)
  • Einfache digitale Ansteuerung oder über PWM (z. B. Helligkeit oder Farbverläufe bei RGB)

2.1.3 Breadboard (Steckplatine)

Das Breadboard ermöglicht den Aufbau von Schaltungen ohne Löten. Es wird häufig im Prototypenbau verwendet und eignet sich besonders für Testaufbauten mit Mikrocontrollern.

Vorteile:

  • Wiederverwendbar und flexibel
  • Keine Lötkenntnisse erforderlich
  • Ideal für schnelle Tests und Änderungen

Nachteile:

  • Kein sicherer Kontakt bei häufigem Umstecken
  • Nicht geeignet für dauerhafte Installationen
  • Begrenzte Stromtragfähigkeit der Kontakte

Aufbau und Struktur:

  • Vertikale Stromschienen (meist links und rechts) für VCC und GND
  • Horizontale Kontaktreihen (je 5 verbundene Pins) für Bauteile
  • Verbindungen über Jumper-Kabel
  • Komponenten wie Widerstände, LEDs, Sensoren oder Mikrocontroller-Boards können direkt eingesteckt werden

2.2 OpenWeatherAPI Theorie

Vorgehen:

  1. Account erstellen
  2. API Key erstellen
  3. API Template verstehen
  4. API Request schreiben
  5. API Result auswerten

Vorteile von OpenWeatherAPI:

  • Kostenlos
  • Globale Abdeckung
  • Verschiedene Datensets (historisch, prediction, realtime)
  • Einfache Integration
  • Zuverlässig und genau

Beispiel API-Aufruf:

https://api.openweathermap.org/data/2.5/weather?lat=48.35879921860846&lon=10.90643546327268&appid=API-KEY&units=metric

Beispiel API-Result:

{
  "coord": {
    "lon": 10.9064,
    "lat": 48.3588
  },
  "weather": [
    {
      "id": 804,
      "main": "Clouds",
      "description": "overcast clouds",
      "icon": "04d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 8.03,
    "feels_like": 4.68,
    "temp_min": 7.85,
    "temp_max": 9.25,
    "pressure": 1014,
    "humidity": 79,
    "sea_level": 1014,
    "grnd_level": 954
  },
  "visibility": 10000,
  "wind": {
    "speed": 6.17,
    "deg": 220
  },
  "clouds": {
    "all": 100
  },
  "dt": 1744968114,
  "sys": {
    "type": 1,
    "id": 1308,
    "country": "DE",
    "sunrise": 1744950020,
    "sunset": 1744999839
  },
  "timezone": 7200,
  "id": 2954172,
  "name": "Augsburg",
  "cod": 200
}

2.3 Ergebnisausgabe Theorie:

ID für aktuelle Ausgabe (0 = reset; 1 = Wetter allgemein; 2= Temperatur; 3= Humidity;…)

  • Wetter allgemein anzeige (rot blau grün) o.ä.
  • Cloudiness in % in Binär?
  • Temperatur und Humidity in Binär?
  • Rain boolean flag / binary mm/h value
  • Wind Speed in m/sec

3 Elektronikaufbau und Verkabelung

-> inkl. Schaltkreis skizze

4 Code

4.1 WiFi Connection

#include <WiFi.h>
const char* ssid = "wifi_ssid";
const char* password = "password";
WiFi.begin(ssid, password);

4.2 API Call

#include <ArduinoJson.h>
const char* api_url = "https://api.openweathermap.org/data/2.5/weather?lat=48.35879921860846&lon=10.90643546327268&appid=API_KEY&units=metric";

if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(api_url); 
    int httpResponseCode = http.GET(); 

    if (httpResponseCode > 0) { 
        String payload = http.getString(); 
        Serial.println("api response:");
        Serial.println(payload);
    }
    ...
}

Die Json-Response kann im Anschluss entweder manuell oder mit Hilfe einer Library ausgewertet werden.

4.3 API Result Conversion

#include <ArduinoJson.h>
JsonDocument doc;

deserializeJson(doc, payload);

const char* weather = doc["weather"]["0"]["main"];
Serial.println(weather);
            
// in °C
float temperature = doc["main"]["temp"];
Serial.println("--------------------------------------- TEMPERATURE ---------------------------------------");
Serial.println(temperature);

// in %
int humidity = doc["main"]["humidity"];
Serial.println("--------------------------------------- HUMIDITY ---------------------------------------");
Serial.println(humidity);

// in mm/h
int rainamount = doc["rain"]["1h"];
bool raining = false;
if (rainamount > 0){
    raining = true;
}

// in mm/h 
int snowamount = doc["snow"]["1h"];

// in meter/sec
float windspeed = doc["wind"]["speed"];

// in %
int cloudiness = doc["clouds"]["all"];

Unter Verwendung der Library “ArduinoJson” können die gewünschten Werte des JsonDocument sehr einfach ausgelesen werden.

4.4 Code Lichter Ausgabe:

Nachdem das API-Setup besprochen wurde, kommen wir zur Lichterausgabe. Nach der setup()-Funktion werden drei Funktionen ausgeführt: die loop()-Funktion, die count()-Funktion und zu guter Letzt die lichteran()-Funktion.

void loop() {
  
  delay(7500);
  Serial.println(" temperatur:");
   // Serial.println("Zahl : -1 in zweierkomplement :");
  String erg = count(TEMP_C);
  lichteran(erg);
  delay(1000);
}

Die loop()-Funktion wiederholt fortlaufend dieselbe Aufgabe: Nach einer kurzen Wartezeit ruft sie die Temperatur als Integer von der API ab und übergibt sie der count()-Funktion, die den Integer in einen 8-Bit-Zweierkomplement-String überführt.

String count(int grad){

  std::bitset<8> bits(static_cast<unsigned char>(grad));
  String ergebnis = bits.to_string().c_str();
  Serial.println(ergebnis);

  return ergebnis;
}

Nachdem dass Zweierkomplement erfasst wurde, wird die Binärzahl an die letzte Funktion “lichteran()” übergeben. Bei jeder “1” im String wird an der entsprechenden Stelle ein Licht ausgegeben - dadurch wird die Temperatur erfolgreich in Binärschreibweise angezeigt.

void lichteran(String zweierkompl){
  for (size_t i = 0; i < zweierkompl.length(); i++) {
    char c = zweierkompl[i];
    int pin = alldigitalarr[i];
    if (c == '1'){
      digitalWrite(pin, HIGH);
      } else {
      digitalWrite(pin, LOW);
    }
  }
}

4.5 Code - Gesamt:

#include <ArduinoJson.h>
#include <ArduinoJson.hpp>
#include <bitset>
#include <DNSServer.h>



#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "hotspotnetzwerkname";
const char* password = "hotspotpasswort";
const char* api_url = "http://api.openweathermap.org/data/2.5/weather?id=2954172&appid=hierkeyreinpacken&units=metric&lang=de";
int TEMP_C = 0;

// alle Pins// LEDs in chronologischer Reihenfolge :
const int alldigitalarr [8] = {4,16,17,5,18,15,2,22};

void setup() {
  Serial.begin(9600);
  WiFi.begin(ssid, password);

  // Warten auf WLAN-Verbindung
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  Serial.print(".");
  }

  Serial.println("\nWLAN verbunden!");

  // API abrufen
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(api_url);
    int httpCode = http.GET();

    if (httpCode > 0) {
      String payload = http.getString();
      JsonDocument doc;
      deserializeJson(doc, payload);
     
      float temp_k = doc["main"]["temp"];
       TEMP_C = static_cast<int>(temp_k); 
      Serial.print(TEMP_C);
      //Serial.println(" °C");
    } else {
      Serial.print("HTTP Fehler: ");
      Serial.println(httpCode);
    }

    http.end();
  }
    

    
// lampen von links nach rechts 
pinMode(4,OUTPUT);
pinMode(16,OUTPUT);
pinMode(17,OUTPUT);
pinMode(5,OUTPUT);
pinMode(18,OUTPUT);
pinMode(15,OUTPUT);
pinMode(2,OUTPUT);
pinMode(22,OUTPUT);

}
String count(int grad){

  std::bitset<8> bits(static_cast<unsigned char>(grad));
  String ergebnis = bits.to_string().c_str();
  Serial.println(ergebnis);

  return ergebnis;
}

void lichteran(String zweierkompl){
  for (size_t i = 0; i < zweierkompl.length(); i++) {
    char c = zweierkompl[i];
    int pin = alldigitalarr[i];
    if (c == '1'){
      digitalWrite(pin, HIGH);
      } else {
      digitalWrite(pin, LOW);
    }
  }
}

void loop() {
  
  delay(7500);
  Serial.println(" temperatur:");
   // Serial.println("Zahl : -1 in zweierkomplement :");
  String erg = count(TEMP_C);
  lichteran(erg);
  delay(1000);
}

5 esp32 Architektur

Der ESP32 ist ein hochintegrierter Mikrocontroller mit zwei unabhängigen Xtensa® LX6-Kernen in Harvard-Architektur \({\color{green}\text{(Abb. 1)}}\).

Abb. 1: Harvard Architektur trennt den Speicher physisch in Programmspeicher und Datenspeicher, was parallelen Zugriff auf Programmcode und Daten ermöglicht.

Beide Kerne („PRO_CPU“ und „APP_CPU“) verfügen jeweils über getrennte Daten- und Instruktionsbusse, teilen sich jedoch, mit wenigen Ausnahmen, eine symmetrische Adressierung für eingebetteten Speicher, externen Speicher und Peripherie \({\color{green}\text{(Abb. 2)}}\). Zahlreiche Peripheriemodule können über DMA direkt auf den internen SRAM zugreifen.

Abb. 2: Die abgebildete Architektur zeigt das Speicher- und Datenverarbeitungssystem des ESP32-Mikrocontrollers. Der ESP32 besitzt eine Dual-Core-Architektur mit PRO_CPU und APP_CPU, die gemeinsam auf eingebetteten Speicher, Cache, externe Speicher über die MMU sowie Peripheriegeräte zugreifen können. Ein DMA-Controller ermöglicht effiziente Datenübertragung ohne CPU-Belastung, was die Architektur besonders leistungsfähig und flexibel für komplexe Embedded-Anwendungen macht.

5.1 Dual-Core-Architektur und Interrupt-Verteilung

Der ESP32 besitzt zwei Rechenkerne, PRO_CPU (Core 0) und APP_CPU (Core 1), die unabhängig voneinander Aufgaben ausführen können. Eine zentrale Komponente zur Steuerung der Interruptverarbeitung ist die Interrupt-Matrix. Diese erlaubt die flexible Zuweisung von bis zu 71 Peripherie-Interruptquellen an 26 CPU-spezifische Interruptleitungen pro Kern \({\color{green}\text{[1, S. 35]}}\). Bis auf vier Ausnahmen (zwei pro Kern, spezifisch für GPIO-Interrupts) können alle Interruptquellen beliebig auf beide Kerne verteilt werden. Das bedeutet, dass Systementwickler die Last gezielt zwischen PRO_CPU und APP_CPU aufteilen können.

Ein Beispiel: Zeitkritische oder sicherheitsrelevante Aufgaben können exklusiv dem PRO_CPU zugewiesen werden, während Netzwerk-Stacks oder Benutzereingaben auf dem APP_CPU verarbeitet werden. Durch diese gezielte Aufteilung wird eine effektive Parallelverarbeitung erreicht und die Reaktionsfähigkeit des Systems optimiert.

Der APP_CPU kann über spezielle Controller-Register \({\color{green}\text{[1, S. 100]}}\) konfiguriert werden. Hierzu zählt die Möglichkeit, den Kern gezielt anzuhalten (Stall), sowie das Setzen eines alternativen Startpunktes im ROM-Bootprozess. Diese Register ermöglichen eine differenzierte Steuerung und sind essenziell für fortgeschrittene Power-Management- und Debugging-Funktionen bei Dual-Core-Anwendungen.

5.1.1 Parallel arbeitende DMA-Controller und Peripherie

Ein weiteres Schlüsselelement zur Entlastung der CPU-Kerne ist der umfangreiche Einsatz von Direct Memory Access (DMA) \({\color{green}\text{[1, S. 127-131]}}\). Der ESP32 unterstützt DMA für eine Vielzahl von Peripheriegeräten, darunter UART, SPI, I2S, SD/MMC, Wi-Fi und Bluetooth. Diese DMA-Engines ermöglichen den direkten Datentransfer zwischen Speicher und Peripherie, ohne CPU-Intervention. Dies bedeutet, dass beispielsweise ein kontinuierlicher Audio-Stream über I2S mit DMA verarbeitet werden kann, während die CPU andere Aufgaben übernimmt.

Die DMA-Architektur basiert auf einer Linked-List-Struktur \({\color{green}\text{(Abb. 3)}}\), wodurch flexible und gepufferte Datenübertragungen mit minimalem Overhead realisierbar sind. Jeder DMA-Kanal kann unabhängig konfiguriert und aktiviert werden, etwa durch Initialisierung einer Empfangs- oder Sende-Linked-List, wie dies z. B. bei UART oder SPI notwendig ist. Diese DMA-Fähigkeiten ermöglichen eine parallele Peripherienutzung auf mehreren Datenpfaden gleichzeitig.

Abb. 3: Die gezeigte Linked-List-Struktur besteht aus drei Datenwörtern (DW0–DW2), wobei DW0 Steuerinformationen wie Besitzer (owner), End-of-File-Markierung (eof), Länge und Größe des Puffers enthält, DW1 die Adresse des Datenpuffers angibt und DW2 auf den nächsten Descriptor in der Kette verweist. Diese Struktur ermöglicht es dem DMA-Controller, Daten effizient und sequenziell über mehrere Speicherpuffer hinweg zu übertragen, ohne die CPU zu belasten.

5.2 Speicherarchitektur des ESP32

ESP32 verfügt über eine komplexe, hierarchisch strukturierte Speicherarchitektur. Diese umfasst sowohl eingebettete Speicherbereiche (Embedded Memory) als auch externe Speicherressourcen.

Eingebetteter Speicher (Embedded Memory): gliedert sich in folgende Komponenten \({\color{green}\text{[1, S. 26-29]}}\):

  • Interner ROM: 448 KB (aufgeteilt in ROM 0 und ROM 1)
  • Interner SRAM: 520 KB (aufgeteilt in SRAM 0, SRAM 1 und SRAM 2)
  • RTC FAST Memory: 8 KB
  • RTC SLOW Memory: 8 KB

DMA-Kompatibilität: DMA-fähige Peripherieeinheiten (z. B. UART, SPI, I2S, SDIO, BT, WLAN) greifen über dieselben Adressräume wie die CPUs auf SRAM 1 und SRAM 2 zu \({\color{green}\text{[1, S. 30]}}\). Diese Funktionalität ermöglicht high-performance Datenübertragungen ohne CPU-Intervention.

Externer Speicher (External Memory): Der ESP32 unterstützt die Anbindung externer Speicher via SPI.

  • Externer Flash: Bis zu 16 MB (über Cache/MMU gemappt)
    • Datenbus: 0x3F40_0000 – 0x3F7F_FFFF (4 MB)
    • Instruktionsbus: 0x400C_2000 – 0x40BF_FFFF (bis zu 11,25 MB)
  • Externe SRAM: Bis zu 8 MB
    • Datenbus: 0x3F80_0000 – 0x3FBF_FFFF

Cache-System: Jeder der beiden CPU-Kerne des ESP32 verfügt über einen eigenen 32 KB großen Cache (Zugriffsblockgröße: 32 Byte), der über eine zweifach assoziative Set-Architektur verfügt. Der Cache kann selektiv aktiviert und konfiguriert werden \({\color{green}\text{[1, S. 31-32]}}\):

  • POOL0/POOL1 aus dem internen SRAM 0 dienen als Cache-Speicher.
  • CACHE_MUX_MODE legt die Zuordnung der Pools zu den jeweiligen CPUs fest.
  • Gleichzeitiger Cache-Zugriff beider CPUs ist nur eingeschränkt möglich (siehe Tabelle 1-5 im TRM).
  • Ein Cache-Flush kann softwareseitig ausgelöst werden; dabei werden Cache-Inhalte nicht in externen Speicher zurückgeschrieben.

5.3 Peripheriegeräte und Schnittstellen des ESP32 mit Fokus auf DMA und SPI

Der ESP32 verfügt über 41 Peripheriemodule \({\color{green}\text{[1, S. 32]}}\), die über dedizierte Adressräume ansprechbar sind und umfangreiche Funktionalitäten für eingebettete Systeme bereitstellen.

5.3.1 Sicherheitsmanagement

Das Sicherheitskonzept des ESP32 basiert auf einer Kombination aus physischer, kryptographischer und softwarebasierter Schutzmechanismen. Integrierte Hardwaremodule wie eFuse-Controller, Krypto-Beschleuniger (AES, RSA, SHA), ein True Random Number Generator (RNG) sowie eine Speicherverschlüsselungseinheit sorgen für Datenschutz, Integrität und Schutz vor Manipulation.

Der eFuse-Controller bietet nichtflüchtigen, einmal beschreibbaren Speicher zur Konfiguration sicherheitsrelevanter Systemparameter. Ein einmal gesetztes Bit bleibt dauerhaft auf \({\color{green}\text{[1, S. 528-539]}}\)

  • Schutzmechanismen: Write-Protection (efuse_wr_disable): verhindert weiteres Programmieren bestimmter Bits. Read-Protection (efuse_rd_disable): schützt sensible Inhalte vor unautorisiertem Auslesen.

Der AES Accelerator unterstützt Hardware-beschleunigte symmetrische Verschlüsselung nach \({\color{green}\text{[1, S. 588-592]}}\):

  • Unterstützte Modi: AES-128, AES-192, AES-256 (jeweils für Verschlüsselung und Entschlüsselung).
  • Funktionsweise:
    • Schlüssel werden in AES_KEY_n_REG abgelegt.
    • Klartext oder Chiffretext in AES_TEXT_m_REG gespeichert.
    • Ergebnisse werden nach Abschluss des Vorgangs automatisch zurückgeschrieben.

Der SHA Accelerator bietet Hardware-Support für kryptografische Hashfunktionen gemäß FIPS PUB 180-4 \({\color{green}\text{[1, S. 594-597]}}\):

  • Unterstützte Algorithmen: SHA-1, SHA-256, SHA-384, SHA-512
  • Funktionsweise:
    • Nachrichtenblöcke (512 bzw. 1024 Bit) werden manuell vorbereitet (Padding erforderlich) und blockweise übergeben.
    • Ergebnisse werden in Registern abgelegt und durch Software weiterverarbeitet.

Der RSA Accelerator realisiert asymmetrische Verschlüsselung durch bignum arithmetic (arbiträre Ganzzahlarithmetik) \({\color{green}\text{[1, S. 603-607]}}\):

  • Funktionen:
    • Modular Exponentiation (Z = X^Y mod M)
    • Modular Multiplication
    • Unterstützung für Bitlängen von 512 bis 4096 Bit
  • Anwendung:
    • RSA-Schlüsseloperationen (z. B. Verifikation digitaler Signaturen)
    • In Kombination mit eFuses für Secure Boot

True Random Number Generator (RNG) basiert auf physikalischem Rauschen (Abb. 4) und erzeugt echte Zufallszahlen (keine Pseudo-RNGs) \({\color{green}\text{[1, S. 609-610]}}\):

  • Einsatzbereiche:
    • Schlüsselgenerierung
    • Challenge-Response-Verfahren
    • Seed-Werte für Kryptooperationen

Abb. 4: Der Zufallszahlengenerator (RNG) nutzt Rauschquellen wie SAR-ADC, High-Speed-ADC und einen RC-Oszillator, um Zufallsbits zu erzeugen. Diese Bits werden durch XOR-Logik kombiniert und anschließend vom Generator zu echten Zufallszahlen verarbeitet, die im Register RNG_DATA_REG ausgegeben werden.

Flash-Verschlüsselung (External Memory Encryption) \({\color{green}\text{(Abb. 5)}}\) Programme und Daten im externen Flash können durch die integrierte Verschlüsselungseinheit geschützt werden \({\color{green}\text{[1, S. 611-614]}}\):

Abb. 5: Die External Memory Encryption/Decryption-Einheit verschlüsselt und entschlüsselt automatisch Daten beim Schreiben und Lesen aus dem externen Flash, basierend auf Schlüsseln, die aus der Speicheradresse generiert werden. Steuerung und Konfiguration erfolgen über Efuse-Einstellungen und DPORT-Register, wodurch ein sicherer Boot- und Betriebsmodus gewährleistet wird.

5.3.2 Energiemanagement

Der ESP32 bietet ein ausgeklügeltes Energiemanagementsystem, das speziell für energieeffiziente Embedded-Anwendungen entwickelt wurde. Dieses basiert auf der RTC-Subsystem-Architektur, die neben stromsparenden GPIOs auch einen eigenen ULP-Coprozessor sowie umfangreiche Low-Power-Management-Funktionen integriert. Diese ermöglichen es, sowohl die Hauptprozessoren als auch andere Peripherien kontrolliert in verschiedene Energiemodi zu versetzen.

RTC IO MUX umfasst 18 GPIO-Pins mit RTC-Funktionalität, die speziell für den Low-Power-Betrieb ausgelegt sind \({\color{green}\text{[1, S. 54]}}\):

  • Retention im Deep-Sleep:
    • Ausgangspegel von RTC-Ausgangspins bleiben im Deep-Sleep erhalten.
    • Eingangspins können das System aus dem Deep-Sleep aufwecken.
  • Anwendung: RTC-GPIOs eignen sich ideal für wake-on-sensor-Anwendungen, z. B. Touchpads oder Umgebungsüberwachung, bei minimalem Stromverbrauch.

Der ULP-Coprozessor \({\color{green}\text{(Abb. 6)}}\) ist ein stromsparender Zusatzprozessor, der auch im Deep-Sleep-Modus aktiv bleiben kann, während die Haupt-CPUs deaktiviert sind \({\color{green}\text{[1, S. 670-688]}}\):

Abb. 6: Die Abbildung zeigt die Architektur des RTC-Subsystems im ESP32, wobei der ULP-Coprozessor (Ultra-Low-Power) zentral eingebunden ist. Er kann selbst mit Sensoren (z. B. TSENS, SAR ADC) und RTC-Komponenten interagieren, ohne dass der Hauptprozessor aktiv sein muss. Über den Arbiter wird der Zugriff auf Speicher, Register und Peripherie geregelt, wobei der ULP selbst im Deep-Sleep-Modus Messungen durchführen und über den RTC Timer das System aufwecken kann.
  • Funktionale Eigenschaften:
    • Bis zu 8 KB RTC Slow Memory für Daten und Programmcode
    • Eigenständiger Zugriff auf RTC-Peripherie, interne Sensoren (z. B. Temperatursensor, ADC) und Register
    • Getaktet mit RTC_FAST_CLK (8 MHz)
    • Vier 16-Bit-Register + 8-Bit-Zählregister für einfache Steuerungslogik
    • Weckfunktion für den Hauptprozessor per Interrupt oder RTC-Timer
  • Anwendung: Ideal für Sensorüberwachung, periodische Messungen, Schwellenwertvergleiche, bei denen der Hauptprozessor nicht benötigt wird – z. B. batteriebetriebene Sensoren, Wearables, IoT-Endpunkte.

Das Modul RTC_CNTL (Low-Power-Management-Architektur) \({\color{green}\text{(Abb. 7)}}\) steuert die Energiezustände des ESP32 und bietet fünf vordefinierte Energiemodi, die zwischen Stromverbrauch, Wecklatenz und Funktionalität abwägen \({\color{green}\text{[1, S. 695-709]}}\):

Abb. 7: Die Abbildung zeigt die Energieversorgungsstruktur des ESP32, bei der der Power Controller im RTC-Bereich zentrale Steuerfunktionen übernimmt. Durch Spannungsregler, Power Switches und Isolation Cells werden unterschiedliche Bereiche wie Digital Core, RTC und Analog Core gezielt mit Energie versorgt oder abgeschaltet. Die flexible Architektur ermöglicht so die Umsetzung der fünf Energiemodi zur Optimierung von Stromverbrauch und Systemreaktivität.
  • Verfügbare Energiemodi:
    1. Active Mode – Volle Funktionalität, höchste Leistungsaufnahme
    2. Modem-sleep – WLAN/Bluetooth deaktiviert, CPU aktiv
    3. Light-sleep – CPU angehalten, Peripherie kann aktiv bleiben
    4. Deep-sleep – Nur RTC und ULP aktiv; <10 µA Verbrauch
    5. Hibernation – Fast vollständiger Stromausfall; nur Wakeup-Logik aktiv
  • Leistungsmerkmale:
    • Retention Memory: Bis zu 16 KB für die Datensicherung zwischen Sleep-Wake-Zyklen
    • Retention Register: 8 × 32-Bit Register für Statusinformationen
    • RTC Boot: Schnelles Aufwachen aus Sleep-Modi durch optimierte Boot-Logik
    • ULP-Unterstützung in allen Energiemodi
  • Architekturkomponenten:
    • Power Controller zur Domänenschaltung
    • Isolation Cells zum Schutz abgeschalteter Bereiche
    • Power Switch Cells zur Trennung von Versorgungsspannungen
    • Voltage Regulators für bedarfsangepasste Versorgung

6 References

  1. ESP32 Technical Reference Manual Version 5.3