Caméra ESP32 S3 - Enregistrer une photo sur carte SD lors d'une détection de mouvement

Ce tutoriel vous explique comment construire une petite caméra de sécurité avec l'ESP32 S3. Un capteur de mouvement PIR surveille la pièce. Quand quelqu'un marche devant lui, l'ESP32 S3 prend une photo et l'enregistre sur une carte microSD. La carte fonctionne seule. Elle n'a pas besoin de WiFi, et elle n'a pas besoin d'ordinateur.

ESP32 S3 Camera - Save Photo to SD Card When Motion Detected

Ce que vous allez construire :

  1. Une caméra ESP32 S3 avec un capteur de mouvement PIR
  2. Une photo enregistrée sur la carte microSD chaque fois que le capteur voit un mouvement
  3. Un temps calme, pour qu'une personne qui marche ne remplisse pas votre carte de 50 photos
  4. Une caméra qui fonctionne sans internet

Matériel requis

1×ESP32 S3 N16R8 OV5640 Camera
1×Alternativement: ESP32 S3 N16R8 OV2640 Camera
1×Câble USB Type-A vers Type-C (pour PC USB-A)
1×Câble USB Type-C vers Type-C (pour PC USB-C)
1×Capteur de mouvement HC-SR501
1×microSD Card
1×Fils de connexion
1×Optionnel: Connecteur d'alimentation DC
1×Recommandé: Screw Terminal Expansion Board for ESP32 S3
1×Recommandé: Breakout Expansion Board for ESP32 S3
1×Recommandé: Power Splitter for ESP32 S3

Ou vous pouvez acheter les kits suivants:

1×Kit de Capteurs DIYables (18 capteurs/écrans)
Divulgation : Certains des liens fournis dans cette section sont des liens affiliés Amazon. Nous pouvons recevoir une commission pour tout achat effectué via ces liens, sans coût supplémentaire pour vous. Nous vous remercions de votre soutien.

※ Note:

La carte caméra ESP32 S3 a 40 broches, mais le bornier à vis et la carte d'extension ont 44 broches. Elles fonctionnent quand même ensemble. Placez la carte caméra au centre de la carte à 44 broches, afin que 2 broches restent libres à gauche et 2 broches restent libres à droite.

Le bornier à vis vous permet de connecter des fils avec un tournevis, sans soudure. La carte d'extension vous donne des broches faciles à utiliser pour une plaque d'essai.

À propos du capteur de mouvement PIR

Un capteur de mouvement PIR voit la chaleur d'un corps humain. PIR signifie « Passive InfraRed » (infrarouge passif). Le capteur n'envoie rien. Il écoute seulement la lumière infrarouge (la chaleur) autour de lui. Quand un corps chaud bouge devant lui, la répartition de chaleur change, et le capteur le signale à l'ESP32 S3.

PIR Motion Sensor HC-SR501

Pour plus de détails sur le capteur de mouvement, consultez le tutoriel ESP32 S3 - Capteur de mouvement.

Spécifications clés

ÉlémentValeur
Alimentation5V
Sortie3,3V HIGH quand il voit un mouvement, LOW quand il ne voit rien
Distance3 à 7 mètres (vous pouvez la changer)
Angleenviron 110°
Temps de préchauffage30 à 60 secondes après la mise sous tension

※ Note:

La sortie du HC-SR501 est en 3,3V, donc vous pouvez le connecter directement à une broche de l'ESP32 S3. C'est sûr.

Brochage du capteur de mouvement PIR

Le capteur a 3 broches :

  1. Broche VCC : connectez cette broche au 5V
  2. Broche GND : connectez cette broche au GND
  3. Broche OUT : passe à HIGH quand le capteur voit un mouvement
PIR Motion Sensor Pinout

Les deux vis orange

Le HC-SR501 a deux petites vis orange. Tournez-les avec un petit tournevis :

VisCe qu'elle changeTourner à droite (sens horaire)
SensibilitéÀ quelle distance le capteur voitVoit plus loin (jusqu'à 7 m)
DélaiCombien de temps la sortie reste HIGHReste HIGH plus longtemps (jusqu'à 5 minutes)

※ Note:

Pour ce projet, tournez la vis délai complètement vers la gauche. La sortie reste alors HIGH pendant environ 3 secondes seulement, afin que le capteur soit à nouveau prêt rapidement.

Le cavalier à deux positions

À côté des broches, il y a un petit cavalier :

PositionNomCe qui se passe
HRépétitionLa sortie reste HIGH tant que le mouvement continue
LSimpleLa sortie passe à HIGH une fois, puis à LOW

Les deux positions fonctionnent avec ce code. H est le choix habituel.

Comment fonctionne le projet

Le code surveille la broche OUT en permanence. Il ne cherche pas « la broche est à HIGH ». Il cherche le moment où la broche passe de LOW à HIGH :

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

C'est important. Si le code cherchait seulement HIGH, il prendrait une nouvelle photo des centaines de fois par seconde pendant qu'une personne se tient devant la caméra.

Schéma de câblage entre le capteur de mouvement PIR et l'ESP32 S3

Connectez le capteur de mouvement PIR à votre ESP32 S3 avec trois fils de raccordement.

ESP32 S3 PIR Motion Sensor Wiring Diagram

Cette image a été créée avec Fritzing. Cliquez pour agrandir l'image.

Broche du capteur PIRBroche ESP32 S3
VCC5V
GNDGND
OUTGPIO21

Ensuite, insérez la carte microSD dans la fente de la carte.

Notes de sécurité

Le capteur PIR a besoin de 5V sur sa broche VCC, pas de 3,3V. Avec 3,3V, il semble fonctionner, mais il donne des signaux erronés. Sa broche OUT donne 3,3V, ce qui est correct pour l'ESP32 S3.

N'utilisez pas une broche de caméra pour le capteur. La caméra utilise déjà les GPIO4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17 et 18. La fente de carte utilise les GPIO38, 39 et 40. GPIO21 est libre, donc nous l'utilisons.

Paramètres de l'Arduino IDE pour la caméra ESP32 S3

La caméra ne fonctionne pas avec les paramètres par défaut de l'Arduino IDE. Vous devez changer certains éléments dans le menu Tools avant de téléverser le code.

Élément du menu ToolsSélectionnez ceci
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

※ Note:

PSRAM doit être OPI PSRAM, et Partition Scheme doit être Huge APP. Changez d'abord Flash Size, car la liste des options de Partition Scheme change ensuite.

Comment programmer la caméra à détection de mouvement

  • Configurez la broche du capteur en entrée.
#define PIR_PIN 21 pinMode(PIR_PIN, INPUT);
  • Attendez le capteur après avoir démarré la carte. Un capteur PIR a besoin de 30 à 60 secondes pour apprendre la chaleur de la pièce. Avant cela, il donne de fausses alertes.
Serial.println("The PIR sensor is warming up. Please wait 30 seconds and do not move."); delay(30000);
  • Cherchez le moment où la broche passe de LOW à HIGH.
int pirState = digitalRead(PIR_PIN); if (lastPirState == LOW && pirState == HIGH) { Serial.println("Motion detected!"); takeAndSavePhoto(); } lastPirState = pirState; // remember the state for the next time
  • Ajoutez un temps calme. Sans cela, une personne qui marche lentement fait dix photos.
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);

Code ESP32 S3

Le code suivant enregistre une photo nommée motion_00001.jpg, motion_00002.jpg, et ainsi de suite, chaque fois que le capteur voit un mouvement. Le temps calme est de 5 secondes. Pour le changer, modifiez la ligne #define QUIET_TIME 5000.

/* * Ce code ESP32 S3 a été développé par newbiely.fr * Ce code ESP32 S3 est mis à disposition du public sans aucune restriction. * Pour des instructions complètes et des schémas de câblage, veuillez visiter: * https://newbiely.fr/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; }

Étapes rapides

  • Nouveau sur ESP32 S3 ? Suivez d'abord notre guide ESP32 S3 - Premiers pas.
  • Formatez votre carte microSD en FAT32 sur votre ordinateur.
  • Débranchez le câble USB. Insérez la carte dans la fente, et câblez le capteur PIR comme dans le tableau ci-dessus.
  • Tournez la vis délai du capteur complètement vers la gauche.
  • Copiez le code ci-dessus et collez-le dans l'Arduino IDE.
  • Changez les paramètres dans le menu Tools. Voir le tableau ci-dessus.
  • Compilez et téléversez le code vers la carte ESP32 S3 en cliquant sur le bouton Upload dans Arduino IDE.
Arduino IDE Upload Code
  • Ouvrez le Serial Monitor dans Arduino IDE.
How to open serial monitor on Arduino IDE
  • Appuyez une fois sur le bouton RESET, puis quittez la pièce pendant 30 secondes. Le capteur préchauffe.
  • Revenez et marchez devant la caméra.
  • Regardez le Serial Monitor. Vous voyez Motion detected! et le nom de la photo.
  • Astuce pro : Pointez le capteur loin des fenêtres, des chauffages et des climatiseurs. L'air chaud en mouvement provoque de fausses alertes.

Moniteur série

Les relevés suivants ont été capturés en 2026 :

∞
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

Dépannage

Le capteur voit un mouvement en permanence, même dans une pièce vide.

Essayez ceci, un par un :

  • Attendez une minute complète après avoir démarré la carte. Le capteur préchauffe encore.
  • Tournez la vis sensibilité un peu vers la gauche.
  • Pointez le capteur loin des fenêtres, chauffages, climatiseurs et lampes.
  • Vérifiez que VCC est sur 5V, pas sur 3,3V. C'est l'erreur la plus courante.

Le capteur ne voit jamais rien.

  • Vérifiez le fil sur la broche OUT. Il doit aller à GPIO21.
  • Tournez la vis sensibilité un peu vers la droite.
  • Marchez en travers devant le capteur, pas droit vers lui. Un capteur PIR voit bien mieux le mouvement latéral.

Une personne fait cinq ou six photos.

Augmentez QUIET_TIME de 5000 à 15000 (15 secondes).

Le Serial Monitor affiche SD card not found.

Formatez la carte en FAT32, utilisez une carte de 32 Go ou moins, et réinsérez la carte.

La photo est sombre.

Un capteur PIR fonctionne aussi dans le noir, mais pas la caméra. Ajoutez une lumière, ou une lampe qui s'allume avec le mouvement.

Le Serial Monitor n'affiche rien après les messages de démarrage.

Si votre câble USB est dans le port nommé UART, réglez USB CDC On Boot sur Disabled. S'il est dans le port nommé USB, réglez-le sur Enabled.

Applications

Cette caméra garde tout sur la carte microSD, donc elle fonctionne sans WiFi, sans internet et sans abonnement mensuel. Voici des projets pratiques que vous pouvez construire avec ce code :

  1. Caméra de sécurité hors ligne : Voyez qui est entré dans votre pièce pendant votre absence, sans aucune connexion internet.
  2. Caméra de livraison de colis : Prenez une photo quand le livreur arrive à votre porte.
  3. Caméra de faune et de sentier : Photographiez des chats, oiseaux, renards ou cerfs dans votre jardin ou en forêt la nuit.
  4. Enregistrement d'alarme de magasin : Gardez une photo de chaque personne qui entre après l'heure de fermeture.
  5. Surveillance de garage et de vélo : Surveillez votre vélo, votre voiture ou votre moto dans un garage sans WiFi.
  6. Caméra de maison de vacances : Laissez-la dans une maison vide pendant des semaines, et lisez la carte à votre retour.
  7. Caméra de chantier : Gardez une photo de tous ceux qui entrent sur le site en dehors des heures de travail.
  8. Caméra de ferme et de champ : Surveillez un portail ou une grange loin de tout routeur.
  9. Projet scientifique de classe : Montrez aux élèves comment un capteur, une caméra et une carte mémoire fonctionnent ensemble.
  10. Sauvegarde pour une caméra WiFi : Gardez des photos sur la carte même quand internet est en panne.

Vidéo

Regardez la démonstration vidéo étape par étape de ce projet ESP32 S3 ci-dessous.

Défis

  1. Débutant : Ajoutez une LED qui s'allume pendant deux secondes chaque fois qu'une photo est enregistrée.
  2. Intermédiaire : Enregistrez trois photos d'affilée à chaque mouvement, afin de voir la direction de la personne.
  3. Avancé : Écrivez un fichier texte sur la carte avec une ligne par événement, par exemple le nom de la photo et le temps écoulé depuis le démarrage de la carte.

Commentaires

※ NOS MESSAGES

  • N'hésitez pas à partager le lien de ce tutoriel. Cependant, veuillez ne pas utiliser notre contenu sur d'autres sites web. Nous avons investi beaucoup d'efforts et de temps pour créer ce contenu, veuillez respecter notre travail !