ESP32-C3 Mini Tutorial: RISC-V WLAN-Board mit Webserver, BLE & Deep-Sleep
Der ESP32-C3 ist Espressifs Antwort auf die Frage: Wie klein und günstig kann ein vollwertiges WLAN-Board sein? Statt der bekannten Xtensa-Kerne steckt hier ein einzelner 32-Bit-RISC-V-Kern mit 160 MHz, dazu 400 KB SRAM, 4 MB Flash, WiFi und Bluetooth LE 5.0 – auf einer Platine kaum größer als ein USB-Stecker. Damit ist der C3 ideal für smarte Sensoren, IoT-Knötchen und batteriebetriebene Projekte, bei denen jeder Cent und jedes Milliampere zählt. In diesem Tutorial richtest du die Arduino IDE ein, baust einen kompletten WLAN-Webserver mit Live-Werten, zeigst Daten auf einem OLED an, sendest sie per Bluetooth LE und schickst das Board zwischendurch in den Deep-Sleep – für Batterielaufzeiten von Monaten.
Was ist der ESP32-C3 – und was nicht?
Anders als der klassische Dual-Core-ESP32 ist der C3 ein Single-Core-Board auf RISC-V-Basis. Das klingt nach weniger, ist aber für die meisten Sensor- und IoT-Aufgaben mehr als genug – und spart deutlich Strom. RISC-V ist eine offene Befehlssatz-Architektur, weshalb der C3 auch als günstiger, moderner Ersatz für viele ESP8266-Projekte gilt: gleiche Baugröße, aber Bluetooth an Bord und mehr Rechenleistung.
| Merkmal | ESP8266 | ESP32-C3 | ESP32 (Classic) |
|---|---|---|---|
| Kerne | 1x Tensilica, 80 MHz | 1x RISC-V, 160 MHz | 2x Xtensa, 240 MHz |
| SRAM | ~80 KB | 400 KB | 520 KB |
| WiFi | ja | ja | ja |
| Bluetooth | nein | BLE 5.0 | BLE 4.2 + Classic |
| Deep-Sleep-Strom | ~20 µA | ~5 µA | ~10 µA |
ℹ️ Ideal für: smarte Taster, Umweltsensoren, die alle paar Minuten funken, BLE-Beacons, ESPHome-Knötchen im Smart Home. Überall dort, wo du keinen zweiten Kern und keine großen Datenmengen brauchst, ist der C3 die effizienteste und günstigste Wahl.
Was du brauchst
Arduino IDE einrichten
-
1In den Voreinstellungen die Boardverwalter-URL
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.jsoneintragen. - 2Im Boardverwalter esp32 by Espressif Systems (Version 3.x) installieren.
- 3Als Board ESP32C3 Dev Module auswählen.
- 4Wichtig für den seriellen Monitor: USB CDC On Boot: Enabled setzen – sonst bleibt der Monitor stumm, weil der C3 natives USB nutzt.
Verkabelung: OLED und BMP280 am I2C-Bus
Beide Module sprechen I2C und teilen sich zwei Leitungen. Beim C3 sind die I2C-Pins frei wählbar – wir nehmen GPIO 8 (SDA) und GPIO 9 (SCL).
| Modul-Pin | ESP32-C3 | Adresse |
|---|---|---|
| OLED / BMP280 VCC | 3V3 | – |
| OLED / BMP280 GND | GND | – |
| OLED SDA / BMP280 SDA | GPIO 8 | – |
| OLED SCL / BMP280 SCL | GPIO 9 | – |
| OLED | – | 0x3C |
| BMP280 | – | 0x76 (oder 0x77) |
Code 1: I2C-Scanner & Systemcheck
Bevor du Sensoren ausliest, prüfe, ob der C3 sie überhaupt sieht. Dieser Sketch scannt den I2C-Bus und meldet jede gefundene Adresse.
#include <Wire.h>
void setup() {
Serial.begin(115200);
delay(1000);
Wire.begin(8, 9); // SDA = 8, SCL = 9
Serial.println("=== ESP32-C3 I2C-Scanner ===");
}
void loop() {
byte gefunden = 0;
for (byte adr = 1; adr < 127; adr++) {
Wire.beginTransmission(adr);
if (Wire.endTransmission() == 0) {
Serial.printf("Geraet gefunden: 0x%02X\n", adr);
gefunden++;
}
}
if (gefunden == 0) Serial.println("Nichts gefunden - Verkabelung pruefen!");
Serial.println("---");
delay(3000);
}
Erwartet werden 0x3C (OLED) und 0x76 (BMP280). Fehlt eins, stimmt meist die Verkabelung oder die 3,3-V-Versorgung nicht.
Code 2: BMP280 auf dem OLED anzeigen
Jetzt lesen wir Temperatur und Luftdruck aus und zeigen sie auf dem kleinen 128×32-OLED. Installiere die Bibliotheken Adafruit BMP280 Library, Adafruit SSD1306 und Adafruit GFX.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP280.h>
Adafruit_SSD1306 oled(128, 32, &Wire, -1);
Adafruit_BMP280 bmp;
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
if (!bmp.begin(0x76)) {
Serial.println("BMP280 nicht gefunden!");
}
}
void loop() {
float temp = bmp.readTemperature();
float druck = bmp.readPressure() / 100.0F; // hPa
oled.clearDisplay();
oled.setTextColor(SSD1306_WHITE);
oled.setTextSize(1);
oled.setCursor(0, 0);
oled.printf("Temp: %.1f C", temp);
oled.setCursor(0, 16);
oled.printf("Druck: %.0f hPa", druck);
oled.display();
delay(1000);
}
Code 3: WLAN-Webserver mit Live-Werten
Das Highlight jedes ESP-Boards: eine kleine Webseite, die du im Browser aufrufst und die die aktuellen Sensorwerte zeigt – mit automatischem Neuladen alle 5 Sekunden. Trage deine WLAN-Zugangsdaten ein und öffne nach dem Start die IP-Adresse, die im seriellen Monitor erscheint.
#include <WiFi.h>
#include <WebServer.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>
const char* ssid = "DEIN_WLAN";
const char* passwort = "DEIN_PASSWORT";
WebServer server(80);
Adafruit_BMP280 bmp;
void seiteSenden() {
float temp = bmp.readTemperature();
float druck = bmp.readPressure() / 100.0F;
String html = "<!DOCTYPE html><html><head>";
html += "<meta charset='utf-8'><meta http-equiv='refresh' content='5'>";
html += "<title>ESP32-C3</title></head><body>";
html += "<h1>ESP32-C3 Sensor</h1>";
html += "<p>Temperatur: " + String(temp, 1) + " C</p>";
html += "<p>Luftdruck: " + String(druck, 0) + " hPa</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
bmp.begin(0x76);
WiFi.begin(ssid, passwort);
Serial.print("Verbinde");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("IP-Adresse: ");
Serial.println(WiFi.localIP());
server.on("/", seiteSenden);
server.begin();
}
void loop() {
server.handleClient();
}
ℹ️ Tipp: Rufst du http://<IP>/ vom Handy im selben WLAN auf, hast du ein Mini-Dashboard für unterwegs. Für schönere Optik kannst du CSS direkt in den HTML-String packen – der C3 hat genug RAM dafür.
Code 4: Bluetooth LE – Sensorwert als BLE-Charakteristik
Der C3 kann Werte auch drahtlos per Bluetooth LE bereitstellen – ideal, wenn kein WLAN in der Nähe ist. Dieser Sketch legt einen BLE-Server mit einer Temperatur-Charakteristik an, die du mit jeder BLE-Scanner-App (z. B. nRF Connect) auslesen kannst.
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>
#define SERVICE_UUID "181A" // Environmental Sensing
#define CHAR_UUID "2A6E" // Temperature
Adafruit_BMP280 bmp;
BLECharacteristic* tempChar;
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
bmp.begin(0x76);
BLEDevice::init("MAKEROO-C3");
BLEServer* server = BLEDevice::createServer();
BLEService* service = server->createService(SERVICE_UUID);
tempChar = service->createCharacteristic(
CHAR_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
service->start();
BLEAdvertising* adv = BLEDevice::getAdvertising();
adv->addServiceUUID(SERVICE_UUID);
BLEDevice::startAdvertising();
Serial.println("BLE aktiv - suche 'MAKEROO-C3'");
}
void loop() {
int16_t temp = (int16_t)(bmp.readTemperature() * 100); // 0,01-C-Schritte
tempChar->setValue((uint8_t*)&temp, 2);
tempChar->notify();
delay(2000);
}
Code 5: Deep-Sleep – Monate mit einer Batterie
Für batteriebetriebene Sensoren ist Deep-Sleep der Schlüssel: Der C3 misst, funkt kurz und schläft dann mit rund 5 µA für eine festgelegte Zeit. Dieser Sketch wacht alle 60 Sekunden auf, macht eine Messung und legt sich wieder hin.
#include <Wire.h>
#include <Adafruit_BMP280.h>
#define SCHLAF_SEKUNDEN 60
#define uS_PRO_SEKUNDE 1000000ULL
Adafruit_BMP280 bmp;
void setup() {
Serial.begin(115200);
delay(300);
Wire.begin(8, 9);
bmp.begin(0x76);
float temp = bmp.readTemperature();
Serial.printf("Messung: %.1f C\n", temp);
// Hier koenntest du den Wert per WiFi/BLE senden ...
Serial.println("Gehe schlafen ...");
esp_sleep_enable_timer_wakeup(SCHLAF_SEKUNDEN * uS_PRO_SEKUNDE);
esp_deep_sleep_start(); // ab hier laeuft setup() beim Aufwachen neu
}
void loop() {
// wird nie erreicht - nach dem Aufwachen startet setup() erneut
}
⚠️ Deep-Sleep verstehen: Nach esp_deep_sleep_start() wird das Board praktisch neu gestartet – loop() läuft nicht weiter, sondern setup() beginnt beim Aufwachen von vorn. Werte, die du über den Schlaf retten willst, gehören in eine RTC_DATA_ATTR-Variable, die den Deep-Sleep überlebt.
Praxistipps
🔋 Echte Batterielaufzeit: Miss den Ruhestrom deines konkreten Boards – On-Board-LEDs und Spannungsregler verbrauchen oft mehr als der Chip selbst. Für Monatslaufzeiten lohnt sich ein Board mit sparsamem Regler und das Deaktivieren der Power-LED.
📡 WiFi kostet Strom: Der Verbindungsaufbau ist der teuerste Moment. Sammle mehrere Messungen und funke sie gebündelt, statt bei jeder einzelnen Messung neu zu verbinden.
🏷️ Pin-Beschriftung: C3-Mini-Boards verschiedener Hersteller haben leicht unterschiedliche Pin-Belegungen. Richte dich immer nach dem aufgedruckten GPIO, nicht nach der Position.
Troubleshooting
⚠️ Serieller Monitor bleibt leer: USB CDC On Boot: Enabled setzen. Der C3 nutzt natives USB – ohne diese Option siehst du keine Ausgaben.
⚠️ Upload schlägt fehl: Board in den Download-Modus zwingen: BOOT gedrückt halten, kurz RESET tippen, dann BOOT loslassen und erneut hochladen.
⚠️ I2C-Geräte nicht gefunden: Prüfe, ob Wire.begin(8, 9) zu deinen Pins passt, und ob VCC wirklich an 3V3 (nicht 5V) hängt. Der BMP280 antwortet je nach Modul auf 0x76 oder 0x77.
⚠️ WLAN verbindet nicht: Der C3 funkt nur im 2,4-GHz-Band. Ein reines 5-GHz-Netz sieht er nicht – im Router ggf. ein 2,4-GHz-SSID aktivieren.
🚀 Bauteile für dein C3-Projekt
Alles aus diesem Tutorial gibt es bei MAKEROO:
Fazit
Der ESP32-C3 beweist, dass „klein und günstig“ nicht „wenig“ bedeuten muss: ein RISC-V-Kern mit 160 MHz, WLAN, Bluetooth LE und ein Deep-Sleep, der batteriebetriebene Sensoren monatelang laufen lässt. Mit den fünf Sketches dieses Tutorials hast du die gesamte IoT-Bandbreite abgedeckt – vom I2C-Sensor über das OLED-Display und den Webserver bis zu Bluetooth und Energiesparmodus. Genau das macht den C3 zum idealen Baustein für smarte, verteilte Projekte: klein genug, um überall zu verschwinden, und clever genug, um trotzdem alles Wichtige zu funken.