ESP32 S3 - Caméra

Ce tutoriel vous explique comment utiliser l'ESP32 S3 avec une caméra. L'ESP32 S3 est assez puissant pour prendre des photos et envoyer de la vidéo en direct via WiFi, afin que vous puissiez regarder la vidéo dans un navigateur web sur votre téléphone ou votre ordinateur. Ce tutoriel fonctionne avec trois capteurs de caméra : l'OV2640, l'OV3660 et l'OV5640. Le même code fonctionne pour les trois.

ESP32 S3 - Caméra

Ce que vous allez construire :

  1. Une carte caméra ESP32 S3 connectée à votre réseau WiFi
  2. Un code qui détecte automatiquement votre capteur de caméra (OV2640, OV3660 ou OV5640)
  3. Un petit serveur web qui affiche la vidéo en direct dans n'importe quel navigateur web
  4. Un second programme, plus court, qui prend une grande photo JPEG nette

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×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, de sorte 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 pour une breadboard.

À propos de la Caméra ESP32 S3

La carte caméra ESP32 S3 est une carte ESP32 S3 N16R8 avec un connecteur caméra dessus. La caméra elle-même est un petit module qui se branche sur ce connecteur avec un câble plat. La carte a 16 Mo de mémoire flash et 8 Mo de PSRAM. La PSRAM est très importante, car une photo est trop grande pour tenir dans la mémoire normale de la puce.

Module Caméra ESP32 S3

Spécifications Clés

ÉlémentValeur
MicrocontrôleurESP32 S3 (double cœur, 240 MHz)
Mémoire flash16 Mo
PSRAM8 Mo (OPI)
WiFi2,4 GHz, 802.11 b/g/n
Interface caméraDVP, parallèle 8 bits
Format d'imageJPEG, RGB565, YUV422, Niveaux de gris
Alimentation5V depuis USB Type-C

Comparaison des Capteurs de Caméra

Trois capteurs de caméra sont disponibles pour cette carte. Ils utilisent tous le même connecteur, les mêmes broches, et le même code. Ils diffèrent seulement par la taille et la qualité d'image.

CapteurRésolutionPlus Grande ImageBon Pour
OV26402 MPUXGA 1600×1200Vidéo rapide, projets simples
OV36603 MPQXGA 2048×1536Meilleur détail, encore rapide
OV56405 MPQSXGA 2592×1944Meilleure qualité photo

※ Note:

Une image plus grande n'est pas toujours meilleure. Une image plus grande prend plus de temps à envoyer via WiFi, donc la vidéo devient plus lente. Pour la vidéo en direct, une petite image comme SVGA (800×600) est habituellement le meilleur choix, même si vous avez l'OV5640.

Comment Fonctionne la Caméra ESP32 S3

Le capteur de caméra prend une image et l'envoie à l'ESP32 S3. Cela se passe en trois étapes :

  1. L'ESP32 S3 envoie un signal d'horloge à la caméra sur la broche XCLK. Cette horloge fait fonctionner la caméra.
  2. L'ESP32 S3 envoie des réglages à la caméra sur les broches SIOD et SIOC. Ces deux broches forment un bus de contrôle (similaire à I2C).
  3. La caméra renvoie les données de l'image sur 8 broches de données (D0 à D7), avec les broches PCLK, HREF et VSYNC. Ces trois broches indiquent à l'ESP32 S3 où commence chaque pixel, chaque ligne, et chaque nouvelle image.

La caméra peut compresser l'image au format JPEG toute seule. C'est important, car une image JPEG est environ 10 fois plus petite qu'une image brute. Une image plus petite signifie une vidéo plus rapide via WiFi.

L'ESP32 S3 stocke chaque image dans la PSRAM. Une image stockée s'appelle un frame buffer. Votre code demande un frame buffer, l'utilise, puis le rend à la caméra.

Noms des Tailles d'Image

La bibliothèque de la caméra utilise des noms courts pour les tailles d'image. Vous verrez ces noms dans le code :

Nom dans le codeTaille en pixelsFonctionne avec
FRAMESIZE_QVGA320 × 240Tous les capteurs
FRAMESIZE_VGA640 × 480Tous les capteurs
FRAMESIZE_SVGA800 × 600Tous les capteurs
FRAMESIZE_HD1280 × 720Tous les capteurs
FRAMESIZE_UXGA1600 × 1200Tous les capteurs
FRAMESIZE_QXGA2048 × 1536OV3660 et OV5640 seulement
FRAMESIZE_QSXGA2592 × 1944OV5640 seulement

Schéma de Câblage entre la Caméra et l'ESP32 S3

La caméra se connecte à la carte ESP32 S3 avec un câble ruban plat. Vous n'avez besoin d'aucune breadboard ni d'aucun fil de connexion.

  • Comment connecter le module caméra à la carte ESP32 S3
Schéma de Câblage Caméra ESP32 S3

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

  1. Coupez l'alimentation. Débranchez d'abord le câble USB.
  2. Trouvez le connecteur noir sur la carte. Tirez doucement la petite barre noire vers le haut.
  3. Poussez le câble plat dans le connecteur. Le côté bleu du câble est orienté vers le haut, et les contacts métalliques vers le bas.
  4. Repoussez la petite barre noire vers le bas pour verrouiller le câble.
  5. Branchez le câble USB.

Notes de Sécurité

Ne branchez ni ne débranchez jamais la caméra pendant que la carte est alimentée. Cela peut endommager le capteur de caméra. Débranchez toujours d'abord le câble USB. Aussi, ne tirez pas fort sur le câble plat, car il se casse facilement.

Le tableau ci-dessous montre comment la caméra est connectée à l'intérieur de la carte. Vous n'avez pas besoin de câbler ces broches vous-même, mais vous en avez besoin dans votre code :

Broche CaméraBroche ESP32 S3Signification
XCLKGPIO15Horloge vers la caméra
SIODGPIO4Données de contrôle
SIOCGPIO5Horloge de contrôle
VSYNCGPIO6Début d'une nouvelle image
HREFGPIO7Début d'une nouvelle ligne
PCLKGPIO13Horloge des pixels
D0GPIO11Bit de données 0
D1GPIO9Bit de données 1
D2GPIO8Bit de données 2
D3GPIO10Bit de données 3
D4GPIO12Bit de données 4
D5GPIO18Bit de données 5
D6GPIO17Bit de données 6
D7GPIO16Bit de données 7

※ Note:

Ces broches sont utilisées par la caméra. Ne les utilisez pas pour d'autres composants dans votre projet.

Réglages de l'Arduino IDE pour la Caméra ESP32 S3

La caméra ne fonctionne pas avec les réglages 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:

Deux réglages sont les plus importants :

  • PSRAM doit être OPI PSRAM. Si c'est Disabled, la caméra ne peut pas démarrer.
  • Partition Scheme doit être Huge APP. Le code de la caméra est grand, et le réglage par défaut est trop petit pour lui.

Changez d'abord Flash Size, car la liste des options de Partition Scheme change après cela.

Installer la Bibliothèque DIYables ESP32 WebServer

Ce tutoriel utilise la bibliothèque DIYables ESP32 WebServer. Cette bibliothèque rend la partie serveur web très courte et facile à lire.

  1. Ouvrez l'Arduino IDE.
  2. Cliquez sur l'icône Libraries sur la barre de gauche.
  3. Tapez DIYables ESP32 WebServer dans la boîte de recherche.
  4. Trouvez la bibliothèque par DIYables.io et cliquez sur INSTALL.
  • Search for DIYables ESP32 WebServer created by DIYables.io and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Library Manager
Type:
All
Topic:
All
DIYables ESP32 WebServer by DIYables.io
DIYables ESP32 WebServer library designed for ESP32 boards. It includes multi-page web server capabilities and WebSocket support for real-time communication, perfect for IoT projects and DIYables ESP32 boards. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32S3 Dev Module on COM15
1

La bibliothèque de la caméra (esp_camera.h) est déjà incluse dans le package de carte ESP32. Vous n'avez pas besoin de l'installer.

Comment Programmer la Caméra ESP32 S3

  • Incluez les deux bibliothèques en haut de votre code.
#include <WiFi.h> #include <DIYables_ESP32_WebServer.h> #include "esp_camera.h"
  • Mettez vos réglages de caméra dans une variable camera_config_t. Les réglages les plus importants sont le format d'image, la taille d'image, et la qualité d'image.
camera_config_t config; config.pixel_format = PIXFORMAT_JPEG; // JPEG is small and fast config.frame_size = FRAMESIZE_SVGA; // 800x600 config.jpeg_quality = 10; // 0 to 63, a lower number means a better image config.fb_count = 2; // use 2 frame buffers for smooth video
  • Démarrez la caméra avec la fonction esp_camera_init(). Elle retourne ESP_OK quand la caméra démarre correctement.
esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x\n", err); }
  • Découvrez quel capteur de caméra se trouve sur votre carte. Chaque capteur a son propre numéro d'identification, appelé PID.
sensor_t *s = esp_camera_sensor_get(); if (s->id.PID == OV2640_PID) Serial.println("This is an OV2640 camera"); else if (s->id.PID == OV3660_PID) Serial.println("This is an OV3660 camera"); else if (s->id.PID == OV5640_PID) Serial.println("This is an OV5640 camera");
  • Prenez une photo avec la fonction esp_camera_fb_get(). Cette fonction vous donne un frame buffer. La photo se trouve dans fb->buf, et sa taille en octets se trouve dans fb->len.
camera_fb_t *fb = esp_camera_fb_get(); if (fb) { Serial.printf("Photo size: %u bytes\n", fb->len); esp_camera_fb_return(fb); // give the frame buffer back }

※ Note:

Vous devez appeler esp_camera_fb_return() après chaque esp_camera_fb_get(). Si vous l'oubliez, la caméra manque de mémoire et s'arrête après quelques photos.

  • Changez l'apparence de l'image. Par exemple, retournez l'image à l'envers ou rendez-la plus lumineuse.
sensor_t *s = esp_camera_sensor_get(); s->set_vflip(s, 1); // turn the image upside down s->set_hmirror(s, 1); // mirror the image left to right s->set_brightness(s, 1); // -2 to 2 s->set_saturation(s, 0); // -2 to 2

※ Note:

L'OV3660 affiche l'image à l'envers par défaut. Le code ci-dessous corrige cela avec s->set_vflip(s, 1). Si votre propre image est à l'envers ou inversée en miroir, changez ces deux lignes.

※ Note:

La taille de l'image est différente. Choisissez-la une fois dans config.frame_size, avant esp_camera_init(). Ne la changez pas plus tard pendant que le code s'exécute, sinon la caméra affichera l'erreur cam_hal: FB-OVF et arrêtera de vous donner des images.

Passons maintenant à la partie serveur web. La bibliothèque DIYables ESP32 WebServer n'a besoin que de trois choses : créer le serveur, ajouter vos adresses, et appeler handleClient() encore et encore.

  • Créez le serveur web sur le port 80.
DIYables_ESP32_WebServer server(80);
  • Écrivez une fonction pour chaque adresse. Chaque fonction doit avoir exactement ces cinq paramètres.
void handleHome(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { server.sendResponse(client, INDEX_HTML, "text/html"); }
  • Ajoutez vos adresses à l'intérieur de setup() et démarrez le serveur.
server.addRoute("/", handleHome); server.addRoute("/stream", handleStream); server.begin();

※ Note:

Utilisez server.begin() et connectez-vous vous-même au WiFi. N'utilisez pas server.begin(ssid, password) dans ce projet, car cette version règle la vitesse du Serial Monitor à 9600, et vous ne pourrez alors pas lire les messages à 115200.

  • Pour envoyer de la vidéo en direct, envoyez de nombreuses photos les unes après les autres, et mettez un texte séparateur entre elles. Cela s'appelle un flux MJPEG. Chaque navigateur web le comprend. Une image n'est pas du texte, donc vous devez utiliser client.write() et non client.print().
while (client.connected()) { camera_fb_t *fb = esp_camera_fb_get(); size_t len = fb->len; client.print("--" BOUNDARY "\r\n"); client.print("Content-Type: image/jpeg\r\n"); client.printf("Content-Length: %u\r\n\r\n", len); client.write(fb->buf, len); client.print("\r\n"); esp_camera_fb_return(fb); }
  • Appelez handleClient() à l'intérieur de loop(). Sans cette ligne, le serveur web ne fait rien.
void loop() { server.handleClient(); }

※ Note:

Pendant qu'une personne regarde la vidéo, l'ESP32 S3 est occupé et ne peut pas répondre à une seconde personne. C'est normal pour une petite carte. Ouvrez la vidéo sur un seul appareil à la fois.

Code ESP32 S3 - Exemple 1 : Vidéo en Direct

Ceci est l'exemple simple. Il démarre la caméra, se connecte à votre réseau WiFi, et affiche la vidéo en direct dans un navigateur web. Commencez par celui-ci.

Le serveur web a deux adresses :

  • http://<IP>/ affiche une page web avec la vidéo en direct
  • http://<IP>/stream est la vidéo en direct seule

Le code lit l'ID du capteur et règle automatiquement les bons réglages pour l'OV2640, l'OV3660 ou l'OV5640. Vous n'avez pas besoin de changer le code pour votre caméra.

/* * 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 */ #include <WiFi.h> #include <DIYables_ESP32_WebServer.h> // DIYables ESP32 WebServer library #include "esp_camera.h" const char *WIFI_SSID = "YOUR_WIFI_SSID"; // CHANGE IT const char *WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"; // CHANGE IT // 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 DIYables_ESP32_WebServer server(80); // The text that separates one image from the next image in the video #define BOUNDARY "diyablesframe" const char INDEX_HTML[] = R"rawliteral( <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 S3 Camera</title> <style> body { background:#111; color:#eee; font-family:sans-serif; text-align:center; margin:0; padding:16px; } img { width:100%; max-width:800px; border-radius:8px; } </style> </head> <body> <h2>ESP32 S3 Camera</h2> <img src="/stream"> </body> </html> )rawliteral"; // 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_SVGA; // 800x600 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; } // Shows the web page with the live video void handleHome(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { server.sendResponse(client, INDEX_HTML, "text/html"); } // Sends the live video to the web browser void handleStream(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { Serial.println("Video stream started"); client.print("HTTP/1.1 200 OK\r\n"); client.print("Content-Type: multipart/x-mixed-replace; boundary=" BOUNDARY "\r\n"); client.print("Access-Control-Allow-Origin: *\r\n"); client.print("Connection: close\r\n\r\n"); while (client.connected()) { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Frame capture failed"); break; } size_t len = fb->len; client.print("--" BOUNDARY "\r\n"); client.print("Content-Type: image/jpeg\r\n"); client.printf("Content-Length: %u\r\n\r\n", len); size_t sent = client.write(fb->buf, len); client.print("\r\n"); esp_camera_fb_return(fb); if (sent != len) { // the web browser closed the video break; } } Serial.println("Video stream stopped"); } void setup() { Serial.begin(115200); delay(1000); if (!initCamera()) { Serial.println("Stopped"); while (true) delay(1000); } WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); WiFi.setSleep(false); // keep WiFi fast for the video server.addRoute("/", handleHome); server.addRoute("/stream", handleStream); server.begin(); Serial.print("Camera is ready. Open this address in your web browser: http://"); Serial.println(WiFi.localIP()); } void loop() { server.handleClient(); }

Étapes Rapides

  • Nouveau sur ESP32 S3 ? Terminez d'abord notre guide ESP32 S3 - Premiers pas.
  • Connectez le module caméra à la carte. Rappel : débranchez d'abord le câble USB.
  • Installez la bibliothèque DIYables ESP32 WebServer. Voir les étapes ci-dessus.
  • Copiez le code ci-dessus et collez-le dans l'Arduino IDE.
  • Changez YOUR_WIFI_SSID et YOUR_WIFI_PASSWORD par le nom et le mot de passe de votre réseau WiFi.
  • Changez les réglages dans le menu Tools. Voir le tableau ci-dessus.
  • Compilez et téléversez le code sur la carte ESP32 S3 en cliquant sur le bouton Upload dans l'Arduino IDE.
Téléverser le code sur Arduino IDE
  • Ouvrez le Serial Monitor dans l'Arduino IDE.
Comment ouvrir le Serial Monitor sur Arduino IDE
  • Appuyez une fois sur le bouton RESET de la carte.
  • Lisez l'adresse IP dans le Serial Monitor.
  • Tapez cette adresse dans votre navigateur web et regardez la vidéo en direct.
  • Astuce : Votre ordinateur ou votre téléphone doit être sur le même réseau WiFi que l'ESP32 S3. S'ils sont sur des réseaux différents, la page ne s'ouvrira pas.

Serial Monitor

Après le téléversement, le Serial Monitor affiche le nom de votre capteur de caméra et l'adresse IP de la caméra. 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 10:00:01] Camera sensor: OV5640 (5 MP, max QSXGA 2592x1944) [2026-09-23 10:00:01] Connecting to WiFi... [2026-09-23 10:00:04] Starting web server on IP: 192.168.0.2 [2026-09-23 10:00:04] Camera is ready. Open this address in your web browser: http://192.168.0.2 [2026-09-23 10:00:15] Method: GET [2026-09-23 10:00:15] Requested path: / [2026-09-23 10:00:15] Client disconnected [2026-09-23 10:00:15] Method: GET [2026-09-23 10:00:15] Requested path: /stream [2026-09-23 10:00:15] Video stream started
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

※ Note:

Les lignes Method: GET, Requested path: / et Client disconnected viennent de la bibliothèque DIYables ESP32 WebServer. Elles vous indiquent que le navigateur web a atteint votre carte. C'est normal.

La ligne avec le nom du capteur est différente pour chaque caméra :

Votre CaméraLigne dans le Serial Monitor
OV2640Camera sensor: OV2640 (2 MP, max UXGA 1600x1200)
OV3660Camera sensor: OV3660 (3 MP, max QXGA 2048x1536)
OV5640Camera sensor: OV5640 (5 MP, max QSXGA 2592x1944)

Maintenant ouvrez l'adresse IP dans votre navigateur web. Vous verrez la vidéo en direct de la caméra :

Vidéo en Direct de la Caméra ESP32 S3 dans un Navigateur Web

Code ESP32 S3 - Exemple 2 : Prendre une Photo

Cet exemple n'utilise pas la vidéo. Il prend seulement une photo. Le code est plus court et plus facile à lire, donc c'est un bon endroit pour commencer si la vidéo semble trop difficile.

Le serveur web a deux adresses :

  • http://<IP>/ affiche la page web avec la photo
  • http://<IP>/photo est la photo seule

Chaque fois que la page s'ouvre, l'ESP32 S3 prend une nouvelle photo. Pour prendre une autre photo, cliquez sur le lien Take a new photo.

/* * 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 */ #include <WiFi.h> #include <DIYables_ESP32_WebServer.h> // DIYables ESP32 WebServer library #include "esp_camera.h" const char *WIFI_SSID = "YOUR_WIFI_SSID"; // CHANGE IT const char *WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"; // CHANGE IT // 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 DIYables_ESP32_WebServer server(80); const char INDEX_HTML[] = R"rawliteral( <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 S3 Camera</title> <style> body { background:#111; color:#eee; font-family:sans-serif; text-align:center; margin:0; padding:16px; } img { width:100%; max-width:800px; border-radius:8px; } a { color:#4da3ff; font-size:18px; } </style> </head> <body> <h2>ESP32 S3 Camera</h2> <img src="/photo"> <p><a href="/">Take a new photo</a></p> </body> </html> )rawliteral"; // 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; } // Shows the web page void handleHome(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { server.sendResponse(client, INDEX_HTML, "text/html"); } // Takes one photo and sends it to the web browser void handlePhoto(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Photo capture failed"); server.sendResponse(client, "Photo capture failed", "text/plain"); return; } Serial.printf("Photo taken: %u bytes\n", fb->len); client.print("HTTP/1.1 200 OK\r\n"); client.print("Content-Type: image/jpeg\r\n"); client.print("Content-Disposition: inline; filename=photo.jpg\r\n"); client.printf("Content-Length: %u\r\n", fb->len); client.print("Connection: close\r\n\r\n"); client.write(fb->buf, fb->len); esp_camera_fb_return(fb); // give the memory back to the camera } void setup() { Serial.begin(115200); delay(1000); if (!initCamera()) { Serial.println("Stopped"); while (true) delay(1000); } WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); server.addRoute("/", handleHome); server.addRoute("/photo", handlePhoto); server.begin(); Serial.print("Camera is ready. Open this address in your web browser: http://"); Serial.println(WiFi.localIP()); } void loop() { server.handleClient(); }

Comment Ça Fonctionne

La page web n'a que deux lignes importantes :

<img src="/photo"> <p><a href="/">Take a new photo</a></p>

Le navigateur web lit <img src="/photo"> et demande à l'ESP32 S3 l'adresse /photo. La fonction handlePhoto() prend une photo et la renvoie comme image JPEG. Le lien / rouvre la page, donc la caméra prend une nouvelle photo. Vous n'avez besoin d'aucun JavaScript.

※ Note:

Cet exemple utilise une grande taille d'image (FRAMESIZE_UXGA, 1600×1200), car une photo n'a pas besoin d'être rapide. L'Exemple 1 utilise une petite taille (FRAMESIZE_SVGA, 800×600), car une petite image voyage plus vite via WiFi, et la vidéo a besoin de nombreuses images chaque seconde.

※ Note:

Vous voulez une photo encore plus grande ? Changez config.frame_size en FRAMESIZE_QXGA (OV3660 et OV5640 seulement) ou en FRAMESIZE_QSXGA (OV5640 seulement). Une photo plus grande a besoin de plus de PSRAM et de plus de temps.

Étapes Rapides

  • Copiez le code ci-dessus et collez-le dans l'Arduino IDE.
  • Changez YOUR_WIFI_SSID et YOUR_WIFI_PASSWORD de nouveau.
  • Téléversez le code et appuyez une fois sur le bouton RESET.
  • Ouvrez l'adresse IP dans votre navigateur web. La photo apparaît.
  • Cliquez sur Take a new photo pour en prendre une autre.
  • Pour garder une photo, faites un clic droit sur l'image et choisissez Save image as...
Photo de la Caméra ESP32 S3 dans un Navigateur Web

Le Serial Monitor affiche la taille de chaque photo :

∞
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 10:05:02] Camera sensor: OV5640 (5 MP, max QSXGA 2592x1944) [2026-09-23 10:05:02] Connecting to WiFi... [2026-09-23 10:05:05] Starting web server on IP: 192.168.0.2 [2026-09-23 10:05:05] Camera is ready. Open this address in your web browser: http://192.168.0.2 [2026-09-23 10:05:20] Method: GET [2026-09-23 10:05:20] Requested path: / [2026-09-23 10:05:20] Client disconnected [2026-09-23 10:05:20] Method: GET [2026-09-23 10:05:20] Requested path: /photo [2026-09-23 10:05:21] Photo taken: 184320 bytes
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

Dépannage

Voici les problèmes que les débutants rencontrent le plus souvent, et comment les résoudre.

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

Le réglage USB CDC On Boot ne correspond pas à votre port USB. Si votre câble USB est dans le port nommé UART, réglez USB CDC On Boot sur Disabled. Si votre câble est dans le port nommé USB, réglez-le sur Enabled. Puis téléversez le code à nouveau. Vérifiez aussi que la boîte de vitesse dans le Serial Monitor affiche 115200.

Le Serial Monitor affiche Camera init failed with error 0x105.

La caméra ne peut pas démarrer. Il y a trois raisons courantes :

  • PSRAM est sur Disabled. Réglez-le sur OPI PSRAM dans le menu Tools.
  • Le câble plat est lâche ou dans le mauvais sens. Débranchez le câble USB, ouvrez le connecteur, et remettez le câble.
  • L'horloge est trop rapide pour votre module caméra. Changez config.xclk_freq_hz de 20000000 à 10000000 dans le code.

Le Serial Monitor affiche WARNING: PSRAM not found.

Réglez PSRAM sur OPI PSRAM dans le menu Tools et téléversez le code à nouveau.

Le téléversement échoue, ou le port COM n'apparaît pas.

Appuyez et maintenez le bouton BOOT, appuyez une fois sur le bouton RESET, puis relâchez le bouton BOOT. Maintenant le port apparaît dans le menu Tools. Après la fin du téléversement, appuyez une fois sur RESET.

Le Serial Monitor affiche l'adresse IP, mais la page web ne s'ouvre pas.

Votre ordinateur et votre ESP32 S3 sont probablement sur des réseaux différents. Les deux doivent être sur le même réseau WiFi. Aussi, tapez http:// et non https://, car l'ESP32 S3 n'utilise pas https.

La vidéo est lente, ou elle s'arrête après quelques secondes.

L'image est trop grande pour votre WiFi. Changez config.frame_size pour une taille plus petite, comme FRAMESIZE_VGA ou FRAMESIZE_QVGA. Vous pouvez aussi augmenter config.jpeg_quality à 15, ce qui fait un fichier plus petit.

Le Serial Monitor affiche cam_hal: FB-OVF et Photo capture failed.

FB-OVF signifie « débordement du frame buffer » : l'image est plus grande que la mémoire prête pour elle. Choisissez votre taille d'image une seule fois, dans config.frame_size, avant d'appeler esp_camera_init(). Ne changez pas la taille plus tard avec s->set_framesize(), car cette fonction change le capteur de caméra sans agrandir la mémoire. Si vous avez vraiment besoin de changer la taille pendant que le code s'exécute, utilisez plutôt la fonction esp_camera_reconfigure().

La photo prend beaucoup de temps, ou la page attend.

Une grande photo a besoin de temps. FRAMESIZE_UXGA prend environ une seconde. Utilisez FRAMESIZE_XGA ou FRAMESIZE_SVGA si vous voulez une photo plus rapide.

La photo échoue à chaque essai.

Votre taille d'image est trop grande pour la mémoire libre. Utilisez une taille plus petite, comme FRAMESIZE_XGA, ou réglez config.fb_count à 1.

L'image est à l'envers ou inversée en miroir.

Changez les deux lignes s->set_vflip(s, 0) et s->set_hmirror(s, 0) dans le code. Utilisez 1 au lieu de 0.

Applications

Une caméra ESP32 S3 est petite, peu chère, et fonctionne via WiFi, donc une seule carte remplace une caméra IP coûteuse. Voici des projets pratiques que vous pouvez construire avec ce code :

  1. Caméra de sécurité maison WiFi : Surveillez votre porte ou votre fenêtre depuis votre téléphone, sans paiement mensuel.
  2. Caméra pour animaux de compagnie (chiens et chats) : Voyez ce que fait votre animal quand vous n'êtes pas à la maison.
  3. Moniteur d'imprimante 3D : Surveillez une longue impression depuis une autre pièce, et arrêtez-la tôt quand ça va mal.
  4. Sonnette vidéo : Prenez une photo quand quelqu'un appuie sur le bouton à votre porte.
  5. Caméra de chambre de bébé ou d'enfant : Regardez dans la pièce depuis votre téléphone sans ouvrir la porte.
  6. Enregistreur de croissance de plante : Prenez une photo toutes les heures et joignez-les en une vidéo time-lapse.
  7. Caméra de voiture robot : Donnez des yeux à un petit robot, et conduisez-le depuis une autre pièce.
  8. Caméra de drone et RC : Envoyez de la vidéo en direct depuis une voiture modèle réduit, un bateau, ou un petit drone.
  9. Observateur d'aquarium et de serre : Gardez un œil sur vos poissons ou vos plantes pendant que vous voyagez.
  10. Moniteur de machine et d'atelier : Surveillez une machine, une ferme d'imprimantes 3D, ou une découpeuse laser pendant qu'elle fonctionne.
  11. Caméra de magasin et de réception : Montrez la porte de votre magasin sur un écran au fond de la pièce.
  12. Projet d'apprentissage pour étudiants : Un exemple complet d'une caméra, d'un serveur web et de WiFi dans une seule petite carte.

Vidéo

Regardez la vidéo étape par étape pour ce projet ESP32 S3 ci-dessous.

Défis

Maintenant que vous avez une caméra fonctionnelle sur l'ESP32 S3, essayez d'étendre le projet avec ces exercices pour approfondir votre compréhension.

  1. Débutant : Changez la taille d'image dans le code de FRAMESIZE_SVGA à FRAMESIZE_VGA, puis à FRAMESIZE_UXGA. Observez comment la vitesse de la vidéo change.
  2. Intermédiaire : Ajoutez un bouton à la carte. Quand quelqu'un appuie sur le bouton, prenez une photo et enregistrez-la sur la carte SD.
  3. Avancé : Prenez une photo toutes les 10 minutes et envoyez-la sur votre téléphone avec un bot Telegram, afin d'avoir une image même quand vous êtes loin de chez vous.

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 !