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.

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.
| Merkmal | Wert |
|---|---|
| Prozessor | ESP32 (ESP32-S-Modul), Dual-Core, bis 240 MHz |
| Funk | WLAN 802.11 b/g/n (nur 2,4 GHz), Bluetooth 4.2 und BLE |
| Speicher | 520 KB internes SRAM + 4 MB PSRAM, 4 MB Flash |
| Kamera | OV2640, 2 MP, bis 1600×1200 (UXGA), JPEG-Ausgabe |
| Speicherkarte | microSD-Slot (laut offizieller Doku bis 4 GB) |
| Licht | Weiße Blitz-LED (GPIO 4), rote Status-LED auf der Rückseite (GPIO 33) |
| Versorgung | 5 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öße | 27 × 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.
| Pin | Funktion | Frei nutzbar? |
|---|---|---|
| 5V | Spannungseingang (empfohlen) | - |
| 3V3 | Spannungseingang 3,3 V | - |
| GND (3 Stück) | Masse | - |
| VCC | Spannungsausgang (standardmäßig 3,3 V) | Nicht zur Versorgung der Platine verwenden |
| U0R (GPIO 3) | Serielles RX: Programmieren und Serieller Monitor | Nur ohne serielle Schnittstelle |
| U0T (GPIO 1) | Serielles TX: Programmieren und Serieller Monitor | Nur ohne serielle Schnittstelle |
| GPIO 0 | Kameratakt (XCLK) und Boot-Modus | Nein; nur beim Hochladen mit GND verbinden |
| GPIO 16 | Bei vielen Platinen mit dem PSRAM verbunden | Nein |
| GPIO 2 | SD DATA0 | Wenn keine SD-Karte genutzt wird; Strapping-Pin |
| GPIO 4 | SD DATA1 und Blitz-LED | Im SD-1-Bit-Modus oder ohne SD |
| GPIO 12 | SD DATA2 | Im SD-1-Bit-Modus oder ohne SD; beim Booten LOW |
| GPIO 13 | SD DATA3 | Im SD-1-Bit-Modus oder ohne SD; der sicherste freie Pin |
| GPIO 14 | SD CLK | Wenn keine SD-Karte genutzt wird |
| GPIO 15 | SD CMD | Wenn keine SD-Karte genutzt wird; Strapping-Pin |
| GPIO 33 | Rote LED (nicht am Rand) | Nur LED; LOW schaltet sie ein |
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.

| USB-TTL-Adapter | ESP32-CAM | Hinweis |
|---|---|---|
| GND | GND | Gemeinsame Masse |
| 5V | 5V | Versorgt die Platine; der 3,3-V-Ausgang des Adapters reicht nicht |
| TX | U0R (GPIO 3) | Gekreuzt: Sender an Empfänger |
| RX | U0T (GPIO 1) | Gekreuzt: Empfänger an Sender |
| - | Zwischen IO0 und GND | Nur 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
- Öffne in der Arduino IDE den Boardverwalter und installiere das Paket esp32 by Espressif Systems; ausführlich erklärt im Beitrag Arduino IDE installieren.
- Wähle unter Werkzeuge > Board > esp32 das Board AI Thinker ESP32-CAM.
- Achte darauf, dass Partition Scheme auf Huge APP (3MB No OTA/1MB SPIFFS) steht; das Kamerabeispiel braucht mindestens 3 MB Programmspeicher.
- 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...).
- Erscheint gar kein Port, installiere den Treiber für CH340 oder CP2102 und nimm ein USB-Kabel mit Datenleitungen.
| Einstellung | Empfohlener Wert | Warum? |
|---|---|---|
| Board | AI Thinker ESP32-CAM | PSRAM, 4 MB Flash und passendes Partitionsschema sind voreingestellt |
| Partition Scheme | Huge APP (3MB No OTA/1MB SPIFFS) | Die 3 MB Programmspeicher, die CameraWebServer braucht |
| PSRAM | Bei diesem Board immer aktiv | Bei ESP32 Dev Module PSRAM: Enabled wählen; bei ESP32 Wrover Module schon aktiv |
| CPU Frequency | 240MHz (WiFi/BT) | Höchste Geschwindigkeit für Bildübertragung und WLAN |
| Flash Mode / Flash Frequency | QIO / 80MHz | Bei Upload- oder Startproblemen DIO / 40MHz testen |
| Core Debug Level | None (zur Fehlersuche Info) | Bei Info erscheinen Kamera- und FPS-Infos im seriellen Monitor |
| Upload Speed | 460800 (bei diesem Board fest) | Bricht der Upload oft ab, ESP32 Wrover Module mit 115200 testen |
Der erste Upload Schritt für Schritt
- 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.
- 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.
- Klicke in der Arduino IDE auf Hochladen. In der Ausgabe erscheint zuerst Connecting... und danach der Schreibfortschritt in Prozent.
- 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.
- Öffne den seriellen Monitor mit 115200 Baud und drücke RST; das neue Programm startet.
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
- Öffne Datei > Beispiele > ESP32 > Camera > CameraWebServer.
- 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.
- Trage in die Zeilen ssid und password Namen und Passwort deines 2,4-GHz-WLANs ein.
- Bring die Platine in den Download-Modus und lade den Sketch hoch; entferne danach die IO0-Verbindung und drücke RST.
- 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.
- Starte das Live-Bild mit dem Button Start Stream oder mach mit Get Still ein einzelnes Foto.
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 passwordDie 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ösung | Pixel | Ca. FPS (WLAN-Stream) | Geeignet für |
|---|---|---|---|
| QQVGA | 160×120 | 25–30 | Bewegungserkennung, sehr schwaches Netz |
| QVGA | 320×240 | 20–30 | Roboterauto, flüssiges Livebild |
| CIF | 400×296 | 15–25 | Flüssige Anzeige auf kleinen Bildschirmen |
| VGA | 640×480 | 10–20 | Livebild für alle Zwecke |
| SVGA | 800×600 | 8–15 | Schärferes Bild; größte Auflösung ohne PSRAM |
| XGA | 1024×768 | 5–10 | Detaillierte Bilder |
| HD | 1280×720 | 4–8 | Breiter Bildausschnitt (16:9) |
| SXGA | 1280×1024 | 3–6 | Fotos |
| UXGA | 1600×1200 | 2–5 | Fotos 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.
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..2Warum 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 Monitor | Bedeutung | Lösung |
|---|---|---|
| Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND) | Der ESP32 hat am SCCB-Bus keine Kamera gefunden | Prüfen, ob CAMERA_MODEL_AI_THINKER aktiv ist, Flachbandkabel neu einstecken, mit 5 V / 2 A versorgen |
| Detected camera not supported und 0x106 | Dieselbe Situation in neueren Treiberversionen: keine Kamera gefunden oder erkannt | Wie bei 0x105; hilft das nicht, Kameramodul tauschen |
| frame buffer malloc failed und 0xffffffff | Speicher für den Bildpuffer konnte nicht reserviert werden | PSRAM aktivieren, Auflösung senken, fb_count auf 1 setzen |
| cam_hal: EV-VSYNC-OVF oder FB-OVF | Ein neues Bild kam, bevor das vorige verarbeitet war; ein Bild wurde übersprungen | Gelegentlich harmlos; bei Häufung Auflösung senken und WLAN-Signal verbessern |
| NO-SOI (JPEG start marker missing) | Defektes oder unvollständiges JPEG-Bild | Stromversorgung und Flachbandkabel prüfen, xclk_freq_hz auf 10000000 setzen |
| Bild halb, grün oder gestreift | Das Bild passte nicht in den Puffer oder die Versorgung ist verrauscht | JPEG-Qualitätswert auf 12 oder höher setzen, Stromversorgung verbessern |
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.

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.
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
| Symptom | Mögliche Ursache | Lö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 vertauscht | IO0 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 LOW | Nach dem Setzen der Brücke IO0-GND immer RST drücken |
| waiting for download im seriellen Monitor | IO0 ist noch mit GND verbunden | IO0-Brücke entfernen und RST drücken |
| Wirre Zeichen im seriellen Monitor | Falsche Baudrate | Seriellen Monitor auf 115200 Baud stellen |
| Platine fehlt in der Portliste | Treiber fehlt oder reines Ladekabel | Treiber für CH340 oder CP2102 installieren, Datenkabel verwenden |
| Upload scheitert mit eingesteckter SD-Karte | GPIO 2 ist SD-Leitung und Strapping-Pin zugleich | microSD-Karte beim Hochladen entfernen |
| Bild sehr langsam oder friert oft ein | Schwaches WLAN-Signal oder hohe Auflösung | Auf VGA oder QVGA gehen, Platine näher an den Router, bei Bedarf externe Antenne |
| Blitz glimmt ständig schwach | SD-Karte im 4-Bit-Modus oder GPIO 4 offen | SD-Karte im 1-Bit-Modus starten, GPIO 4 als OUTPUT auf LOW setzen |
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.
Projekte, die du danach bauen kannst
Alle Projekte ansehen
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.

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.

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.

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

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

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

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

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.)
Weitere Artikel
BlueGrays-App
Diese Schaltung Schritt für Schritt auf dem Handy nachbauen
Schaltplan, Code und Teileliste auf einem Bildschirm. Über 160 Arduino-, ESP32- und Pico-Projekte zum Nachbauen.
Mit dem Handy scannen
Richte die Kamera auf den Code, dann öffnet sich der App-Store deines Handys.
oder im Store öffnen

