├── .gitattributes ├── ESP32-CAM simplified code ├── .gitignore ├── platformio.ini ├── test │ └── README ├── lib │ └── README ├── include │ └── README └── src │ ├── camera_pins.h │ └── main.cpp ├── LICENSE ├── ESP32-CAM CameraWebServer modified ├── LICENSE ├── README.md └── esp32-cam.ino └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ESP32-CAM simplified code/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | .DS_Store 7 | .vscode/* -------------------------------------------------------------------------------- /ESP32-CAM simplified code/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32cam] 12 | platform = espressif32 13 | board = esp32cam 14 | framework = arduino 15 | monitor_speed = 115200 -------------------------------------------------------------------------------- /ESP32-CAM simplified code/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Projets DIY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ESP32-CAM CameraWebServer modified/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Projets DIY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ESP32-CAM simplified code/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /ESP32-CAM simplified code/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # List of ESP32-CAM projects 2 | 3 | 1. Project installed with the ESP32 library for Arduino modified 4 | * The video stream can be easily retrieved from a home automation server at the address IP_Camera / stream 5 | * A snapshot can be retrieved from the address IP_Camera / jpg / image.jpg 6 | 7 | 8 | ______ 9 | # Liste des projets ESP32-CAM 10 | 11 | 1. [Projet installé avec la librairie ESP32 pour Arduino modifiée](). 12 | * Le flux vidéo peut être récupéré facilement depuis un serveur domotique à l'adresse IP_Camera/stream 13 | * Un snapshot peut être récupéré à l'adresse IP_Camera/jpg/image.jpg 14 | 2. [5 astuces pour ESP32-CAM. Version simplifiée du code HTML et C++]() Adresse IP fixe. Mode AP. Rotation image 90°. Récupération automatique connexion WiFi. stockage du code HTML 15 | 16 | ## D'autres tutoriels pour débuter aec l'ESP32-CAM 17 | 18 | * [ESP32-CAM. Migrer le projet CameraWebServer pour l’IDE Arduino vers PlatformIO](https://projetsdiy.fr/esp32-cam-migrer-projet-camerawebserver-ide-arduino-platformio/) 19 | * [ESP32-CAM, flash du firmware officiel modifié avec capture d’image](https://projetsdiy.fr/esp32-cam-aithinker-flash-firmware-test/) 20 | * [Intégrer un module ESP32-CAM à un Dashboard Node-RED (firmware modifié)](https://projetsdiy.fr/integrer-esp32-cam-dashboard-node-red-firmware-modifie/) 21 | * [Intégrer un module ESP32-CAM à Domoticz (firmware modifié)](https://projetsdiy.fr/integrer-module-esp32-cam-domoticz-firmware-modifie/) 22 | * [Intégrer un module ESP32-CAM à Jeedom ou NextDom (firmware modifié)](https://projetsdiy.fr/integrer-module-esp32-cam-jeedom-nextdom/) 23 | * [Intégrer un module ESP32-CAM à Home Assistant (firmware officiel)](https://projetsdiy.fr/integrer-module-esp32-cam-home-assistant/) -------------------------------------------------------------------------------- /ESP32-CAM simplified code/src/camera_pins.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(CAMERA_MODEL_WROVER_KIT) 3 | #define PWDN_GPIO_NUM -1 4 | #define RESET_GPIO_NUM -1 5 | #define XCLK_GPIO_NUM 21 6 | #define SIOD_GPIO_NUM 26 7 | #define SIOC_GPIO_NUM 27 8 | 9 | #define Y9_GPIO_NUM 35 10 | #define Y8_GPIO_NUM 34 11 | #define Y7_GPIO_NUM 39 12 | #define Y6_GPIO_NUM 36 13 | #define Y5_GPIO_NUM 19 14 | #define Y4_GPIO_NUM 18 15 | #define Y3_GPIO_NUM 5 16 | #define Y2_GPIO_NUM 4 17 | #define VSYNC_GPIO_NUM 25 18 | #define HREF_GPIO_NUM 23 19 | #define PCLK_GPIO_NUM 22 20 | 21 | #elif defined(CAMERA_MODEL_ESP_EYE) 22 | #define PWDN_GPIO_NUM -1 23 | #define RESET_GPIO_NUM -1 24 | #define XCLK_GPIO_NUM 4 25 | #define SIOD_GPIO_NUM 18 26 | #define SIOC_GPIO_NUM 23 27 | 28 | #define Y9_GPIO_NUM 36 29 | #define Y8_GPIO_NUM 37 30 | #define Y7_GPIO_NUM 38 31 | #define Y6_GPIO_NUM 39 32 | #define Y5_GPIO_NUM 35 33 | #define Y4_GPIO_NUM 14 34 | #define Y3_GPIO_NUM 13 35 | #define Y2_GPIO_NUM 34 36 | #define VSYNC_GPIO_NUM 5 37 | #define HREF_GPIO_NUM 27 38 | #define PCLK_GPIO_NUM 25 39 | 40 | #elif defined(CAMERA_MODEL_M5STACK_PSRAM) 41 | #define PWDN_GPIO_NUM -1 42 | #define RESET_GPIO_NUM 15 43 | #define XCLK_GPIO_NUM 27 44 | #define SIOD_GPIO_NUM 25 45 | #define SIOC_GPIO_NUM 23 46 | 47 | #define Y9_GPIO_NUM 19 48 | #define Y8_GPIO_NUM 36 49 | #define Y7_GPIO_NUM 18 50 | #define Y6_GPIO_NUM 39 51 | #define Y5_GPIO_NUM 5 52 | #define Y4_GPIO_NUM 34 53 | #define Y3_GPIO_NUM 35 54 | #define Y2_GPIO_NUM 32 55 | #define VSYNC_GPIO_NUM 22 56 | #define HREF_GPIO_NUM 26 57 | #define PCLK_GPIO_NUM 21 58 | 59 | #elif defined(CAMERA_MODEL_M5STACK_WIDE) 60 | #define PWDN_GPIO_NUM -1 61 | #define RESET_GPIO_NUM 15 62 | #define XCLK_GPIO_NUM 27 63 | #define SIOD_GPIO_NUM 22 64 | #define SIOC_GPIO_NUM 23 65 | 66 | #define Y9_GPIO_NUM 19 67 | #define Y8_GPIO_NUM 36 68 | #define Y7_GPIO_NUM 18 69 | #define Y6_GPIO_NUM 39 70 | #define Y5_GPIO_NUM 5 71 | #define Y4_GPIO_NUM 34 72 | #define Y3_GPIO_NUM 35 73 | #define Y2_GPIO_NUM 32 74 | #define VSYNC_GPIO_NUM 25 75 | #define HREF_GPIO_NUM 26 76 | #define PCLK_GPIO_NUM 21 77 | 78 | #elif defined(CAMERA_MODEL_AI_THINKER) 79 | #define PWDN_GPIO_NUM 32 80 | #define RESET_GPIO_NUM -1 81 | #define XCLK_GPIO_NUM 0 82 | #define SIOD_GPIO_NUM 26 83 | #define SIOC_GPIO_NUM 27 84 | 85 | #define Y9_GPIO_NUM 35 86 | #define Y8_GPIO_NUM 34 87 | #define Y7_GPIO_NUM 39 88 | #define Y6_GPIO_NUM 36 89 | #define Y5_GPIO_NUM 21 90 | #define Y4_GPIO_NUM 19 91 | #define Y3_GPIO_NUM 18 92 | #define Y2_GPIO_NUM 5 93 | #define VSYNC_GPIO_NUM 25 94 | #define HREF_GPIO_NUM 23 95 | #define PCLK_GPIO_NUM 22 96 | 97 | #else 98 | #error "Camera model not selected" 99 | #endif 100 | -------------------------------------------------------------------------------- /ESP32-CAM CameraWebServer modified/README.md: -------------------------------------------------------------------------------- 1 | # ESP32-CAM firmware with Webserver modified 2 | This is a modified firmware from [Espressif](https://github.com/espressif/esp32-camera) with the following upgrade 3 | * Stream video at IP/stream. Easy to integrate in a smart home server 4 | * Take snapshot at IP_CAM/jpg/image.jpg 5 | 6 | Before to download, you need to modify several settings : 7 | * Network ssid 8 | * Network password 9 | * Adjust picture orientation according the position of the ESP32-CAM FLIP_V, MIRROR_H (true or false) 10 | * Ajust image compression IMAGE_COMPRESSION (0 to 63) 11 | * Uncomment our camera 12 | * CAMERA_MODEL_WROVER_KIT 13 | * CAMERA_MODEL_ESP_EYE 14 | * CAMERA_MODEL_M5STACK_PSRAM 15 | * CAMERA_MODEL_M5STACK_WIDE 16 | * CAMERA_MODEL_AI_THINKER 17 | * Connect [FTDI](http://s.click.aliexpress.com/e/_d8ldxmV) to ESP32-CAM 18 | * GND to GND 19 | * 5V to 5V 20 | * RX to UOR 21 | * TX to UOT 22 | * IO0 to GND 23 | * Press Reset 24 | * Configure Arduino IDE setting 25 | * You need to install ESP32 SDK before to be able to build firmware 26 | * Flash Mode: QIO (by default) 27 | * Partition Schema : Huge APP (3MB No OTA) 28 | * Port: choose your FTDI board 29 | * Upload 30 | * Unconnect IO0 and GND 31 | * Reset 32 | * Open Serial Monitor to get IP 33 | * Open favorite browser and go to IP_CAM/stream 34 | * Enjoy ! 35 | 36 | More information here [in french](https://projetsdiy.fr/esp32-cam-flash-firmware-test-domoticz-jeedom-home-assistant-nextdom-node-red/) 37 | 38 | ## Firmware pour ESP32-CAM modifié 39 | Ce firmware est une version modifiée du firmware original d'[Espressif](https://github.com/espressif/esp32-camera) 40 | * Le flux vidéo peut être récupéré facilement depuis un serveur domotique à l'adresse IP_Camera/stream 41 | * Un snapshot peut être récupéré à l'adresse IP_Camera/jpg/image.jpg 42 | 43 | Avant de téléverser, vous devez modifier plusieurs paramètres 44 | * SSID du réseau WiFi 45 | * Mot de passe du réseau WiFi 46 | * MOdifier l'orientation de l'image en fonction de la position de la caméra avec les variables FLIP_V, MIRROR_H 47 | * Ajuster le taux de compression IMAGE_COMPRESSION (0 à 63) 48 | * Décommenter votre caméra 49 | * CAMERA_MODEL_WROVER_KIT 50 | * CAMERA_MODEL_ESP_EYE 51 | * CAMERA_MODEL_M5STACK_PSRAM 52 | * CAMERA_MODEL_M5STACK_WIDE 53 | * CAMERA_MODEL_AI_THINKER 54 | * Connecter l'ESP32-CAM à l'adaptateyr [FTDI](http://s.click.aliexpress.com/e/_d8ldxmV) 55 | * GND sur GND 56 | * 5V sur 5V 57 | * RX sur UOR 58 | * TX sur UOT 59 | * IO0 sur GND 60 | * Presser Reset 61 | * Configurer l'Arduino IDE 62 | * Le SDK ESP32 SDK doit être installé avant de pouvoir compiler le firmware 63 | * Flash Mode: QIO (par défaut) 64 | * Partition Schema : Huge APP (3MB No OTA) 65 | * Port: Sélectionner votre adaptateur FTDI 66 | * Téléverser 67 | * Déconnecter le jumper IO0 et GND 68 | * Reset 69 | * Ouvrer le moniteur série pour récupérer l'adresse IP de la caméra 70 | * Ouvrez votre navigateur internet et allez à l'adresse IP_CAM/stream 71 | * Féliciations ! 72 | 73 | Plus d'information sur le [blog](https://projetsdiy.fr/esp32-cam-flash-firmware-test-domoticz-jeedom-home-assistant-nextdom-node-red/) 74 | -------------------------------------------------------------------------------- /ESP32-CAM CameraWebServer modified/esp32-cam.ino: -------------------------------------------------------------------------------- 1 | /********* 2 | projetsdiy.fr - diyprojects.io 3 | 4 | Step by step tutorial 5 | En français https://projetsdiy.fr/esp32-cam-flash-firmware-test-domoticz-jeedom-home-assistant-nextdom-node-red/ 6 | 7 | IMPORTANT BEFORE TO DOWNLOAD SKETCH !!! 8 | - Install ESP32 libraries 9 | - Select Board "ESP32 Wrover Module" 10 | - Select the Partion Scheme "Huge APP (3MB No OTA)" 11 | - GPIO 0 must be connected to GND to upload a sketch 12 | - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files. 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | *********/ 20 | 21 | #include 22 | #include 23 | #include "esp_timer.h" 24 | #include "esp_camera.h" 25 | 26 | #include 27 | #include "img_converters.h" 28 | #include "Arduino.h" 29 | #include "fb_gfx.h" 30 | #include "soc/soc.h" //disable brownout problems 31 | #include "soc/rtc_cntl_reg.h" //disable brownout problems 32 | #include "dl_lib.h" 33 | #include "esp_http_server.h" // API https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/esp_http_server.html 34 | 35 | #include "driver/sdmmc_host.h" 36 | #include "driver/sdmmc_defs.h" 37 | #include "sdmmc_cmd.h" 38 | #include "esp_vfs_fat.h" 39 | 40 | //Replace with your network credentials - Remplacez par vos identificants de connexion WiFi 41 | const char* ssid = "XXXX"; 42 | const char* password = "XXXX"; 43 | 44 | #define SERIAL_DEBUG true // Enable / Disable log - activer / désactiver le journal 45 | #define ESP_LOG_LEVEL ESP_LOG_VERBOSE // ESP_LOG_NONE, ESP_LOG_VERBOSE, ESP_LOG_DEBUG, ESP_LOG_ERROR, ESP_LOG_WARM, ESP_LOG_INFO 46 | 47 | // Web server port - port du serveur web 48 | #define WEB_SERVER_PORT 80 49 | #define URI_STATIC_JPEG "/jpg/image.jpg" 50 | #define URI_STREAM "/stream" 51 | 52 | // Basic image Settings (compression, flip vertical orientation) - Réglages basiques de l'image (compression, inverse l'orientation verticale) 53 | #define FLIP_V true // Vertical flip - inverse l'image verticalement 54 | #define MIRROR_H true // Horizontal mirror - miroir horizontal 55 | #define IMAGE_COMPRESSION 10 //0-63 lower number means higher quality - Plus de chiffre est petit, meilleure est la qualité de l'image, plus gros est le fichier 56 | 57 | static const char *TAG = "esp32-cam"; 58 | 59 | /* 60 | Handler for video streaming - Entête pour le flux vidéo 61 | */ 62 | #define PART_BOUNDARY "123456789000000000000987654321" 63 | static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; 64 | static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; 65 | static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; 66 | 67 | // Uncomment your dev board model - Décommentez votre carte de développement 68 | // This project was only tested with the AI Thinker Model - le croquis a été testé uniquement avec le modèle AI Thinker 69 | //#define CAMERA_MODEL_WROVER_KIT 70 | //#define CAMERA_MODEL_ESP_EYE 71 | //#define CAMERA_MODEL_M5STACK_PSRAM 72 | //#define CAMERA_MODEL_M5STACK_WIDE 73 | #define CAMERA_MODEL_AI_THINKER 74 | 75 | #if defined(CAMERA_MODEL_WROVER_KIT) 76 | #define PWDN_GPIO_NUM -1 77 | #define RESET_GPIO_NUM -1 78 | #define XCLK_GPIO_NUM 21 79 | #define SIOD_GPIO_NUM 26 //Flash LED - Flash Light is On if SD card is present 80 | #define SIOC_GPIO_NUM 27 81 | #define Y9_GPIO_NUM 35 82 | #define Y8_GPIO_NUM 34 83 | #define Y7_GPIO_NUM 39 84 | #define Y6_GPIO_NUM 36 85 | #define Y5_GPIO_NUM 19 86 | #define Y4_GPIO_NUM 18 87 | #define Y3_GPIO_NUM 5 88 | #define Y2_GPIO_NUM 4 89 | #define VSYNC_GPIO_NUM 25 90 | #define HREF_GPIO_NUM 23 91 | #define PCLK_GPIO_NUM 22 92 | 93 | #elif defined(CAMERA_MODEL_M5STACK_PSRAM) 94 | #define PWDN_GPIO_NUM -1 95 | #define RESET_GPIO_NUM 15 96 | #define XCLK_GPIO_NUM 27 97 | #define SIOD_GPIO_NUM 25 98 | #define SIOC_GPIO_NUM 23 99 | #define Y9_GPIO_NUM 19 100 | #define Y8_GPIO_NUM 36 101 | #define Y7_GPIO_NUM 18 102 | #define Y6_GPIO_NUM 39 103 | #define Y5_GPIO_NUM 5 104 | #define Y4_GPIO_NUM 34 105 | #define Y3_GPIO_NUM 35 106 | #define Y2_GPIO_NUM 32 107 | #define VSYNC_GPIO_NUM 22 108 | #define HREF_GPIO_NUM 26 109 | #define PCLK_GPIO_NUM 21 110 | 111 | #elif defined(CAMERA_MODEL_AI_THINKER) 112 | #define PWDN_GPIO_NUM 32 113 | #define RESET_GPIO_NUM -1 114 | #define XCLK_GPIO_NUM 0 115 | #define SIOD_GPIO_NUM 26 //Flash LED - Flash Light is On if SD card is present 116 | #define SIOC_GPIO_NUM 27 117 | #define Y9_GPIO_NUM 35 118 | #define Y8_GPIO_NUM 34 119 | #define Y7_GPIO_NUM 39 120 | #define Y6_GPIO_NUM 36 121 | #define Y5_GPIO_NUM 21 122 | #define Y4_GPIO_NUM 19 123 | #define Y3_GPIO_NUM 18 124 | #define Y2_GPIO_NUM 5 125 | #define VSYNC_GPIO_NUM 25 126 | #define HREF_GPIO_NUM 23 127 | #define PCLK_GPIO_NUM 22 128 | #else 129 | #error "Camera model not selected" 130 | #endif 131 | 132 | httpd_handle_t stream_httpd = NULL; 133 | 134 | /* 135 | This method only stream one JPEG image - Cette méthode ne publie qu'une seule image JPEG 136 | Compatible with/avec Jeedom / NextDom / Domoticz 137 | */ 138 | static esp_err_t capture_handler(httpd_req_t *req) { 139 | camera_fb_t *fb = NULL; 140 | esp_err_t res = ESP_OK; 141 | size_t fb_len = 0; 142 | int64_t fr_start = esp_timer_get_time(); 143 | 144 | res = httpd_resp_set_type(req, "image/jpeg"); 145 | if (res == ESP_OK) 146 | { 147 | res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=image.jpg"); //capture 148 | } 149 | if (res == ESP_OK) { 150 | ESP_LOGI(TAG, "Take a picture"); 151 | //while(1){ 152 | fr_start = esp_timer_get_time(); 153 | fb = esp_camera_fb_get(); 154 | if (!fb) 155 | { 156 | ESP_LOGE(TAG, "Camera capture failed"); 157 | httpd_resp_send_500(req); 158 | return ESP_FAIL; 159 | } else { 160 | fb_len = fb->len; 161 | res = httpd_resp_send(req, (const char *)fb->buf, fb->len); 162 | 163 | esp_camera_fb_return(fb); 164 | // Uncomment if you want to know the bit rate - décommentez pour connaître le débit 165 | //int64_t fr_end = esp_timer_get_time(); 166 | //ESP_LOGD(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len / 1024), (uint32_t)((fr_end - fr_start) / 1000)); 167 | return res; 168 | } 169 | //} 170 | } 171 | } 172 | 173 | /* 174 | This method stream continuously a video 175 | Compatible with/avec Home Assistant, HASS.IO 176 | */ 177 | esp_err_t stream_handler(httpd_req_t *req) { 178 | camera_fb_t * fb = NULL; 179 | esp_err_t res = ESP_OK; 180 | size_t _jpg_buf_len; 181 | uint8_t * _jpg_buf; 182 | char * part_buf[64]; 183 | static int64_t last_frame = 0; 184 | if (!last_frame) { 185 | last_frame = esp_timer_get_time(); 186 | } 187 | 188 | res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); 189 | if (res != ESP_OK) { 190 | return res; 191 | } 192 | ESP_LOGI(TAG, "Start video streaming"); 193 | while (true) { 194 | fb = esp_camera_fb_get(); 195 | if (!fb) { 196 | ESP_LOGE(TAG, "Camera capture failed"); 197 | res = ESP_FAIL; 198 | } else { 199 | if (fb->format != PIXFORMAT_JPEG) { 200 | bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); 201 | if (!jpeg_converted) { 202 | ESP_LOGE(TAG, "JPEG compression failed"); 203 | esp_camera_fb_return(fb); 204 | res = ESP_FAIL; 205 | } 206 | } else { 207 | _jpg_buf_len = fb->len; 208 | _jpg_buf = fb->buf; 209 | } 210 | } 211 | if (res == ESP_OK) { 212 | size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); 213 | 214 | res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); 215 | } 216 | if (res == ESP_OK) { 217 | res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); 218 | } 219 | if (res == ESP_OK) { 220 | res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); 221 | } 222 | if (fb->format != PIXFORMAT_JPEG) { 223 | free(_jpg_buf); 224 | } 225 | esp_camera_fb_return(fb); 226 | if (res != ESP_OK) { 227 | break; 228 | } 229 | 230 | //Uncomment if you want to know the bit rate - décommentez pour connaître le débit 231 | /* 232 | int64_t fr_end = esp_timer_get_time(); 233 | int64_t frame_time = fr_end - last_frame; 234 | last_frame = fr_end; 235 | frame_time /= 1000; 236 | ESP_LOGD(TAG, "MJPG: %uKB %ums (%.1ffps)", 237 | (uint32_t)(_jpg_buf_len/1024), 238 | (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time); 239 | */ 240 | } 241 | 242 | last_frame = 0; 243 | return res; 244 | } 245 | 246 | void startCameraServer() { 247 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); 248 | config.server_port = WEB_SERVER_PORT; 249 | 250 | // endpoints 251 | static const httpd_uri_t static_image = { 252 | .uri = URI_STATIC_JPEG, 253 | .method = HTTP_GET, 254 | .handler = capture_handler, 255 | .user_ctx = NULL 256 | }; 257 | 258 | static const httpd_uri_t stream_video = { 259 | .uri = URI_STREAM, 260 | .method = HTTP_GET, 261 | .handler = stream_handler, 262 | .user_ctx = NULL 263 | }; 264 | 265 | ESP_LOGI(TAG, "Register URIs and start web server"); 266 | if (httpd_start(&stream_httpd, &config) == ESP_OK) { 267 | if ( httpd_register_uri_handler(stream_httpd, &static_image) != ESP_OK) { 268 | ESP_LOGE(TAG, "register uri failed for static_image"); 269 | return; 270 | }; 271 | if ( httpd_register_uri_handler(stream_httpd, &stream_video) != ESP_OK) { 272 | ESP_LOGE(TAG, "register uri failed for stream_video"); 273 | return; 274 | }; 275 | } 276 | } 277 | 278 | void setup() { 279 | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector 280 | 281 | Serial.begin(115200); 282 | Serial.setDebugOutput(SERIAL_DEBUG); 283 | esp_log_level_set("*", ESP_LOG_LEVEL); 284 | 285 | camera_config_t config; 286 | config.ledc_channel = LEDC_CHANNEL_0; 287 | config.ledc_timer = LEDC_TIMER_0; 288 | config.pin_d0 = Y2_GPIO_NUM; 289 | config.pin_d1 = Y3_GPIO_NUM; 290 | config.pin_d2 = Y4_GPIO_NUM; 291 | config.pin_d3 = Y5_GPIO_NUM; 292 | config.pin_d4 = Y6_GPIO_NUM; 293 | config.pin_d5 = Y7_GPIO_NUM; 294 | config.pin_d6 = Y8_GPIO_NUM; 295 | config.pin_d7 = Y9_GPIO_NUM; 296 | config.pin_xclk = XCLK_GPIO_NUM; 297 | config.pin_pclk = PCLK_GPIO_NUM; 298 | config.pin_vsync = VSYNC_GPIO_NUM; 299 | config.pin_href = HREF_GPIO_NUM; 300 | config.pin_sscb_sda = SIOD_GPIO_NUM; 301 | config.pin_sscb_scl = SIOC_GPIO_NUM; 302 | config.pin_pwdn = PWDN_GPIO_NUM; 303 | config.pin_reset = RESET_GPIO_NUM; 304 | config.xclk_freq_hz = 20000000; //XCLK 20MHz or 10MHz 305 | config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG 306 | config.frame_size = FRAMESIZE_SVGA; //UXGA SVGA VGA QVGA Do not use sizes above QVGA when not JPEG 307 | config.jpeg_quality = 10; 308 | config.fb_count = 2; //if more than one, i2s runs in continuous mode. Use only with JPEG 309 | 310 | // Camera init - Initialise la caméra 311 | esp_err_t err = esp_camera_init(&config); 312 | if (err != ESP_OK) { 313 | ESP_LOGE(TAG, "Camera init failed with error 0x%x", err); 314 | return; 315 | } else { 316 | ESP_LOGD(TAG, "Camera correctly initialized "); 317 | sensor_t * s = esp_camera_sensor_get(); 318 | s->set_vflip(s, FLIP_V); 319 | s->set_hmirror(s, MIRROR_H); 320 | } 321 | 322 | // Wi-Fi connection - Connecte le module au réseau Wi-Fi 323 | ESP_LOGD(TAG, "Start Wi-Fi connexion "); 324 | WiFi.begin(ssid, password); 325 | while (WiFi.status() != WL_CONNECTED) { 326 | delay(500); 327 | Serial.print("."); 328 | } 329 | Serial.println(""); 330 | ESP_LOGD(TAG, "Wi-Fi connected "); 331 | 332 | // Start streaming web server 333 | startCameraServer(); 334 | 335 | ESP_LOGI(TAG, "Camera Stream Ready"); 336 | Serial.println(WiFi.localIP()); 337 | } 338 | 339 | void loop() { 340 | delay(1); 341 | } 342 | -------------------------------------------------------------------------------- /ESP32-CAM simplified code/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* Five ESP32-CAM tips. Simplified version of HTML and C ++ code 2 | Fixed IP address. AP mode. Image rotation 90 °. Automatic recovery WiFi connection. HTML code storage 3 | 4 | 5 astuces pour ESP32-CAM. Version simplifiée du code HTML et C++ 5 | Adresse IP fixe. Mode AP. Rotation image 90°. Récupération automatique connexion WiFi. stockage du code HTML 6 | 7 | Licence : see licence file 8 | */ 9 | #include 10 | #include "esp_camera.h" 11 | #include 12 | #include "esp_http_server.h" 13 | 14 | // Select camera model 15 | // Dé-commentez (uniquement) votre ESP32-CAM 16 | //#define CAMERA_MODEL_WROVER_KIT 17 | //#define CAMERA_MODEL_ESP_EYE 18 | //#define CAMERA_MODEL_M5STACK_PSRAM 19 | //#define CAMERA_MODEL_M5STACK_WIDE 20 | #define CAMERA_MODEL_AI_THINKER 21 | 22 | #include "camera_pins.h" 23 | 24 | /**********************************************************************/ 25 | /* PARAMETRES WIFI */ 26 | /**********************************************************************/ 27 | const char* ssid = "enter_your_ssid"; 28 | const char* password = "enter_your_password"; 29 | #define TEST_WIFI_SIGNAL true 30 | // Activate AP mode AP (Access point). User need to connect directly to ESP32 wifi network to access video stream 31 | // Active le mode AP (Access point). L'ESP32-CAM n'est pas connectée au WiFi, on se connecte directement sur la caméra 32 | #define AP_MODE false 33 | const char* ap_ssid = "esp32-cam"; 34 | const char* ap_password = "12345678"; // Mini. 8 car 35 | /**********************************************************************/ 36 | /* USE FIXED IP */ 37 | /* UTILISE UNE IP FIXE */ 38 | /**********************************************************************/ 39 | #define USE_FIXED_IP true 40 | // Set your Static IP address. Do not use existing IP address (other computer, TV box, printer, smartphone) 41 | // L'adresse IP que vous souhaitez attribuer à l'ESP32-CAM. Attention à ne pas utiliser une adresse existante ! 42 | IPAddress local_IP(192, 168, 1, 80); 43 | // Set your Gateway IP address 44 | // Adresse du routeur ou de la box internet 45 | IPAddress gateway(192, 168, 1, 1); 46 | IPAddress subnet(255, 255, 0, 0); 47 | IPAddress primaryDNS(8, 8, 8, 8); //optional 48 | IPAddress secondaryDNS(8, 8, 4, 4); //optional 49 | /**********************************************************************/ 50 | /* PARAMETRE DE REDEMARRAGE SI LE RESEAU WIFI N'EST PAS DISPONIBLE */ 51 | /**********************************************************************/ 52 | int wifi_counter = 0; 53 | #define wifi_try 10 54 | #define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */ 55 | #define TIME_TO_SLEEP 30 /* Time ESP32 will go to sleep (in seconds) */ 56 | /**********************************************************************/ 57 | /* PROTOTYPES */ 58 | /**********************************************************************/ 59 | void restartESP32Cam(); 60 | void startCameraServer(); 61 | /**********************************************************************/ 62 | /* WEB SERVER + STREAM SERVER */ 63 | /* SERVEUR WEB + SERVEUR VIDEO */ 64 | /**********************************************************************/ 65 | #define PART_BOUNDARY "123456789000000000000987654321" 66 | static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; 67 | static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; 68 | static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; 69 | 70 | httpd_handle_t stream_httpd = NULL; 71 | httpd_handle_t camera_httpd = NULL; 72 | 73 | // Stream sever port number 74 | // Numéro du port du server vidéo 75 | int port_number; 76 | 77 | const char index_html[] PROGMEM = R"=====( 78 | 79 | 80 | 81 | 101 | 102 | 103 |

ESP32-CAM Stream Server

104 |
105 | 106 |
107 |
108 |

Rotate Image

109 | 110 | 111 |
112 | 113 | 127 | )====="; 128 | /*********************************************/ 129 | /* GENERATE MJPEG STREAM */ 130 | /* GENERE LE FLUX VIDEO MJPEG */ 131 | /*********************************************/ 132 | static esp_err_t stream_handler(httpd_req_t *req) { 133 | camera_fb_t * fb = NULL; 134 | esp_err_t res = ESP_OK; 135 | size_t _jpg_buf_len = 0; 136 | uint8_t * _jpg_buf = NULL; 137 | char * part_buf[64]; 138 | 139 | static int64_t last_frame = 0; 140 | if (!last_frame) { 141 | last_frame = esp_timer_get_time(); 142 | } 143 | 144 | res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); 145 | if (res != ESP_OK) { 146 | return res; 147 | } 148 | httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); 149 | 150 | while (true) { 151 | fb = esp_camera_fb_get(); 152 | if (!fb) { 153 | // Echec de la capture de camera 154 | Serial.println("JPEG capture failed"); 155 | res = ESP_FAIL; 156 | } else { 157 | if (fb->width > 400) { 158 | if (fb->format != PIXFORMAT_JPEG) { 159 | bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); 160 | esp_camera_fb_return(fb); 161 | fb = NULL; 162 | if (!jpeg_converted) { 163 | // Echec de la compression JPEG 164 | Serial.println("JPEG compression failed"); 165 | res = ESP_FAIL; 166 | } 167 | } else { 168 | _jpg_buf_len = fb->len; 169 | _jpg_buf = fb->buf; 170 | } 171 | } 172 | } 173 | if (res == ESP_OK) { 174 | size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); 175 | res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); 176 | } 177 | if (res == ESP_OK) { 178 | res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); 179 | } 180 | if (res == ESP_OK) { 181 | res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); 182 | } 183 | if (fb) { 184 | esp_camera_fb_return(fb); 185 | fb = NULL; 186 | _jpg_buf = NULL; 187 | } else if (_jpg_buf) { 188 | free(_jpg_buf); 189 | _jpg_buf = NULL; 190 | } 191 | if (res != ESP_OK) { 192 | break; 193 | } 194 | } 195 | last_frame = 0; 196 | return res; 197 | } 198 | 199 | /*******************************************************/ 200 | /* HTML PAGE BUILDER */ 201 | /* CONSTRUCTEUR DE LA PAGE HTML */ 202 | /*******************************************************/ 203 | static esp_err_t web_handler(httpd_req_t *req) { 204 | httpd_resp_set_type(req, "text/html"); 205 | httpd_resp_set_hdr(req, "Content-Encoding", "identity"); 206 | 207 | int indexhtmlsize = sizeof(index_html) + 50; 208 | char indexpage[indexhtmlsize] = ""; 209 | //strcat(indexpage, index_html); 210 | char streamip[20] = ""; 211 | 212 | if ( AP_MODE ) { 213 | // In AP Mode, IP is always 192.168.4.1 214 | // En mode AP (connexion directe à l'ESP32-CAM), l'IP est toujours 192.168.4.1 215 | sprintf(streamip, "192.168.4.1:%d", port_number); 216 | } else { 217 | sprintf(streamip, "%d.%d.%d.%d:%d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3], port_number); 218 | } 219 | // Replace stream url inside HTML page code 220 | // Remplace l'adresse du flux vidéo dans le code de la page HTML 221 | sprintf(indexpage, index_html, streamip); 222 | int pagezize = strlen(indexpage); 223 | 224 | // Return HTML page source code 225 | // Renvoie le code source de la page HTML 226 | return httpd_resp_send(req, (const char *)indexpage, pagezize); 227 | } 228 | 229 | /***********************************************************/ 230 | /* START WEB SERVER AND VIDEO STREAM */ 231 | /* DEMARRE LE SERVEUR WEB ET LE FLUX VIDEO */ 232 | /***********************************************************/ 233 | void startCameraServer() { 234 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); 235 | 236 | httpd_uri_t index_uri = { 237 | .uri = "/", 238 | .method = HTTP_GET, 239 | .handler = web_handler, 240 | .user_ctx = NULL 241 | }; 242 | 243 | httpd_uri_t stream_uri = { 244 | .uri = "/stream", 245 | .method = HTTP_GET, 246 | .handler = stream_handler, 247 | .user_ctx = NULL 248 | }; 249 | 250 | // Démarre le serveur web de l'interface HTML accessible depuis le navigateur internet 251 | Serial.printf("Web server started on port: '%d'\n", config.server_port); 252 | if (httpd_start(&camera_httpd, &config) == ESP_OK) { 253 | httpd_register_uri_handler(camera_httpd, &index_uri); 254 | } 255 | 256 | config.server_port += 1; 257 | config.ctrl_port += 1; 258 | // Démarre le flux vidéo 259 | Serial.printf("Stream server started on port: '%d'\n", config.server_port); 260 | if (httpd_start(&stream_httpd, &config) == ESP_OK) { 261 | httpd_register_uri_handler(stream_httpd, &stream_uri); 262 | } 263 | 264 | port_number = config.server_port; 265 | } 266 | 267 | 268 | void setup() { 269 | Serial.begin(115200); 270 | Serial.setDebugOutput(true); 271 | Serial.println(); 272 | 273 | // Configure camera Pins 274 | // Configure les broches de la caméra 275 | camera_config_t config; 276 | config.ledc_channel = LEDC_CHANNEL_0; 277 | config.ledc_timer = LEDC_TIMER_0; 278 | config.pin_d0 = Y2_GPIO_NUM; 279 | config.pin_d1 = Y3_GPIO_NUM; 280 | config.pin_d2 = Y4_GPIO_NUM; 281 | config.pin_d3 = Y5_GPIO_NUM; 282 | config.pin_d4 = Y6_GPIO_NUM; 283 | config.pin_d5 = Y7_GPIO_NUM; 284 | config.pin_d6 = Y8_GPIO_NUM; 285 | config.pin_d7 = Y9_GPIO_NUM; 286 | config.pin_xclk = XCLK_GPIO_NUM; 287 | config.pin_pclk = PCLK_GPIO_NUM; 288 | config.pin_vsync = VSYNC_GPIO_NUM; 289 | config.pin_href = HREF_GPIO_NUM; 290 | config.pin_sscb_sda = SIOD_GPIO_NUM; 291 | config.pin_sscb_scl = SIOC_GPIO_NUM; 292 | config.pin_pwdn = PWDN_GPIO_NUM; 293 | config.pin_reset = RESET_GPIO_NUM; 294 | config.xclk_freq_hz = 20000000; 295 | config.pixel_format = PIXFORMAT_JPEG; 296 | 297 | // Init with high specs to pre-allocate larger buffers 298 | // Utilise toute la mémoire PSRAM disponible pour augmenter la taille du buffer vidéo 299 | /* AVAILABLE RESOLUTIONS 300 | Résolutions disponibles 301 | FRAMESIZE_QQVGA, // 160x120 302 | FRAMESIZE_QQVGA2, // 128x160 303 | FRAMESIZE_QCIF, // 176x144 304 | FRAMESIZE_HQVGA, // 240x176 305 | FRAMESIZE_QVGA, // 320x240 306 | FRAMESIZE_CIF, // 400x296 307 | FRAMESIZE_VGA, // 640x480 308 | FRAMESIZE_SVGA, // 800x600 309 | FRAMESIZE_XGA, // 1024x768 310 | FRAMESIZE_SXGA, // 1280x1024 311 | FRAMESIZE_UXGA, // 1600x1200 312 | FRAMESIZE_QXGA, // 2048*1536 313 | */ 314 | if(psramFound()){ 315 | config.frame_size = FRAMESIZE_UXGA; //FRAMESIZE_UXGA; // 1600x1200 316 | config.jpeg_quality = 10; 317 | config.fb_count = 1; // Si > 1, active le bus I2S 318 | } else { 319 | config.frame_size = FRAMESIZE_SVGA; // 800x600 320 | config.jpeg_quality = 12; 321 | config.fb_count = 1; 322 | } 323 | #if defined(CAMERA_MODEL_ESP_EYE) 324 | pinMode(13, INPUT_PULLUP); 325 | pinMode(14, INPUT_PULLUP); 326 | #endif 327 | 328 | // camera init 329 | esp_err_t err = esp_camera_init(&config); 330 | if (err != ESP_OK) { 331 | Serial.printf("Camera init failed with error 0x%x", err); 332 | return; 333 | } 334 | 335 | if ( AP_MODE ) { 336 | // In AP Mode, connect to http://192.168.4.1 337 | // En mode AP, on se connecte directement au réseau WiFi de l'ESP32 à l'adresse http://192.168.4.1 338 | /* ACCESS POINT PARAMETERS 339 | ap_ssid (defined earlier): maximum of 63 characters 340 | ap_password (defined earlier): minimum of 8 characters; set to NULL if you want the access point to be open 341 | channel: Wi-Fi channel, number between 1 to 13 342 | ssid_hidden: (0 = broadcast SSID, 1 = hide SSID) 343 | max_connection: maximum simultaneous connected clients, max. 4 344 | -------- 345 | ap_ssid (déjà définit): 63 caractères max. 346 | ap_password (déjà defint): au minimum 8 caractères. NULL pour un accès libre. déconseillé !!! 347 | channel: canal Wi-Fi, nombre entre 1 et 13 348 | ssid_hidden: 0 = diffuser le nom du résau, 1 = cache le nom du réseau SSID 349 | max_connection: nombre maximum de clients connectés simultannément à l'ESP32-CAM. 4 max. 350 | */ 351 | WiFi.softAP(ap_ssid, ap_password); 352 | } else { 353 | if ( USE_FIXED_IP ) { 354 | if(!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) { 355 | Serial.println("STA Failed to configure"); 356 | } 357 | } 358 | WiFi.begin(ssid, password); 359 | while ( WiFi.status() != WL_CONNECTED) { 360 | delay(500); 361 | Serial.print("."); 362 | wifi_counter++; 363 | 364 | if ( wifi_counter > wifi_try ) { 365 | restartESP32Cam(); 366 | } 367 | } 368 | Serial.println(""); 369 | Serial.println("WiFi connected"); 370 | } 371 | 372 | // La caméra est prête, ouvrez votre navigateur à l'adresse suivante 373 | Serial.print("Camera Ready! Open your browser at 'http://"); 374 | 375 | Serial.print(WiFi.localIP()); 376 | Serial.println(""); 377 | 378 | // Test WiFi signal quality 379 | // Test la qualité du réseau WiFi 380 | if ( TEST_WIFI_SIGNAL ){ 381 | long logrssi = 0 ; 382 | for (size_t i = 0; i < 10; i++) 383 | { 384 | long rssi = WiFi.RSSI(); 385 | logrssi = logrssi + rssi; 386 | Serial.printf("measured rssi = %d dBm \n", WiFi.RSSI()); 387 | delay(200); 388 | } 389 | 390 | Serial.printf("Mean rssi = %0.1d dBm \n", logrssi / 10); 391 | } 392 | 393 | 394 | // Start web server and MJPEG stream 395 | // Démarrer le serveur web et le flux vidéo MJPEG 396 | startCameraServer(); 397 | 398 | } 399 | 400 | void loop() { 401 | if ( WiFi.status() != WL_CONNECTED ) { 402 | // We just lost WiFi connexion! 403 | // On vient de perdre la connexion WiFi 404 | restartESP32Cam(); 405 | } 406 | 407 | delay(10); 408 | } 409 | 410 | // Auto re-connect WiFi network after a moment 411 | // Récupération automatique de la connexion WiFi s'il est impossible de se connecter ou si la connexion est perdue 412 | void restartESP32Cam() 413 | { 414 | Serial.println("Impossible to connect WiFi network or connexion lost ! I sleep a moment and I retry later, sorry "); 415 | // Activate ESP32 deep sleep mode 416 | // Met l'ESP32 en mode deep-sleep pour ne pas drainer la batterie ou consommer inutilement 417 | esp_sleep_enable_timer_wakeup(uS_TO_S_FACTOR * TIME_TO_SLEEP); 418 | esp_deep_sleep_start(); 419 | } --------------------------------------------------------------------------------