Bauteile · 13 Min. Lesezeit

ESP32-CAM Anleitung: Programmieren, Livestream und SD-Karte

ESP32-CAM programmieren: AI-Thinker-Pinout, Upload mit ESP32-CAM-MB oder USB-TTL, CameraWebServer, PSRAM, Fehler 0x105 und Brownout, Blitz-LED, SD-Karte.

Die ESP32-CAM ist ein günstiges WLAN-Kameramodul, das trotz seiner Größe von nur 27 × 40 mm einen ESP32-Prozessor, eine 2-Megapixel-Kamera OV2640, einen microSD-Kartenslot und eine weiße Blitz-LED mitbringt. Ganz allein verbindet sie sich mit deinem Heimnetz, streamt Live-Bilder in den Browser, macht Fotos und speichert sie auf der SD-Karte oder schickt sie ins Internet. Sie ist das beliebteste Board für Überwachungskameras, Türklingelkameras, Zeitraffer vom Pflanzenwachstum und Roboterautos mit Kamera. Weil sie aber keine USB-Buchse hat, läuft der Einstieg etwas anders als bei den ESP32-Boards, die du vielleicht schon kennst.

In dieser Anleitung lernst du die Pinbelegung der AI-Thinker ESP32-CAM kennen, erfährst, wie du sie mit dem ESP32-CAM-MB-Adapter oder einem USB-TTL-Adapter programmierst (inklusive der Verbindung IO0-GND), wie du mit dem fertigen Beispiel CameraWebServer ein Live-Bild im Browser bekommst und welche PSRAM- und Partitionseinstellungen richtig sind. Danach siehst du die Ursachen der häufigsten Fehler Camera init failed with error 0x105 und Brownout, steuerst die Blitz-LED und baust einen Sketch, der per Tastendruck ein Foto auf der microSD-Karte speichert.

AI-Thinker ESP32-CAM Kameramodul
ESP32-CAM: ESP32-S-Modul, Kamera OV2640, microSD-Slot und Blitz-LED auf einer Platine. Eine USB-Buchse fehlt, zum Programmieren brauchst du einen Adapter.

Was ist die ESP32-CAM und wie funktioniert sie?

Das Herz der Platine ist das ESP32-S-Modul mit dem Dual-Core-Chip ESP32, der WLAN und Bluetooth an Bord hat. Die Kamera steckt über ein dünnes Flachbandkabel (FPC) in einem 24-poligen Stecker auf der Platine. Der ESP32 schickt der Kamera über GPIO 0 ein Taktsignal mit 20 MHz (XCLK) und konfiguriert sie über den I2C-ähnlichen SCCB-Bus an GPIO 26 und 27. Da der OV2640-Sensor das Bild selbst als JPEG komprimieren kann, bekommt der ESP32 statt roher Pixel kleine JPEG-Bilder. Diese gelangen über einen parallelen 8-Bit-Datenbus in den 4 MB großen PSRAM der Platine, und das WLAN bringt sie weiter zum Browser oder zu einem Server.

MerkmalWert
ProzessorESP32 (ESP32-S-Modul), Dual-Core, bis 240 MHz
FunkWLAN 802.11 b/g/n (nur 2,4 GHz), Bluetooth 4.2 und BLE
Speicher520 KB internes SRAM + 4 MB PSRAM, 4 MB Flash
KameraOV2640, 2 MP, bis 1600×1200 (UXGA), JPEG-Ausgabe
SpeicherkartemicroSD-Slot (laut offizieller Doku bis 4 GB)
LichtWeiße Blitz-LED (GPIO 4), rote Status-LED auf der Rückseite (GPIO 33)
Versorgung5 V am Pin 5V (empfohlen) oder 3,3 V am Pin 3V3
Strom (bei 5 V)Ohne Blitz etwa 180 mA, mit voller Blitzhelligkeit etwa 310 mA; WLAN-Spitzen liegen höher
Größe27 × 40,5 × 4,5 mm

ESP32-CAM Pinbelegung (AI-Thinker): welche Pins sind frei?

An den beiden Rändern der Platine sitzen 16 Pins, aber nur wenige davon sind wirklich frei: Die Kamera belegt allein 15 GPIOs, der microSD-Slot teilt sich sechs weitere. Die Tabelle fasst die Randpins zusammen und zeigt, wann du sie nutzen kannst. Die allgemeinen Pin-Eigenschaften des ESP32 findest du auch im Tool Pinout.

PinFunktionFrei nutzbar?
5VSpannungseingang (empfohlen)-
3V3Spannungseingang 3,3 V-
GND (3 Stück)Masse-
VCCSpannungsausgang (standardmäßig 3,3 V)Nicht zur Versorgung der Platine verwenden
U0R (GPIO 3)Serielles RX: Programmieren und Serieller MonitorNur ohne serielle Schnittstelle
U0T (GPIO 1)Serielles TX: Programmieren und Serieller MonitorNur ohne serielle Schnittstelle
GPIO 0Kameratakt (XCLK) und Boot-ModusNein; nur beim Hochladen mit GND verbinden
GPIO 16Bei vielen Platinen mit dem PSRAM verbundenNein
GPIO 2SD DATA0Wenn keine SD-Karte genutzt wird; Strapping-Pin
GPIO 4SD DATA1 und Blitz-LEDIm SD-1-Bit-Modus oder ohne SD
GPIO 12SD DATA2Im SD-1-Bit-Modus oder ohne SD; beim Booten LOW
GPIO 13SD DATA3Im SD-1-Bit-Modus oder ohne SD; der sicherste freie Pin
GPIO 14SD CLKWenn keine SD-Karte genutzt wird
GPIO 15SD CMDWenn keine SD-Karte genutzt wird; Strapping-Pin
GPIO 33Rote LED (nicht am Rand)Nur LED; LOW schaltet sie ein
Der Pin VCC ist kein Eingang, sondern der Ausgang des Spannungsreglers auf der Platine und liefert standardmäßig 3,3 V. Legst du hier 5 V an, ziehst du die 3,3-V-Schiene direkt auf 5 V und kannst den ESP32 zerstören; speise die Spannung deshalb immer am Pin 5V ein. Ist außerdem GPIO 12 beim Start HIGH, versucht der ESP32, den Flash mit 1,8 V zu betreiben, und die Platine startet nicht. Schließe an diesen Pin also keinen Pull-up-Widerstand und kein Modul an, das ihn auf HIGH zieht.

ESP32-CAM programmieren: zwei Wege

Der USB-Seriell-Chip, über den normale ESP32-Boards mit dem Computer sprechen, fehlt auf der ESP32-CAM. Zum Hochladen hast du zwei Möglichkeiten: den ESP32-CAM-MB-Adapter, der unter die Platine gesteckt wird (eine kleine Grundplatine mit CH340-Chip und Micro-USB-Buchse), oder einen vorhandenen USB-TTL-Adapter (FTDI, CH340, CP2102). Das Prinzip ist bei beiden gleich: Ist GPIO 0 beim Start LOW, geht der ESP32 in den Download-Modus und wartet auf Code; ist er HIGH, startet er das Programm im Flash. Genau das erledigen der Taster IO0 auf dem MB-Adapter und die Drahtbrücke IO0-GND beim USB-TTL-Adapter.

CP2102 USB-TTL-Adapter
CP2102 USB-TTL-Adapter: Zum Programmieren der ESP32-CAM reichen die Pins GND, 5V, TX und RX.
USB-TTL-AdapterESP32-CAMHinweis
GNDGNDGemeinsame Masse
5V5VVersorgt die Platine; der 3,3-V-Ausgang des Adapters reicht nicht
TXU0R (GPIO 3)Gekreuzt: Sender an Empfänger
RXU0T (GPIO 1)Gekreuzt: Empfänger an Sender
-Zwischen IO0 und GNDNur beim Hochladen; kurze Brücke zwischen den beiden benachbarten Pins

Hat dein Adapter einen Jumper zur Wahl zwischen 3,3 V und 5 V, stelle ihn auf 3,3 V, damit die TX-Leitung einen Pegel hat, der zu den Pins des ESP32 passt. Die Versorgung der Platine nimmst du aber vom Pin 5V des Adapters. Der 3,3-V-Ausgang der meisten Adapter liefert nur etwa 50–100 mA; sobald die ESP32-CAM das WLAN einschaltet, bricht diese Spannung ein und die Platine startet neu.

Einstellungen in der Arduino IDE: Board, Partitionsschema und PSRAM

  1. Öffne in der Arduino IDE den Boardverwalter und installiere das Paket esp32 by Espressif Systems; ausführlich erklärt im Beitrag Arduino IDE installieren.
  2. Wähle unter Werkzeuge > Board > esp32 das Board AI Thinker ESP32-CAM.
  3. Achte darauf, dass Partition Scheme auf Huge APP (3MB No OTA/1MB SPIFFS) steht; das Kamerabeispiel braucht mindestens 3 MB Programmspeicher.
  4. Verbinde die Platine mit dem Adapter und wähle unter Werkzeuge > Port den neu erscheinenden Port (unter Windows COMx, unter macOS /dev/cu.usbserial... oder /dev/cu.wchusbserial...).
  5. Erscheint gar kein Port, installiere den Treiber für CH340 oder CP2102 und nimm ein USB-Kabel mit Datenleitungen.
EinstellungEmpfohlener WertWarum?
BoardAI Thinker ESP32-CAMPSRAM, 4 MB Flash und passendes Partitionsschema sind voreingestellt
Partition SchemeHuge APP (3MB No OTA/1MB SPIFFS)Die 3 MB Programmspeicher, die CameraWebServer braucht
PSRAMBei diesem Board immer aktivBei ESP32 Dev Module PSRAM: Enabled wählen; bei ESP32 Wrover Module schon aktiv
CPU Frequency240MHz (WiFi/BT)Höchste Geschwindigkeit für Bildübertragung und WLAN
Flash Mode / Flash FrequencyQIO / 80MHzBei Upload- oder Startproblemen DIO / 40MHz testen
Core Debug LevelNone (zur Fehlersuche Info)Bei Info erscheinen Kamera- und FPS-Infos im seriellen Monitor
Upload Speed460800 (bei diesem Board fest)Bricht der Upload oft ab, ESP32 Wrover Module mit 115200 testen
Öffne den seriellen Monitor immer mit 115200 Baud. Startmeldungen kommen nur im Moment eines Resets; ist das Fenster leer, drücke den Taster RST auf der Platine. Steht dort waiting for download, ist IO0 noch mit GND verbunden; entferne die Brücke, drücke erneut RST, und dein Programm läuft los.

Der erste Upload Schritt für Schritt

  1. Verkabeln: Stecke die Platine mit ausgerichteten Pins auf den MB-Adapter oder schließe den USB-TTL-Adapter wie in der Tabelle oben an. Beim USB-TTL-Adapter setzt du zusätzlich die kurze Brücke zwischen IO0 und GND.
  2. Platine in den Download-Modus bringen: Halte am MB-Adapter den Taster IO0 gedrückt, drücke kurz RST und lass dann IO0 los. Beim USB-TTL-Adapter genügt ein Druck auf RST, während die Brücke IO0-GND steckt. Manche MB-Adapter mit Auto-Reset-Schaltung laden auch ganz ohne Tastendruck hoch.
  3. Klicke in der Arduino IDE auf Hochladen. In der Ausgabe erscheint zuerst Connecting... und danach der Schreibfortschritt in Prozent.
  4. Sobald die Zeile Hard resetting via RTS pin... erscheint, ist der Upload fertig. Beim USB-TTL-Adapter ziehst du jetzt die Brücke IO0-GND ab.
  5. Öffne den seriellen Monitor mit 115200 Baud und drücke RST; das neue Programm startet.
Arduino (C++)
1// ESP32-CAM ilk yükleme testi / ESP32-CAM first upload test
2const int KIRMIZI_LED = 33;   // arkadaki kırmızı LED, ters mantık / red LED on the back, inverted logic
3
4void setup() {
5  Serial.begin(115200);
6  pinMode(KIRMIZI_LED, OUTPUT);
7  delay(500);
8
9  // PSRAM kontrolü / PSRAM check
10  if (psramFound()) {
11    Serial.print("PSRAM bulundu / PSRAM found: ");
12    Serial.print(ESP.getPsramSize());
13    Serial.println(" bayt / bytes");
14  } else {
15    Serial.println("PSRAM yok / No PSRAM");
16  }
17}
18
19void loop() {
20  digitalWrite(KIRMIZI_LED, LOW);    // LOW = yanar / LOW = on
21  delay(500);
22  digitalWrite(KIRMIZI_LED, HIGH);   // HIGH = söner / HIGH = off
23  delay(500);
24}

Hat der Upload geklappt, blinkt die kleine rote LED auf der Rückseite im Halbsekundentakt. Diese LED arbeitet mit invertierter Logik: LOW schaltet sie ein, HIGH aus. Im seriellen Monitor solltest du rund 4 Millionen Byte PSRAM sehen; steht dort No PSRAM, prüfe die Boardauswahl, und wenn das nicht hilft, hat deine Platine womöglich keinen PSRAM-Chip. Wenn du diesen kurzen Test vor dem Kamerabeispiel machst, weißt du sofort, ob ein Problem beim Upload oder bei der Kamera liegt.

Das Beispiel CameraWebServer: Live-Bild im Browser

  1. Öffne Datei > Beispiele > ESP32 > Camera > CameraWebServer.
  2. Kameramodell wählen: In der Liste im Tab board_config.h (neuere Versionen) bzw. am Anfang der Hauptdatei (ältere Versionen) setzt du // vor die Zeile CAMERA_MODEL_ESP_EYE und entfernst die // vor CAMERA_MODEL_AI_THINKER.
  3. Trage in die Zeilen ssid und password Namen und Passwort deines 2,4-GHz-WLANs ein.
  4. Bring die Platine in den Download-Modus und lade den Sketch hoch; entferne danach die IO0-Verbindung und drücke RST.
  5. Im seriellen Monitor erscheint eine Zeile wie Camera Ready! Use 'http://192.168.1.45' to connect; öffne diese Adresse im Browser eines Handys oder Computers im selben Netz.
  6. Starte das Live-Bild mit dem Button Start Stream oder mach mit Get Still ein einzelnes Foto.
Arduino (C++)
1// board_config.h (eski sürümlerde CameraWebServer.ino) / (CameraWebServer.ino in older versions)
2//#define CAMERA_MODEL_ESP_EYE      // Has PSRAM  <- kapat / comment out
3#define CAMERA_MODEL_AI_THINKER     // Has PSRAM  <- aç / enable
4
5// CameraWebServer.ino
6const char *ssid = "AgAdi";          // Wi-Fi adı / Wi-Fi name
7const char *password = "Sifre123";   // Wi-Fi şifresi / Wi-Fi password

Die Oberfläche läuft auf zwei getrennten Servern: Die Einstellungsseite und die Adresse /capture, die ein Einzelfoto liefert, liegen auf Port 80, der Livestream unter /stream auf Port 81 (z. B. http://192.168.1.45:81/stream). Diese Stream-Adresse kannst du in deine eigene Webseite oder in eine Hausautomations-Software einbinden. Im linken Menü änderst du Auflösung, JPEG-Qualität, Helligkeit, Kontrast und Weißabgleich; steht das Bild auf dem Kopf, helfen die Schalter V-Flip und H-Mirror, und neuere Versionen haben zusätzlich einen Regler LED Intensity für den Blitz. Die Platine bedient meist nur einen Stream-Zuschauer gleichzeitig; ein Stream in einem zweiten Tab kann einfrieren. Öffnet sich die Seite gar nicht, prüfe, ob Handy und Platine im selben Netz sind; bei Verbindungsproblemen hilft der Beitrag ESP32 verbindet sich nicht mit dem WLAN.

ESP32-CAM Auflösung und FPS: Übersicht

Auf dem Papier schafft der OV2640-Sensor 15 Bilder pro Sekunde bei 1600×1200, 30 bei 800×600 und 60 in CIF-Größe. In der Praxis bestimmen vor allem die WLAN-Verbindung und die Größe der JPEG-Bilder die Bildrate: Mit steigender Auflösung und Qualität wird jedes Bild größer und braucht länger durchs Netz. Die Werte unten sind ungefähre Bereiche mit CameraWebServer bei gutem WLAN-Signal und JPEG-Qualität 10–12. Um deine eigene Platine zu messen, stelle Core Debug Level auf Info; während des Streams schreibt der serielle Monitor für jedes Bild eine Zeile wie MJPG: ... (x fps).

AuflösungPixelCa. FPS (WLAN-Stream)Geeignet für
QQVGA160×12025–30Bewegungserkennung, sehr schwaches Netz
QVGA320×24020–30Roboterauto, flüssiges Livebild
CIF400×29615–25Flüssige Anzeige auf kleinen Bildschirmen
VGA640×48010–20Livebild für alle Zwecke
SVGA800×6008–15Schärferes Bild; größte Auflösung ohne PSRAM
XGA1024×7685–10Detaillierte Bilder
HD1280×7204–8Breiter Bildausschnitt (16:9)
SXGA1280×10243–6Fotos
UXGA1600×12002–5Fotos in höchster Auflösung

In deinem eigenen Code änderst du Auflösung, Qualität und Bildausrichtung über das Sensor-Objekt, sobald die Kamera erfolgreich gestartet ist. Die JPEG-Qualität ist eine Zahl von 0 bis 63, und eine kleinere Zahl bedeutet höhere Qualität; unter 10 werden die Bilder größer und können unvollständig ankommen.

Arduino (C++)
1// esp_camera_init() başarılı olduktan sonra / after esp_camera_init() succeeds
2sensor_t *s = esp_camera_sensor_get();
3s->set_framesize(s, FRAMESIZE_VGA);   // 640x480 çözünürlük / resolution
4s->set_quality(s, 12);                // 0-63: küçük = daha kaliteli, 10 altı önerilmez / lower = better, below 10 not advised
5s->set_vflip(s, 1);                   // görüntüyü dikey çevir / flip vertically
6s->set_hmirror(s, 1);                 // yatay ayna / mirror horizontally
7s->set_brightness(s, 1);              // parlaklık -2..2 / brightness -2..2

Warum ist die PSRAM-Einstellung der ESP32-CAM so wichtig?

Der interne Speicher des ESP32 umfasst 520 KB, und ein großer Teil davon geht an den WLAN-Stack. Ein einzelnes JPEG-Bild mit 1600×1200 kann dagegen je nach Motiv und Qualität 100–250 KB groß sein. Deshalb legt der Kameratreiber seine Bildpuffer (Frame Buffer) im PSRAM ab. CameraWebServer prüft mit der Funktion psramFound(), ob PSRAM vorhanden ist: Wenn ja, startet es mit der höchsten Auflösung und zwei Bildpuffern, wenn nein, begrenzt es die Auflösung auf SVGA (800×600) und legt einen einzigen Puffer in den internen Speicher.

Forderst du ohne aktiven PSRAM eine hohe Auflösung an, zeigt der serielle Monitor frame buffer malloc failed und danach Camera init failed with error 0xffffffff. Die Lösung: Wähle AI Thinker ESP32-CAM als Board (bei ESP32 Dev Module Werkzeuge > PSRAM: Enabled) oder senke die Auflösung und reduziere die Zahl der Bildpuffer auf 1. Bei manchen billigen Nachbauten fehlt der PSRAM-Chip ganz; die PSRAM-Zeile im ersten Test-Sketch zeigt das sofort.

Camera init failed with error 0x105 und andere Kamerafehler

Die meisten Kamerafehler haben eine von drei Ursachen: das falsche Kameramodell im Code, ein Flachbandkabel, das nicht richtig im Stecker sitzt, oder eine unzureichende Stromversorgung. Der Fehlercode im seriellen Monitor grenzt die Ursache schnell ein:

Meldung im seriellen MonitorBedeutungLösung
Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND)Der ESP32 hat am SCCB-Bus keine Kamera gefundenPrüfen, ob CAMERA_MODEL_AI_THINKER aktiv ist, Flachbandkabel neu einstecken, mit 5 V / 2 A versorgen
Detected camera not supported und 0x106Dieselbe Situation in neueren Treiberversionen: keine Kamera gefunden oder erkanntWie bei 0x105; hilft das nicht, Kameramodul tauschen
frame buffer malloc failed und 0xffffffffSpeicher für den Bildpuffer konnte nicht reserviert werdenPSRAM aktivieren, Auflösung senken, fb_count auf 1 setzen
cam_hal: EV-VSYNC-OVF oder FB-OVFEin neues Bild kam, bevor das vorige verarbeitet war; ein Bild wurde übersprungenGelegentlich harmlos; bei Häufung Auflösung senken und WLAN-Signal verbessern
NO-SOI (JPEG start marker missing)Defektes oder unvollständiges JPEG-BildStromversorgung und Flachbandkabel prüfen, xclk_freq_hz auf 10000000 setzen
Bild halb, grün oder gestreiftDas Bild passte nicht in den Puffer oder die Versorgung ist verrauschtJPEG-Qualitätswert auf 12 oder höher setzen, Stromversorgung verbessern
Hebe beim Einstecken des Flachbandkabels die schwarze Verriegelung des Steckers an, schiebe das Kabel gerade bis zum Anschlag hinein und klappe die Verriegelung wieder zu. Stecke die Kamera nie bei eingeschalteter Platine ein oder aus; Kamera und ESP32 können dabei Schaden nehmen. Denk auch daran, bei einem neuen Kameramodul die Schutzfolie vom Objektiv abzuziehen, sonst wirkt das Bild unscharf.

Brownout-Fehler und die richtige Stromversorgung (5 V / 2 A)

Zeigt der serielle Monitor Brownout detector was triggered und startet die Platine ständig neu, ist die Versorgungsspannung des ESP32 kurz unter einen sicheren Wert gefallen. Die ESP32-CAM zieht kurze, aber hohe Stromspitzen, sobald sie den WLAN-Sender einschaltet und die Kamera Bilder aufnimmt. Ein schwacher USB-Port, dünne und lange Jumperkabel oder der 3,3-V-Ausgang des Adapters kommen mit diesen Spitzen nicht mit. Das hilft dauerhaft:

  • Nimm ein Netzteil mit 5 V und mindestens 2 A und schließe es am Pin 5V an; der Spannungsregler auf der Platine macht daraus 3,3 V.
  • Halte die Versorgungsleitungen kurz und dick; Steckbrett und lange Jumperkabel erhöhen den Spannungsabfall.
  • Setze einen 470–1000 µF-Elko möglichst nah an der Platine zwischen 5V und GND (Pluspol an 5V).
  • Versorgst du sie über den Computer, stecke sie direkt in einen Port auf der Rückseite statt in einen USB-Hub.
  • Für Akkubetrieb nimm eine 18650-Zelle mit einem 5-V-Aufwärtswandler (Boost-Modul); das ist viel stabiler als in Reihe geschaltete AA-Batterien.
18650 Li-Ionen-Akku
18650 Li-Ionen-Akku: Zusammen mit einem 5-V-Aufwärtswandler versorgt er akkubetriebene ESP32-CAM-Projekte stabil.

Im Netz stößt du oft auf die Zeile WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0), die den Brownout-Detektor per Code abschaltet. Sie stoppt die Neustarts, löst aber das Problem nicht: Die Spannung bricht weiterhin ein, und die Platine kann nun einfrieren, kaputte Bilder liefern oder beim Schreiben in den Flash Daten verlieren. Nutze sie nur für einen kurzen Test; alle Neustart-Meldungen erklärt der Beitrag ESP32 Brownout und Guru Meditation. Für die Akkulaufzeit rechnest du mit durchschnittlich 180 mA im Dauerstream: Ein 18650-Akku mit 2600 mAh ergibt mit einem Aufwärtswandler mit 85 % Wirkungsgrad etwa 1600 mAh auf der 5-V-Seite, also rund 9 Stunden Stream. Deine eigenen Werte berechnest du mit dem Akkulaufzeit-Rechner; denk daran, dass die Platine selbst im Deep Sleep wegen Spannungsregler und PSRAM etwa 6 mA zieht.

Die Blitz-LED (GPIO 4) steuern

Die helle weiße LED auf der Vorderseite wird über einen Transistor an GPIO 4 angesteuert: Der Pin schaltet nur den Transistor, der hohe LED-Strom kommt aus der Versorgung. digitalWrite(4, HIGH) schaltet sie ein, LOW aus. Die LED ist sehr hell, und bleibt sie lange an, werden LED und Platine warm; am besten lässt du den Blitz nur für ein paar hundert Millisekunden beim Fotografieren leuchten. GPIO 4 ist zugleich die Leitung DATA1 der microSD-Karte, deshalb blitzt die LED im 4-Bit-Modus bei jedem Lesen und Schreiben von selbst. Um das zu verhindern, startest du die SD-Karte im 1-Bit-Modus (SD_MMC.begin("/sdcard", true)); bei manchen Platinen glimmt die LED trotzdem ganz schwach.

ESP32-CAM: Fotos auf der microSD-Karte speichern

Der folgende Sketch schaltet bei jedem Druck auf einen Taster an GPIO 13 den Blitz ein, macht ein Foto mit 1600×1200 und speichert es als foto1.jpg, foto2.jpg... auf der microSD-Karte. Formatiere die Karte am Computer mit FAT32; die offizielle Doku nennt zwar Karten bis 4 GB, in der Praxis laufen aber meist auch FAT32-Karten mit 16–32 GB problemlos. Schließe ein Bein des Tasters an GPIO 13 und das andere an GND an; der Sketch aktiviert den internen Pull-up-Widerstand, ein zusätzlicher Widerstand ist also nicht nötig. Wie das Anschließen eines Tasters funktioniert, liest du im Beitrag Taster am Arduino anschließen.

Arduino (C++)
1#include "esp_camera.h"
2#include "FS.h"
3#include "SD_MMC.h"
4
5// AI-Thinker ESP32-CAM kamera pinleri / AI-Thinker ESP32-CAM camera pins
6#define PWDN_GPIO_NUM     32
7#define RESET_GPIO_NUM    -1
8#define XCLK_GPIO_NUM      0
9#define SIOD_GPIO_NUM     26
10#define SIOC_GPIO_NUM     27
11#define Y9_GPIO_NUM       35
12#define Y8_GPIO_NUM       34
13#define Y7_GPIO_NUM       39
14#define Y6_GPIO_NUM       36
15#define Y5_GPIO_NUM       21
16#define Y4_GPIO_NUM       19
17#define Y3_GPIO_NUM       18
18#define Y2_GPIO_NUM        5
19#define VSYNC_GPIO_NUM    25
20#define HREF_GPIO_NUM     23
21#define PCLK_GPIO_NUM     22
22
23#define FLAS_LED  4    // beyaz flaş LED'i / white flash LED
24#define BUTON    13    // butonun diğer ucu GND'de / other button leg to GND
25
26int fotoNo = 1;        // sıradaki dosya numarası / next file number
27bool hazir = false;    // kamera ve SD hazır mı? / are camera and SD ready?
28
29bool kameraBaslat() {
30  camera_config_t config = {};
31  config.ledc_channel = LEDC_CHANNEL_0;
32  config.ledc_timer   = LEDC_TIMER_0;
33  config.pin_d0 = Y2_GPIO_NUM;
34  config.pin_d1 = Y3_GPIO_NUM;
35  config.pin_d2 = Y4_GPIO_NUM;
36  config.pin_d3 = Y5_GPIO_NUM;
37  config.pin_d4 = Y6_GPIO_NUM;
38  config.pin_d5 = Y7_GPIO_NUM;
39  config.pin_d6 = Y8_GPIO_NUM;
40  config.pin_d7 = Y9_GPIO_NUM;
41  config.pin_xclk     = XCLK_GPIO_NUM;
42  config.pin_pclk     = PCLK_GPIO_NUM;
43  config.pin_vsync    = VSYNC_GPIO_NUM;
44  config.pin_href     = HREF_GPIO_NUM;
45  config.pin_sccb_sda = SIOD_GPIO_NUM;
46  config.pin_sccb_scl = SIOC_GPIO_NUM;
47  config.pin_pwdn     = PWDN_GPIO_NUM;
48  config.pin_reset    = RESET_GPIO_NUM;
49  config.xclk_freq_hz = 20000000;           // 20 MHz kamera saati / 20 MHz camera clock
50  config.pixel_format = PIXFORMAT_JPEG;
51
52  if (psramFound()) {
53    config.frame_size   = FRAMESIZE_UXGA;   // 1600x1200
54    config.jpeg_quality = 10;               // küçük = daha kaliteli / lower = better quality
55    config.fb_count     = 2;
56    config.fb_location  = CAMERA_FB_IN_PSRAM;
57    config.grab_mode    = CAMERA_GRAB_LATEST;
58  } else {
59    config.frame_size   = FRAMESIZE_SVGA;   // PSRAM yoksa 800x600 / 800x600 without PSRAM
60    config.jpeg_quality = 12;
61    config.fb_count     = 1;
62    config.fb_location  = CAMERA_FB_IN_DRAM;
63    config.grab_mode    = CAMERA_GRAB_WHEN_EMPTY;
64  }
65
66  esp_err_t err = esp_camera_init(&config);
67  if (err != ESP_OK) {
68    Serial.printf("Camera init failed 0x%x (%s)\n", err, esp_err_to_name(err));
69    return false;
70  }
71  return true;
72}
73
74void fotoCek() {
75  digitalWrite(FLAS_LED, HIGH);              // flaşı yak / flash on
76  delay(150);                                // pozlama otursun / let exposure settle
77
78  camera_fb_t *fb = esp_camera_fb_get();     // eski kareyi at / discard the stale frame
79  if (fb) esp_camera_fb_return(fb);
80  fb = esp_camera_fb_get();                  // asıl fotoğraf / the real photo
81  digitalWrite(FLAS_LED, LOW);               // flaşı söndür / flash off
82
83  if (!fb) {
84    Serial.println("Kare alinamadi / Capture failed");
85    return;
86  }
87
88  String yol = "/foto" + String(fotoNo) + ".jpg";
89  File dosya = SD_MMC.open(yol, FILE_WRITE);
90  if (dosya) {
91    dosya.write(fb->buf, fb->len);           // JPEG verisini yaz / write the JPEG data
92    dosya.close();
93    Serial.printf("Kaydedildi / Saved: %s (%u bayt / bytes)\n", yol.c_str(), (unsigned)fb->len);
94    fotoNo++;
95  } else {
96    Serial.println("Dosya acilamadi / Could not open file");
97  }
98  esp_camera_fb_return(fb);                  // tamponu geri ver / return the buffer
99}
100
101void setup() {
102  Serial.begin(115200);
103  pinMode(BUTON, INPUT_PULLUP);
104
105  if (!kameraBaslat()) return;               // kamera yoksa dur / stop without a camera
106
107  // 1-bit mod: GPIO 4, 12 ve 13 boşta kalır / 1-bit mode keeps GPIO 4, 12 and 13 free
108  if (!SD_MMC.begin("/sdcard", true)) {
109    Serial.println("SD kart takilamadi / SD card mount failed");
110    return;
111  }
112  if (SD_MMC.cardType() == CARD_NONE) {
113    Serial.println("SD kart yok / No SD card");
114    return;
115  }
116
117  pinMode(FLAS_LED, OUTPUT);
118  digitalWrite(FLAS_LED, LOW);
119
120  // Var olan fotoğrafların üzerine yazma / don't overwrite existing photos
121  while (SD_MMC.exists("/foto" + String(fotoNo) + ".jpg")) fotoNo++;
122
123  hazir = true;
124  Serial.println("Hazir, butona bas / Ready, press the button");
125}
126
127void loop() {
128  if (!hazir) {                              // hata varsa bekle / wait if setup failed
129    delay(1000);
130    return;
131  }
132  if (digitalRead(BUTON) == LOW) {
133    delay(30);                               // buton sıçramasını (bounce) önle / debounce
134    if (digitalRead(BUTON) == LOW) {
135      fotoCek();
136      while (digitalRead(BUTON) == LOW) delay(10);   // bırakılmasını bekle / wait for release
137    }
138  }
139}

Weil der Sketch die SD-Karte im 1-Bit-Modus startet, belegt er nur GPIO 2, 14 und 15; GPIO 4 bleibt für den Blitz und GPIO 13 für den Taster frei. Vor dem Foto wird ein Bild geholt und sofort zurückgegeben: Die Kamera liefert ständig Bilder, das erste Bild im Puffer kann also noch vor dem Blitz entstanden sein, und die automatische Belichtung braucht eine kurze Pause, um sich an das neue Licht anzupassen. Die Dateinummer ergibt sich aus den Dateien, die schon auf der Karte liegen; so werden alte Fotos auch nach einem Neustart nicht überschrieben. Die allgemeinen Regeln für das Speichern auf SD-Karten findest du im Beitrag SD-Kartenmodul.

MicroPython und neuere Kamera-Boards

Du kannst die ESP32-CAM auch mit MicroPython programmieren, allerdings enthält die offizielle MicroPython-Firmware keinen Kameratreiber; du musst eine Community-Firmware mit Kameraunterstützung aufspielen. Für den Einstieg ist der Weg über die Arduino IDE deshalb deutlich unkomplizierter. Wenn du dich nicht mit einer Platine ohne USB-Buchse herumschlagen willst, schau dir auch Kamera-Boards auf Basis des ESP32-S3 mit USB und mehr Speicher an (z. B. Seeed XIAO ESP32S3 Sense oder ESP32-S3-EYE); sie stehen ebenfalls in der Modellliste von CameraWebServer.

Projektideen mit der ESP32-CAM

  • Foto bei Bewegung: Mach ein Foto, wenn ein PIR-Sensor jemanden erkennt, und schick es aufs Handy; die Schritt-für-Schritt-Anleitung steht im Beitrag ESP32-CAM Fotos an Telegram.
  • Zeitraffer: Lass die Platine alle 10 Minuten aufwachen, ein Foto machen, es auf der SD-Karte speichern und wieder in den Deep Sleep gehen; so beobachtest du Pflanzenwachstum oder das Wetter.
  • Türklingelkamera: Fotografiere den Eingang, wenn jemand klingelt, und schick eine Nachricht über einen Telegram-Bot.
  • Roboterauto mit Kamera: Steuere das Auto, während du auf dem Handy ein flüssiges QVGA-Livebild siehst.
  • Haustierkamera: Sieh dir den Livestream im Heimnetz an und schalte bei Bedarf den Blitz über die Webseite ein.
  • Eigenes Dashboard: Bette den Livestream in deine eigene Webseite ein und ergänze Relais-Schalter und Sensorwerte; der Beitrag ESP32 WebSocket zeigt den Weg.

Häufige Fehler und Lösungen

SymptomMögliche UrsacheLösung
Failed to connect to ESP32: No serial data received (in älteren Versionen Timed out waiting for packet header)Platine nicht im Download-Modus oder TX und RX vertauschtIO0 mit GND verbinden oder IO0-Taster nutzen, RST drücken; prüfen, ob TX an U0R und RX an U0T geht
Wrong boot mode detected (0x13)GPIO 0 war beim Start nicht LOWNach dem Setzen der Brücke IO0-GND immer RST drücken
waiting for download im seriellen MonitorIO0 ist noch mit GND verbundenIO0-Brücke entfernen und RST drücken
Wirre Zeichen im seriellen MonitorFalsche BaudrateSeriellen Monitor auf 115200 Baud stellen
Platine fehlt in der PortlisteTreiber fehlt oder reines LadekabelTreiber für CH340 oder CP2102 installieren, Datenkabel verwenden
Upload scheitert mit eingesteckter SD-KarteGPIO 2 ist SD-Leitung und Strapping-Pin zugleichmicroSD-Karte beim Hochladen entfernen
Bild sehr langsam oder friert oft einSchwaches WLAN-Signal oder hohe AuflösungAuf VGA oder QVGA gehen, Platine näher an den Router, bei Bedarf externe Antenne
Blitz glimmt ständig schwachSD-Karte im 4-Bit-Modus oder GPIO 4 offenSD-Karte im 1-Bit-Modus starten, GPIO 4 als OUTPUT auf LOW setzen
Willst du eine externe Antenne (IPEX) anschließen: Welche Antenne die Platine nutzt, entscheidet die Lage eines winzigen 0-Ω-Widerstands neben der Antenne. Die Antenne einzustecken reicht nicht, du musst auch den Widerstand umsetzen. Startet die Platine nicht oder lässt sich die SD-Karte nicht starten, entferne Module an GPIO 2, 12 und 13 und versuche es erneut: GPIO 2 und 12 sind Strapping-Pins, und GPIO 13 ist die Leitung DATA3 der SD-Karte, die beim Initialisieren nicht LOW sein darf.

Die ESP32-CAM ist der einfachste Weg zu einer WLAN-Kamera auf einer günstigen Platine, und fast alle Schwierigkeiten kommen von der Programmierverbindung oder der Stromversorgung. Hast du diese beiden Punkte im Griff, streamt die Platine live über ihren eigenen Webserver, macht Fotos und speichert sie auf der SD-Karte. In der BlueGrays-App findest du ESP32-Projekte wie WLAN-Verbindung, Webserver, mDNS, Datenlogging auf microSD und eine Bewegungsalarmanlage mit Telegram-Benachrichtigung, jeweils mit Schritt-für-Schritt-Schaltplan und fertigem Code.

Häufige Fragen

Wie programmiere ich die ESP32-CAM?

Da die ESP32-CAM keine USB-Buchse hat, brauchst du einen ESP32-CAM-MB-Adapter oder einen USB-TTL-Adapter. In der Arduino IDE wählst du das Board AI Thinker ESP32-CAM und bringst die Platine in den Download-Modus, indem du RST drückst, während GPIO 0 mit GND verbunden ist (oder der IO0-Taster am MB gedrückt ist). Nach dem Upload entfernst du die IO0-Verbindung und drückst erneut RST.

Kann man die ESP32-CAM mit einem Arduino Uno programmieren?

Ja; verbindest du den RESET-Pin des Uno mit GND, arbeitet sein USB-Chip wie eine USB-Seriell-Brücke. Dann wird nicht gekreuzt, sondern gerade verbunden: D0 (RX) des Uno an U0R, D1 (TX) an U0T, und IO0 kommt wie gewohnt an GND. Da der Uno mit 5-V-Signalen arbeitet, belastet das den ESP32 an der Grenze; auf Dauer ist ein MB-Adapter oder ein USB-TTL-Adapter mit 3,3-V-Pegel sicherer.

Mit wie viel Volt läuft die ESP32-CAM?

Empfohlen sind 5 V am Pin 5V; der Spannungsregler auf der Platine macht daraus 3,3 V. Du kannst auch 3,3 V am Pin 3V3 einspeisen, aber wenn die Quelle die WLAN-Stromspitzen nicht schafft, startet die Platine ständig neu. Ein Netzteil mit mindestens 2 A verhindert die meisten Brownout-Fehler.

Wie behebe ich den Fehler Camera init failed bei der ESP32-CAM?

Fehlercode 0x105 oder 0x106 bedeutet, dass gar keine Kamera gefunden wurde: Prüfe zuerst, ob im Code CAMERA_MODEL_AI_THINKER aktiv ist, dann, ob das Flachbandkabel fest sitzt, und versorge die Platine mit 5 V / 2 A. Hilft das nicht, ist das Kameramodul eventuell defekt. Siehst du 0xffffffff zusammen mit frame buffer malloc failed, aktiviere PSRAM oder senke die Auflösung.

Funktioniert die ESP32-CAM ohne Internet?

Ja. Zum Ansehen des Bildes brauchst du nur ein lokales Netz, kein Internet; die ESP32-CAM kann mit WiFi.softAP() auch ein eigenes WLAN aufbauen und ist dann im Browser unter 192.168.4.1 erreichbar. Du kannst sie sogar ganz ohne Netz als Kamera betreiben, die Fotos nur auf der microSD-Karte speichert.

Kann die ESP32-CAM Videos aufnehmen?

Die fertigen Beispiele streamen das Livebild als MJPEG und machen Einzelfotos; eine Videodatei zeichnen sie nicht direkt auf. Es gibt Community-Projekte, die aufeinanderfolgende JPEG-Bilder auf die microSD-Karte schreiben und daraus eine AVI-Datei bauen, die Bildrate ist aber selbst bei niedriger Auflösung begrenzt. Ein Mikrofon hat die Platine nicht, Ton kann sie also auch nicht aufnehmen.

Alle Projekte ansehen
LED Blinken mit ESP32
#103Anfänger

LED Blinken mit ESP32

Lehrt die grundlegende Verwendung von GPIO-Ausgängen mit ESP32. Wir erreichen einen Blinkeffekt, indem wir eine LED über einen digitalen Pin ein- und ausschalten. ESP32-Version des klassischen Blink-Projekts auf Arduino UNO; die grundlegenden Blink-Befehle in der Arduino-Umgebung bleiben gleich, aber die Pinbelegung und die GPIO-Pegel von 3,3 V des ESP32 unterscheiden sich von denen des Arduino UNO.

4.7(36)
96
ESP32 Interne LED Blinken
#106Anfänger

ESP32 Interne LED Blinken

Die eingebaute blaue LED auf dem ESP32 DevKit V1 zum Blinken bringen. Keine externen Komponenten erforderlich! Das erste Projekt, das Sie ausprobieren sollten, wenn Sie einen ESP32 kaufen. GPIO 2 ist mit der internen LED verbunden.

4.8(29)
53
ESP32-WLAN-STA-Verbindung (mit LCD-Display)
#127Fortgeschritten
Premium

ESP32-WLAN-STA-Verbindung (mit LCD-Display)

In diesem Projekt verbinden wir den ESP32 im Station-Modus (STA) sicher und fehlertolerant mit dem heimischen WLAN. Wir lagern SSID und Passwort in eine separate `secrets.h`-Datei aus, um Leaks zu Git zu verhindern, richten einen Auto-Reconnect-Mechanismus ein und zeigen RSSI-Signalpegel und IP-Adresse auf einem I2C-LCD-Display an. Die interne LED dient als Statusanzeige. Ein Verbindungsmanager auf Produktionsniveau.

4.4(21)
33
ESP32 Async-Webserver (mit IP-Anzeige auf dem LCD)
#129Fortgeschritten
Premium

ESP32 Async-Webserver (mit IP-Anzeige auf dem LCD)

In diesem Projekt verwandeln wir den ESP32 in einen **asynchronen Webserver**, den Sie über Ihr Smartphone oder Ihren Computer im selben WLAN-Netzwerk steuern können. Dank der ESPAsyncWebServer-Bibliothek kann der Server mehrere Anfragen gleichzeitig bearbeiten (im Gegensatz zum klassischen `WebServer.h`, der bei einer einzigen Anfrage blockiert). Sie können über den Browser die IP-Adresse des ESP32 öffnen und durch Drücken der ON/OFF-Schaltflächen (Routen `/on` und `/off`) die an GPIO 5 anges

4.8(16)
26
ESP32 mDNS: Zugriff auf das Gerät über „bluegrays-esp.local“ (mit LCD-Display)
#131Fortgeschritten
Premium

ESP32 mDNS: Zugriff auf das Gerät über „bluegrays-esp.local“ (mit LCD-Display)

In diesem Projekt fügen wir dem ESP32 einen mDNS-Dienst (Multicast DNS) hinzu, um den Zugriff nicht über eine IP-Adresse, sondern über einen lesbaren Hostnamen wie `bluegrays-esp.local` zu ermöglichen. Selbst wenn sich die vom DHCP zugewiesene IP-Adresse ändert, können Sie das Gerät immer unter demselben Namen erreichen. Indem wir zusätzlich einen kleinen Webserver darauf betreiben, senden wir über den Browser unter der Adresse `http://bluegrays-esp.local/` Befehle zur LED-Steuerung. Auf dem I2C

4.8(14)
23
ESP32 Temperatur-Datenlogger (DHT22 + DS1307 RTC + microSD + OLED)
#144Fortgeschritten
Premium

ESP32 Temperatur-Datenlogger (DHT22 + DS1307 RTC + microSD + OLED)

Baue einen zeitgestempelten Temperaturlogger mit ESP32! Lese Temperatur/Feuchtigkeit vom DHT22 jede Minute, hole die aktuelle Zeit vom DS1307 RTC und protokolliere auf microSD-Karte als CSV. Das OLED zeigt live Temperatur (große Schrift), Luftfeuchtigkeit, Zeitstempel und Logzähler. Die `/temp_log.csv`-Datei auf der SD-Karte öffnet sich in Excel, Google Sheets oder Python pandas zur Analyse — perfekt für Gewächshausüberwachung, Raumtemperaturverfolgung, Laboraufzeichnung, Lebensmittellageru

4.7(7)
12
ESP32 Bewegungsalarmsystem (PIR + Buzzer + LED + Telegram)
#145Fortgeschritten
Premium

ESP32 Bewegungsalarmsystem (PIR + Buzzer + LED + Telegram)

Ein intelligentes Sicherheitsalarmsystem, das Buzzer und LED aktiviert, sobald der PIR-Sensor Bewegung erkennt, und gleichzeitig eine sofortige Benachrichtigung per Telegram an den Besitzer sendet. Ein 30-sekündiger Cooldown begrenzt die Häufigkeit wiederholter Alarme; dieser Mechanismus überprüft weder die Gültigkeit der PIR-Erkennungen noch verhindert er Fehlauslösungen. Geeignet für Heimsicherheit, Garagenüberwachung, Lagerräume oder Arbeitszimmer. Mit ESP32-CAM sind Foto-Benachrichtigungen m

0.0(0)
8
ESP32-Bewegungsalarm
#140Mittel
Premium

ESP32-Bewegungsalarm

In diesem Projekt, das mit einem ESP32 und einem PIR-Sensor realisiert wurde, wird bei Bewegungserkennung ein Summer aktiviert, der einen akustischen Alarm auslöst. Es handelt sich um eine einfache und kostengünstige Sicherheitssystem-Anwendung. (Die Abbildungen dienen nur zur Veranschaulichung; bitte ordnen Sie sie den Texten zu.)

4.4(10)
15