ESP32 S3 Kamera - Foto auf SD-Karte speichern, wenn Bewegung erkannt wird

Dieses Tutorial zeigt Ihnen, wie Sie mit dem ESP32 S3 eine kleine Sicherheitskamera bauen. Ein PIR-Bewegungssensor überwacht den Raum. Wenn jemand davor vorbeigeht, nimmt der ESP32 S3 ein Foto auf und speichert es auf einer microSD-Karte. Das Board arbeitet allein. Es braucht kein WLAN und keinen Computer.

ESP32 S3 Kamera - Foto auf SD-Karte speichern, wenn Bewegung erkannt wird

Was Sie bauen werden:

  1. Eine ESP32 S3 Kamera mit einem PIR-Bewegungssensor
  2. Ein Foto, das jedes Mal auf der microSD-Karte gespeichert wird, wenn der Sensor eine Bewegung erkennt
  3. Eine Ruhezeit, damit eine vorbeigehende Person Ihre Karte nicht mit 50 Fotos füllt
  4. Eine Kamera, die ohne Internet funktioniert

Erforderliche Hardware

1×ESP32 S3 N16R8 OV5640 Camera
1×(Alternativ) ESP32 S3 N16R8 OV2640 Camera
1×USB-Kabel Typ-A zu Typ-C (für USB-A PC)
1×USB-Kabel Typ-C zu Typ-C (für USB-C PC)
1×HC-SR501 Bewegungssensor
1×microSD Card
1×Verbindungskabel
1×(Optional) DC-Stromanschluss
1×(Empfohlen) Screw Terminal Expansion Board for ESP32 S3
1×(Empfohlen) Breakout Expansion Board for ESP32 S3
1×(Empfohlen) Power Splitter for ESP32 S3

Oder Sie können die folgenden Kits kaufen:

1×DIYables Sensor-Kit (18 Sensoren/Displays)
Offenlegung: Einige der in diesem Abschnitt bereitgestellten Links sind Amazon-Affiliate-Links. Wir können eine Provision für Käufe erhalten, die über diese Links getätigt werden, ohne zusätzliche Kosten für Sie. Wir schätzen Ihre Unterstützung.

※ Notiz:

Das ESP32 S3 Kamera-Board hat 40 Pins, aber der Schraubklemmenblock und das Breakout-Board haben 44 Pins. Sie funktionieren trotzdem zusammen. Setzen Sie das Kamera-Board in die Mitte des 44-Pin-Boards, sodass auf der linken Seite 2 Pins frei bleiben und auf der rechten Seite 2 Pins frei bleiben.

Mit dem Schraubklemmenblock können Sie Drähte mit einem Schraubendreher anschließen, ganz ohne Löten. Das Breakout-Board bietet Ihnen einfache Stiftleisten für ein Breadboard.

Überblick über PIR Motion Sensor

Ein PIR-Bewegungssensor erkennt die Wärme eines menschlichen Körpers. PIR steht für "Passive InfraRed" (passives Infrarot). Der Sensor sendet nichts aus. Er empfängt nur das Infrarotlicht (die Wärme) um sich herum. Wenn sich ein warmer Körper vor ihm bewegt, ändert sich das Wärmemuster, und der Sensor meldet es dem ESP32 S3.

PIR-Bewegungssensor HC-SR501

Weitere Details zum Bewegungssensor finden Sie im Tutorial ESP32 S3 - Bewegungssensor.

Wichtige technische Daten

PunktWert
Stromversorgung5V
Ausgang3,3V HIGH, wenn er eine Bewegung erkennt, LOW, wenn er nichts erkennt
Reichweite3 bis 7 Meter (einstellbar)
Winkeletwa 110°
Aufwärmzeit30 bis 60 Sekunden nach dem Einschalten

※ Notiz:

Der Ausgang des HC-SR501 liefert 3,3V, daher können Sie ihn direkt an einen Pin des ESP32 S3 anschließen. Das ist sicher.

PIR-Bewegungssensor Pinbelegung

Der Sensor hat 3 Pins:

  1. VCC-Pin: Schließen Sie diesen Pin an 5V an
  2. GND-Pin: Schließen Sie diesen Pin an GND an
  3. OUT-Pin: geht auf HIGH, wenn der Sensor eine Bewegung erkennt
PIR-Bewegungssensor Pinbelegung

Die beiden orangefarbenen Schrauben

Der HC-SR501 hat zwei kleine orangefarbene Schrauben. Drehen Sie sie mit einem kleinen Schraubendreher:

SchraubeWas sie ändertNach rechts drehen (im Uhrzeigersinn)
EmpfindlichkeitWie weit der Sensor siehtSieht weiter (bis zu 7 m)
VerzögerungszeitWie lange der Ausgang HIGH bleibtBleibt länger HIGH (bis zu 5 Minuten)

※ Notiz:

Drehen Sie für dieses Projekt die Schraube für die Verzögerungszeit ganz nach links. Der Ausgang bleibt dann nur etwa 3 Sekunden lang HIGH, sodass der Sensor schnell wieder bereit ist.

Der Jumper mit zwei Stellungen

Neben den Pins befindet sich ein kleiner Jumper:

StellungNameWas passiert
HWiederholenDer Ausgang bleibt HIGH, solange die Bewegung anhält
LEinzelnDer Ausgang geht einmal auf HIGH, dann auf LOW

Beide Stellungen funktionieren mit diesem Code. H ist die übliche Wahl.

Wie das Projekt funktioniert

Der Code überwacht ständig den OUT-Pin. Er achtet nicht auf "der Pin ist HIGH". Er achtet auf den Moment, in dem der Pin von LOW auf HIGH wechselt:

if (lastPirState == LOW && pirState == HIGH) { // the movement has just started }

Das ist wichtig. Wenn der Code nur auf HIGH achten würde, würde er hunderte Male pro Sekunde ein neues Foto aufnehmen, während eine Person vor der Kamera steht.

Schaltplan zwischen PIR-Bewegungssensor und ESP32 S3

Schließen Sie den PIR-Bewegungssensor mit drei Jumperkabeln an Ihren ESP32 S3 an.

ESP32 S3 PIR-Bewegungssensor Schaltplan

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

PIR-Sensor-PinESP32 S3 Pin
VCC5V
GNDGND
OUTGPIO21

Stecken Sie dann die microSD-Karte in den Steckplatz auf dem Board.

Sicherheitshinweise

Der PIR-Sensor braucht 5V an seinem VCC-Pin, nicht 3,3V. Mit 3,3V scheint er zu funktionieren, liefert aber falsche Signale. Sein OUT-Pin liefert 3,3V, was für den ESP32 S3 korrekt ist.

Verwenden Sie keinen Kamera-Pin für den Sensor. Die Kamera verwendet bereits GPIO4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17 und 18. Der Kartensteckplatz verwendet GPIO38, 39 und 40. GPIO21 ist frei, also verwenden wir ihn.

Arduino IDE Einstellungen für die ESP32 S3 Kamera

Die Kamera funktioniert nicht mit den Standardeinstellungen der Arduino IDE. Sie müssen einige Punkte im Menü Tools ändern, bevor Sie den Code hochladen.

Menüpunkt in ToolsDiese Auswahl treffen
BoardESP32S3 Dev Module
Flash Size16MB (128Mb)
PSRAMOPI PSRAM
Partition SchemeHuge APP (3MB No OTA/1MB SPIFFS)
CPU Frequency240MHz (WiFi)
USB ModeHardware CDC and JTAG
Upload ModeUART0 / Hardware CDC
Upload Speed921600
USB CDC On BootEnabled

※ Notiz:

PSRAM muss OPI PSRAM sein, und Partition Scheme muss Huge APP sein. Ändern Sie zuerst Flash Size, denn danach ändert sich die Liste der Optionen für Partition Scheme.

So programmieren Sie die Bewegungskamera

  • Stellen Sie den Sensor-Pin als Eingang ein.
#define PIR_PIN 21 pinMode(PIR_PIN, INPUT);
  • Warten Sie nach dem Start des Boards auf den Sensor. Ein PIR-Sensor braucht 30 bis 60 Sekunden, um die Wärme des Raums zu lernen. Davor löst er Fehlalarme aus.
Serial.println("The PIR sensor is warming up. Please wait 30 seconds and do not move."); delay(30000);
  • Achten Sie auf den Moment, in dem der Pin von LOW auf HIGH wechselt.
int pirState = digitalRead(PIR_PIN); if (lastPirState == LOW && pirState == HIGH) { Serial.println("Motion detected!"); takeAndSavePhoto(); } lastPirState = pirState; // remember the state for the next time
  • Fügen Sie eine Ruhezeit hinzu. Ohne sie erzeugt eine langsam gehende Person zehn Fotos.
if (millis() - lastPhotoTime >= QUIET_TIME) { takeAndSavePhoto(); lastPhotoTime = millis(); }
camera_fb_t *fb = esp_camera_fb_get(); File file = SD_MMC.open("/motion_00001.jpg", FILE_WRITE); file.write(fb->buf, fb->len); file.close(); esp_camera_fb_return(fb);

ESP32 S3 Code

Der folgende Code speichert jedes Mal, wenn der Sensor eine Bewegung erkennt, ein Foto mit dem Namen motion_00001.jpg, motion_00002.jpg und so weiter. Die Ruhezeit beträgt 5 Sekunden. Um sie zu ändern, ändern Sie die Zeile #define QUIET_TIME 5000.

/* * Dieser ESP32 S3 Code wurde von newbiely.de entwickelt * Dieser ESP32 S3 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32-s3/esp32-s3-camera-save-photo-to-sd-card-when-motion-detected */ #include "esp_camera.h" #include "FS.h" #include "SD_MMC.h" #define PIR_PIN 21 // the PIR motion sensor is connected to GPIO21 #define QUIET_TIME 5000 // wait 5 seconds before the next photo (5000 milliseconds) // Camera pins of the ESP32-S3-N16R8 camera board. // The same pins work for the OV2640, OV3660 and OV5640 versions. #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 15 #define SIOD_GPIO_NUM 4 #define SIOC_GPIO_NUM 5 #define Y9_GPIO_NUM 16 #define Y8_GPIO_NUM 17 #define Y7_GPIO_NUM 18 #define Y6_GPIO_NUM 12 #define Y5_GPIO_NUM 10 #define Y4_GPIO_NUM 8 #define Y3_GPIO_NUM 9 #define Y2_GPIO_NUM 11 #define VSYNC_GPIO_NUM 6 #define HREF_GPIO_NUM 7 #define PCLK_GPIO_NUM 13 // Pins of the microSD card slot on the board #define SD_CLK_GPIO_NUM 39 #define SD_CMD_GPIO_NUM 38 #define SD_D0_GPIO_NUM 40 int photoNumber = 1; int lastPirState = LOW; unsigned long lastPhotoTime = 0; // Returns the name of the camera sensor that is installed on the board const char *getSensorName(int pid) { switch (pid) { case OV2640_PID: return "OV2640 (2 MP, max UXGA 1600x1200)"; case OV3660_PID: return "OV3660 (3 MP, max QXGA 2048x1536)"; case OV5640_PID: return "OV5640 (5 MP, max QSXGA 2592x1944)"; default: return "Unknown sensor"; } } bool initCamera() { camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sccb_sda = SIOD_GPIO_NUM; config.pin_sccb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_UXGA; // 1600x1200 - a big, sharp photo config.jpeg_quality = 12; // 0 to 63, a lower number means a better image config.fb_count = 1; config.fb_location = CAMERA_FB_IN_DRAM; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; if (psramFound()) { config.fb_location = CAMERA_FB_IN_PSRAM; config.jpeg_quality = 10; config.fb_count = 2; config.grab_mode = CAMERA_GRAB_LATEST; } else { config.frame_size = FRAMESIZE_QVGA; Serial.println("WARNING: PSRAM not found. Please set PSRAM to OPI PSRAM in the Tools menu."); } esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x\n", err); return false; } sensor_t *s = esp_camera_sensor_get(); Serial.printf("Camera sensor: %s\n", getSensorName(s->id.PID)); // Each sensor needs slightly different settings switch (s->id.PID) { case OV2640_PID: s->set_vflip(s, 0); s->set_hmirror(s, 0); break; case OV3660_PID: s->set_vflip(s, 1); // the OV3660 image is upside down by default s->set_brightness(s, 1); // make the image a little brighter s->set_saturation(s, -2); // make the colors a little softer break; case OV5640_PID: s->set_vflip(s, 0); s->set_hmirror(s, 0); break; default: break; } return true; } bool initSDCard() { SD_MMC.setPins(SD_CLK_GPIO_NUM, SD_CMD_GPIO_NUM, SD_D0_GPIO_NUM); // true means 1-bit mode. The camera uses the other pins, so we cannot use 4-bit mode. if (!SD_MMC.begin("/sdcard", true)) { Serial.println("SD card not found. Please check the card and push it in again."); return false; } if (SD_MMC.cardType() == CARD_NONE) { Serial.println("No SD card inside the slot"); return false; } Serial.printf("SD card size: %llu MB\n", SD_MMC.cardSize() / (1024 * 1024)); return true; } // Makes a file name like /motion_00001.jpg String makeFileName(int number) { char name[32]; sprintf(name, "/motion_%05d.jpg", number); return String(name); } // Looks for the first free file name, so old photos are never lost void findFirstFreeNumber() { while (SD_MMC.exists(makeFileName(photoNumber))) photoNumber++; Serial.printf("The next photo will be motion_%05d.jpg\n", photoNumber); } void takeAndSavePhoto() { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Photo capture failed"); return; } String fileName = makeFileName(photoNumber); File file = SD_MMC.open(fileName.c_str(), FILE_WRITE); if (file) { file.write(fb->buf, fb->len); file.close(); Serial.printf("Saved %s (%u bytes)\n", fileName.c_str(), fb->len); photoNumber++; } else { Serial.printf("Cannot write the file %s\n", fileName.c_str()); } esp_camera_fb_return(fb); // give the memory back to the camera } void setup() { Serial.begin(115200); delay(1000); pinMode(PIR_PIN, INPUT); if (!initCamera()) { Serial.println("Stopped"); while (true) delay(1000); } if (!initSDCard()) { Serial.println("Stopped"); while (true) delay(1000); } findFirstFreeNumber(); Serial.println("The PIR sensor is warming up. Please wait 30 seconds and do not move."); delay(30000); Serial.println("Ready. Waiting for motion..."); } void loop() { int pirState = digitalRead(PIR_PIN); // LOW to HIGH means the sensor has just seen a movement if (lastPirState == LOW && pirState == HIGH) { if (millis() - lastPhotoTime >= QUIET_TIME) { Serial.println("Motion detected!"); takeAndSavePhoto(); lastPhotoTime = millis(); } } lastPirState = pirState; }

Schnelle Schritte

  • Neu beim ESP32 S3? Arbeiten Sie zuerst unsere Anleitung Erste Schritte mit dem ESP32 S3 durch.
  • Formatieren Sie Ihre microSD-Karte auf Ihrem Computer als FAT32.
  • Ziehen Sie das USB-Kabel ab. Stecken Sie die Karte in den Steckplatz und verdrahten Sie den PIR-Sensor wie in der Tabelle oben.
  • Drehen Sie die Schraube für die Verzögerungszeit des Sensors ganz nach links.
  • Kopieren Sie den obigen Code und fügen Sie ihn in die Arduino IDE ein.
  • Ändern Sie die Einstellungen im Menü Tools. Siehe die Tabelle oben.
  • Kompilieren Sie den Code und laden Sie ihn auf das ESP32 S3 Board hoch, indem Sie in der Arduino IDE auf die Schaltfläche Upload klicken.
Arduino IDE Code hochladen
  • Öffnen Sie den Seriellen Monitor in der Arduino IDE.
So öffnen Sie den Seriellen Monitor in der Arduino IDE
  • Drücken Sie einmal die Taste RESET und verlassen Sie dann den Raum für 30 Sekunden. Der Sensor wärmt sich auf.
  • Kommen Sie zurück und gehen Sie vor der Kamera vorbei.
  • Sehen Sie sich den Seriellen Monitor an. Sie sehen Motion detected! und den Namen des Fotos.
  • Profi-Tipp: Richten Sie den Sensor von Fenstern, Heizungen und Klimaanlagen weg. Sich bewegende warme Luft verursacht Fehlalarme.

Serieller Monitor

Die folgenden Messwerte wurden im Jahr 2026 aufgezeichnet:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
[2026-09-23 12:00:01] Camera sensor: OV5640 (5 MP, max QSXGA 2592x1944) [2026-09-23 12:00:01] SD card size: 15193 MB [2026-09-23 12:00:01] The next photo will be motion_00001.jpg [2026-09-23 12:00:01] The PIR sensor is warming up. Please wait 30 seconds and do not move. [2026-09-23 12:00:31] Ready. Waiting for motion... [2026-09-23 12:01:12] Motion detected! [2026-09-23 12:01:13] Saved /motion_00001.jpg (184320 bytes) [2026-09-23 12:01:45] Motion detected! [2026-09-23 12:01:46] Saved /motion_00002.jpg (183104 bytes)
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

Fehlerbehebung

Der Sensor erkennt ständig eine Bewegung, sogar in einem leeren Raum.

Probieren Sie Folgendes, eins nach dem anderen:

  • Warten Sie nach dem Start des Boards eine volle Minute. Der Sensor wärmt sich noch auf.
  • Drehen Sie die Empfindlichkeits-Schraube ein wenig nach links.
  • Richten Sie den Sensor von Fenstern, Heizungen, Klimaanlagen und Lampen weg.
  • Prüfen Sie, ob VCC an 5V liegt, nicht an 3,3V. Das ist der häufigste Fehler.

Der Sensor erkennt nie etwas.

  • Prüfen Sie den Draht am OUT-Pin. Er muss an GPIO21 gehen.
  • Drehen Sie die Empfindlichkeits-Schraube ein wenig nach rechts.
  • Gehen Sie quer vor dem Sensor vorbei, nicht direkt auf ihn zu. Ein PIR-Sensor erkennt seitliche Bewegungen viel besser.

Eine Person erzeugt fünf oder sechs Fotos.

Erhöhen Sie QUIET_TIME von 5000 auf 15000 (15 Sekunden).

Der Serielle Monitor zeigt SD card not found.

Formatieren Sie die Karte als FAT32, verwenden Sie eine Karte mit 32 GB oder weniger und stecken Sie die Karte erneut ein.

Das Foto ist dunkel.

Ein PIR-Sensor funktioniert auch im Dunkeln, die Kamera aber nicht. Fügen Sie ein Licht hinzu, oder eine Lampe, die sich bei Bewegung einschaltet.

Der Serielle Monitor zeigt nach den Startmeldungen nichts an.

Wenn Ihr USB-Kabel im Anschluss mit dem Namen UART steckt, stellen Sie USB CDC On Boot auf Disabled. Wenn es im Anschluss mit dem Namen USB steckt, stellen Sie es auf Enabled.

Anwendungen

Diese Kamera speichert alles auf der microSD-Karte, daher funktioniert sie ohne WLAN, ohne Internet und ohne monatliche Kosten. Hier sind praktische Projekte, die Sie mit diesem Code bauen können:

  1. Offline-Sicherheitskamera: Sehen Sie, wer in Ihren Raum gekommen ist, während Sie weg waren, ganz ohne Internetverbindung.
  2. Paketlieferungskamera: Nehmen Sie ein Foto auf, wenn der Zusteller an Ihrer Tür ankommt.
  3. Wild- und Tierkamera: Fotografieren Sie nachts Katzen, Vögel, Füchse oder Rehe in Ihrem Garten oder im Wald.
  4. Alarmprotokoll für Läden: Bewahren Sie ein Bild jeder Person auf, die nach Ladenschluss eintritt.
  5. Garagen- und Fahrradbeobachter: Überwachen Sie Ihr Fahrrad, Ihr Auto oder Ihr Motorrad in einer Garage ohne WLAN.
  6. Ferienhauskamera: Lassen Sie sie wochenlang in einem leeren Haus und lesen Sie die Karte, wenn Sie zurückkommen.
  7. Baustellenkamera: Bewahren Sie ein Foto von jedem auf, der die Baustelle außerhalb der Arbeitszeit betritt.
  8. Hof- und Feldkamera: Überwachen Sie ein Tor oder eine Scheune weit weg von jedem Router.
  9. Naturwissenschaftliches Schulprojekt: Zeigen Sie Schülern, wie ein Sensor, eine Kamera und eine Speicherkarte zusammenarbeiten.
  10. Ergänzung zu einer WLAN-Kamera: Behalten Sie Fotos auf der Karte, auch wenn das Internet ausfällt.

Video Tutorial

Wir erwägen die Erstellung von Video-Tutorials. Wenn Sie Video-Tutorials für wichtig halten, abonnieren Sie bitte unseren YouTube-Kanal , um uns zu motivieren, die Videos zu erstellen.

Sehen Sie sich unten die Schritt-für-Schritt-Videoanleitung für dieses ESP32 S3 Projekt an.

Herausforderungen

  1. Einsteiger: Fügen Sie eine LED hinzu, die jedes Mal für zwei Sekunden aufleuchtet, wenn ein Foto gespeichert wird.
  2. Fortgeschrittene: Speichern Sie bei jeder Bewegung drei Fotos hintereinander, sodass Sie die Richtung der Person sehen.
  3. Profis: Schreiben Sie eine Textdatei auf die Karte mit einer Zeile pro Ereignis, zum Beispiel dem Fotonamen und der Zeit seit dem Start des Boards.

※ UNSERE NACHRICHTEN

  • Sie können gerne den Link zu diesem Tutorial teilen. Bitte verwenden Sie jedoch unsere Inhalte nicht auf anderen Websites. Wir haben viel Mühe und Zeit in die Erstellung der Inhalte investiert, bitte respektieren Sie unsere Arbeit!