ESP32-CAM, flash du firmware officiel modifié avec capture d’image

Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

Table des matières

ESP32-CAM est un module ESP-WROOM-32 du fabricant AI Thinker associé à une caméra couleur 2MP OV2640. Le module ESP32-CAM dispose également d’un lecteur de carte SD qui pourra servir à enregistrer des images lorsqu’un événement est détecté (détecteur de présence ou de mouvement par exemple). Espressif fournit une API complète qui permet d’accéder à toutes les fonctionnalités du module caméra. C’est vraiment une excellente base pour développer son propre système de vidéo surveillance IP sans avoir la crainte que le flux vidéo arrive sur des serveurs douteux.

 

Un exemple de serveur vidéo est proposé par Espressif dans le SDK des cartes ESP32. Vous pouvez l’installer très simplement en suivant la procédure décrite dans ce tutoriel. Le flux vidéo du serveur vidéo n’est pas supporté par Domoticz, Jeedom (et de facto par NextDom). J’ai donc fait une adaptation d’un exemple proposé sur le GitHub d’Espressif. Ce firmware diffuse deux flux vidéos. Le premier est une image fixe que l’on pourra intégrer à l’aide du module Camera officiel de Jeedom, Nextdom ainsi qu’à Domoticz. C’est le serveur domotique qui s’occupe de récupérer un image à intervalle régulier. Le second est un flux vidéo au format MJPEG. On pourra l’intégrer à Home Assistant, Hass.io ou Node-RED. Le firmware devrait être compatible avec d’autres modules caméra ESP32 tel que M5Stack, ESP Eye et Wrover Kit d’Espressif mais je ne dispose pas des cartes pour tester. N’hésitez pas à me signaler vos retours dans les commentaires.

Un exemple de reconnaissance faciale est également disponible. Attention, une simple photo suffit pour leurrer le programme de reconnaissance faciale !! Ne l’utilisez pas pour déverrouiller votre porte d’entrée 😉 .

Présentation du module ESP32-CAM de AI Thinker

Le module ESP32-CAM a été développé par le fabricant chinois AI Thinker sur la base du module ESP32 ESP-WROVER-32 à 240Mhz équipé de 520 Ko intégrée de SRAM et 4 Mo de PSRAM externe (pour le stockage des programmes et données de l’utilisateur). La carte qui ne mesure que 27 x 40.5 x 4.5 mm est équipée d’un lecteur de carte micro SD et d’une LED flash. La documentation détaillée est disponible (en chinois) sur cette page.

ai thinker esp32 cam diagram

ESP32-CAM AI Thinker. Vues du dessus et du dessous. Reset, flash LED, connecteur caméra DVP, lecteur de carte SD

Un connecteur uFL (IPEX) pour antenne externe est également disponible mais il faudra souder une résistance CMS pour pouvoir l’utiliser (autant dire que ce n’est pas gagné !).

16 broches de l’ESP-WROVER-32 sont exposées. On pourra par exemple ajouter une sonde climatique (BME280) ou un détecteur de mouvement au module caméra. Les broches U0T (GPIO1 port série TX) et U0R (GPIO3, port série RX) seront nécessaires pour téléverser le programme. La broche IO0 (GPIO0) sera nécessaire pour mettre l’ESP32 en flash mode pour téléverser le programme.

Les broches GPIO2 GPIO4 GPIO12 GPIO13 GPIO14 GPIO15 GPIO16 sont disponibles pour vos projets.

ai thinker esp32 cam pinout

Repérage de broches (pinout) de l’ESP32-CAM

Plusieurs broches sont utilisées pour le module caméra OV2640 et le lecteur de carte micro SD qui utilise le bus SPI standard

ai thinker esp32 cam pinout ov2640

Par défaut, la carte est livrée avec un module caméra 2MP (1600*1200 pixels) OV2640 du fabricant OmniVision. La librairie est compatible avec le module OV7670. Attention, contrairement à ce qu’on pourrait croire, l’OV7670 n’offre une résolution que de 640×480 pixels.

Pour une application de vidéo surveillance, on trouve des modules OV2640 avec une optique de type fisheye pouvant atteindre jusqu’à 160° (au lieu de 78° en standard) qui est mieux adaptée.

Le design du module ESP32-CAM étant Open Source, de très (très) nombreux fabricants produisent cette carte. On la trouve maintenant très facilement

Voir plus de modules ESP32-CAM

Circuit pour flasher un firmware sur l’ESP32-CAM

La carte ESP32-CAM est dépourvu de connecteur micro USB (ainsi que de convertisseur USB vers Série). C’est étonnant pour une carte de développement. Il faudra donc penser à acheter un module FTDI si vous n’en possédez pas encore. Vous aurez également besoin de quelques jumpers femelle-femelle. Connectez les broches du module FTDI comme ceci.

Comme vous pouvez le constater les broches RX / TX ne sont pas croisées comme cela devrait être normalement le cas. Si vous rencontrez des problèmes, croisez les broches RX/TX. Il y a peut être une erreur sur ma carte ESP32-CAM générique.

FTDI ESP32 CAM
5V 5V
GND GND
TX UOT
RX UOR
IO0 sur GND + RESET à chaque téléversement

J’ai essayé d’alimenter le module via la broche VCC ou 3V3 sans succès. Cela dépend peut être d’un fabricant à l’autre.

esp32cam pinout ftdi cable ide arduino

Avant de pouvoir téléverser le programme depuis l’IDE Arduino (ou un autre environnement), il faudra mettre l’ESP32 en flash mode. Pour cela, il faut connecter la broche IO0 à la broche GND puis faire un reset (ou mettre sous tension).

Après chaque téléversement, déconnectez la broche IO0 du GND et faites un RESET pour redémarrer le firmware.

esp32-cam diagram flash mode firmware ide arduino ftdi cable

 

Installation de l’IDE Arduino et des librairies pour les cartes ESP32

Ce paragraphe s’adresse à tous ceux qui débutent dans le monde des micro-contrôleurs. Si vous disposez déjà d’un IDE Arduino et des librairies nécessaires pour les cartes ESP32, vous pouvez directement sauter à l’étape suivante.

Remarque. N’oubliez pas de mettre à jour le SDK des cartes ESP32 avant d’aller plus loin.

A LIRE AUSSI :
ESP32. Débuter avec Arduino-ESP32 sur IDE Arduino, macOS, Windows, Linux

Commencez par télécharger et installer l’IDE Arduino qui convient à votre environnement en vous rendant sur le site officiel. Une fois installé, lancez l’IDE Arduino.

Ouvrez le panneau des préférences et cliquez sur le bouton situé à droite de l’option URL de gestionnaire de cartes supplémentaires.

sdk espressif esp32 ide arduino preferences

Dans la boîte de dialogue qui s’ouvre, ajoutez le lien suivant puis cliquez sur OK

https://dl.espressif.com/dl/package_esp32_index.json
Attention, une ligne par URL.

link sdk espressif esp32 ide arduino

Ouvrez le gestionnaire de carte depuis le menu Outils puis Type de carte

2 install sdk espressif esp32 ide arduino

Cherchez le SDK avec le mot clé ESP32 puis cliquez sur installer.

install sdk espressif esp32 ide arduino

Maintenant que les cartes ESP32 sont gérées depuis le gestionnaire de carte, les librairies pourront être mises à jour dès qu’une nouvelle version est disponible.

Vous trouverez d’autres tutoriels pour allez plus loin avec l’IDE Arduino ici.

Sélection du module ESP32

Maintenant que le framework ESP32 est installé, il faut sélectionner le module ESP32 Wrover dans la liste utilisé par AI Thinker. Ouvrez le menu Outils et faites descendre la liste Type de carte. Modifiez ensuite les réglages suivants :

  • Flash Mode : QIO (par défaut normalement)
  • Partition Schema : Huge APP (3MB No OTA)
  • Core Debug Level : il est directement géré dans les paramètres du programme (paragraphe suivant)
  • Port : sélectionnez le port USB sur lequel est connecté le module FTDI. Ici un exemple sur macOS. Sur Windows, il prendra la forme COMx

esp32 wrover ai thinker ide arduino parameters

Installation du firmware sur l’ESP32-CAM. Image JPEG et flux vidéo

Comme je l’ai dit en introduction, de nombreux logiciels domotiques ne supportent pas l’intégration d’un flux vidéo au format MJPG, voici une petit adaptation d’un exemple publié par Espressif sur son compte GitHub.

Voir le code source sur Github

Vous disposez de plusieurs réglages de base au début du programme.

Tout d’abord, il est possible d’activer le débogueur du firmware ESP32

#define SERIAL_DEBUG true // Enable / Disable log - activer / désactiver le journal
#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

Le firmware délivre deux sorties vidéos. Une capture fixe qui nécessite une actualisation manuelle de la page web. Un flux vidéo au format MJPEG. Vous pouvez changer le port du serveur web et l’URL de sortie en fonction de vos besoins

// Web server port - port du serveur web
#define WEB_SERVER_PORT 80
#define URI_STATIC_JPEG "/jpg/image.jpg"
#define URI_STREAM "/stream"

Enfin vous pouvez changer l’orientation de l’image en fonction de la position de la caméra ainsi que le niveau de compression

// Basic image Settings (compression, flip vertical orientation) - Réglages basiques de l'image (compression, inverse l'orientation verticale)
#define FLIP_V true // Vertical flip - inverse l'image verticalement
#define MIRROR_H true // Horizontal mirror - miroir horizontal
#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

N’oubliez pas enfin d’indiquer vos identifiants de connexion au réseau Wi-Fi

//Replace with your network credentials - Remplacez par vos identifiants de connexion WiFi
const char* ssid = "xxxx";
const char* password = "xxxx";

Créez un nouveau croquis et coller le code suivant puis

  • Modifiez vos paramètres.
  • Mettez l’ESP32 en flash Mode en reliant la broche IO0 au GND puis en faisant un RESET avec le bouton situé sur la face intérieure de la carte
  • Téléversez le croquis
/*********
  projetsdiy.fr - diyprojects.io

  IMPORTANT BEFORE TO DOWNLOAD SKETCH !!!
   - Install ESP32 libraries
   - Select Board "ESP32 Wrover Module"
   - Select the Partion Scheme "Huge APP (3MB No OTA)"
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <esp_event_loop.h>
#include <esp_log.h>
#include "esp_timer.h"
#include "esp_camera.h"

#include <WiFi.h>
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h"           //disable brownout problems
#include "soc/rtc_cntl_reg.h"  //disable brownout problems
#include "dl_lib.h"
#include "esp_http_server.h"    // API https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/esp_http_server.html

#include "driver/sdmmc_host.h"
#include "driver/sdmmc_defs.h"
#include "sdmmc_cmd.h"
#include "esp_vfs_fat.h"

//Replace with your network credentials - Remplacez par vos identificants de connexion WiFi
const char* ssid = "XXXX";
const char* password = "XXXX"; 

#define SERIAL_DEBUG true                // Enable / Disable log - activer / désactiver le journal
#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

// Web server port - port du serveur web
#define WEB_SERVER_PORT 80
#define URI_STATIC_JPEG "/jpg/image.jpg"
#define URI_STREAM "/stream"

// Basic image Settings (compression, flip vertical orientation) - Réglages basiques de l'image (compression, inverse l'orientation verticale)
#define FLIP_V true            // Vertical flip - inverse l'image verticalement
#define MIRROR_H true          // Horizontal mirror - miroir horizontal
#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

static const char *TAG = "esp32-cam";

/*
   Handler for video streaming - Entête pour le flux vidéo
*/
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";

// Uncomment your dev board model - Décommentez votre carte de développement
// This project was only tested with the AI Thinker Model - le croquis a été testé uniquement avec le modèle AI Thinker
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER

#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM    -1
#define RESET_GPIO_NUM   -1
#define XCLK_GPIO_NUM    21
#define SIOD_GPIO_NUM    26     //Flash LED - Flash Light is On if SD card is present
#define SIOC_GPIO_NUM    27
#define Y9_GPIO_NUM      35
#define Y8_GPIO_NUM      34
#define Y7_GPIO_NUM      39
#define Y6_GPIO_NUM      36
#define Y5_GPIO_NUM      19
#define Y4_GPIO_NUM      18
#define Y3_GPIO_NUM       5
#define Y2_GPIO_NUM       4
#define VSYNC_GPIO_NUM   25
#define HREF_GPIO_NUM    23
#define PCLK_GPIO_NUM    22

#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     25
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       32
#define VSYNC_GPIO_NUM    22
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

#elif defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26  //Flash LED - Flash Light is On if SD card is present
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22
#else
#error "Camera model not selected"
#endif

httpd_handle_t stream_httpd = NULL;

/*
   This method only stream one JPEG image - Cette méthode ne publie qu'une seule image JPEG
   Compatible with/avec Jeedom / NextDom / Domoticz
*/
static esp_err_t capture_handler(httpd_req_t *req) {
  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;
  size_t fb_len = 0;
  int64_t fr_start = esp_timer_get_time();

  res = httpd_resp_set_type(req, "image/jpeg");
  if (res == ESP_OK)
  {
    res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=image.jpg");  //capture
  }
  if (res == ESP_OK) {
    ESP_LOGI(TAG, "Take a picture");
    //while(1){
    fr_start = esp_timer_get_time();
    fb = esp_camera_fb_get();
    if (!fb)
    {
      ESP_LOGE(TAG, "Camera capture failed");
      httpd_resp_send_500(req);
      return ESP_FAIL;
    } else {
      fb_len = fb->len;
      res = httpd_resp_send(req, (const char *)fb->buf, fb->len);

      esp_camera_fb_return(fb);
      // Uncomment if you want to know the bit rate - décommentez pour connaître le débit
      //int64_t fr_end = esp_timer_get_time();
      //ESP_LOGD(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len / 1024), (uint32_t)((fr_end - fr_start) / 1000));
      return res;
    }
    //}
  }
}

/*
   This method stream continuously a video
   Compatible with/avec Home Assistant, HASS.IO
*/
esp_err_t stream_handler(httpd_req_t *req) {
  camera_fb_t * fb = NULL;
  esp_err_t res = ESP_OK;
  size_t _jpg_buf_len;
  uint8_t * _jpg_buf;
  char * part_buf[64];
  static int64_t last_frame = 0;
  if (!last_frame) {
    last_frame = esp_timer_get_time();
  }

  res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  if (res != ESP_OK) {
    return res;
  }
  ESP_LOGI(TAG, "Start video streaming");
  while (true) {
    fb = esp_camera_fb_get();
    if (!fb) {
      ESP_LOGE(TAG, "Camera capture failed");
      res = ESP_FAIL;
    } else {
      if (fb->format != PIXFORMAT_JPEG) {
        bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
        if (!jpeg_converted) {
          ESP_LOGE(TAG, "JPEG compression failed");
          esp_camera_fb_return(fb);
          res = ESP_FAIL;
        }
      } else {
        _jpg_buf_len = fb->len;
        _jpg_buf = fb->buf;
      }
    }
    if (res == ESP_OK) {
      size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);

      res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
    }
    if (res == ESP_OK) {
      res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
    }
    if (res == ESP_OK) {
      res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
    }
    if (fb->format != PIXFORMAT_JPEG) {
      free(_jpg_buf);
    }
    esp_camera_fb_return(fb);
    if (res != ESP_OK) {
      break;
    }

    //Uncomment if you want to know the bit rate - décommentez pour connaître le débit
    /*
      int64_t fr_end = esp_timer_get_time();
      int64_t frame_time = fr_end - last_frame;
      last_frame = fr_end;
      frame_time /= 1000;
      ESP_LOGD(TAG, "MJPG: %uKB %ums (%.1ffps)",
        (uint32_t)(_jpg_buf_len/1024),
        (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time);
    */
  }

  last_frame = 0;
  return res;
}

void startCameraServer() {
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = WEB_SERVER_PORT;

  // endpoints
  static const httpd_uri_t static_image = {
    .uri       = URI_STATIC_JPEG,
    .method    = HTTP_GET,
    .handler   = capture_handler,
    .user_ctx  = NULL
  };

  static const httpd_uri_t stream_video = {
    .uri       = URI_STREAM,
    .method    = HTTP_GET,
    .handler   = stream_handler,
    .user_ctx  = NULL
  };

  ESP_LOGI(TAG, "Register URIs and start web server");
  if (httpd_start(&stream_httpd, &config) == ESP_OK) {
    if ( httpd_register_uri_handler(stream_httpd, &static_image) != ESP_OK) {
      ESP_LOGE(TAG, "register uri failed for static_image");
      return;
    };
    if ( httpd_register_uri_handler(stream_httpd, &stream_video) != ESP_OK) {
      ESP_LOGE(TAG, "register uri failed for stream_video");
      return;
    };
  }
}

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

  Serial.begin(115200);
  Serial.setDebugOutput(SERIAL_DEBUG);
  esp_log_level_set("*", ESP_LOG_LEVEL);

  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_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;       //XCLK 20MHz or 10MHz
  config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG
  config.frame_size = FRAMESIZE_SVGA;   //UXGA SVGA VGA QVGA Do not use sizes above QVGA when not JPEG
  config.jpeg_quality = 10;
  config.fb_count = 2;                  //if more than one, i2s runs in continuous mode. Use only with JPEG

  // Camera init - Initialise la caméra
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    ESP_LOGE(TAG, "Camera init failed with error 0x%x", err);
    return;
  } else {
    ESP_LOGD(TAG, "Camera correctly initialized ");
    sensor_t * s = esp_camera_sensor_get();
    s->set_vflip(s, FLIP_V);
    s->set_hmirror(s, MIRROR_H);
  }

  // Wi-Fi connection - Connecte le module au réseau Wi-Fi
  ESP_LOGD(TAG, "Start Wi-Fi connexion ");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  ESP_LOGD(TAG, "Wi-Fi connected ");

  // Start streaming web server
  startCameraServer();

  ESP_LOGI(TAG, "Camera Stream Ready");
  Serial.println(WiFi.localIP());
}

void loop() {
  delay(1);
}
Voir le code source sur Github

Tester si tout fonctionne correctement

Un fois que le programme est téléversé, l’IDE Arduino affiche le message Téléversement terminé.

ide arduino esp32 ai thinker upload completed

Ouvrez le moniteur série depuis le menu Outils. Débranchez la broche IO0 du GND et faites un RESET sur la carte. Si vous avez activé le journal de déboggage, vous obtiendrez immédiatement l’adresse IP de la caméra.

ip esp32cam ide arduino serial monitor

Connectez-vous sur l’adresse http://IP_ESP32CAM/stream pour visualiser directement le flux vidéo

esp32-cam test ios

Intégrer le module ESP32-CAM à un serveur domotique

Maintenant, il est très facile d’intégrer le flux vidéo ou la capture dans la majorité des serveurs domotiques Open Source. Voici plusieurs guides détaillés pour Domoticz, Jeedom / Nexdom et Home Assistant

A LIRE AUSSI :
Intégrer un module ESP32-CAM à Domoticz (firmware modifié)
A LIRE AUSSI :
Intégrer un module ESP32-CAM à Jeedom ou NextDom (firmware modifié)
A LIRE AUSSI :
Intégrer un module ESP32-CAM à Home Assistant (firmware officiel)
A LIRE AUSSI :
Intégrer un module ESP32-CAM à un Dashboard Node-RED (firmware modifié)

Utiliser la LED Flash dans vos projets

L’ESP32-CAM dispose d’une LED flash sur la face avant de la carte. Elle est connectée au GIPO4 (broche n°26) de l’ESP32 comme on peut le voir sur le diagramme ci-dessous. Manque de chance cette broche est partagée avec la broche DATA1 du lecteur de carte SD (repère HS2_DATA1 sur le diagramme). Si vous n’utilisez pas le lecteur de carte micro SD dans vos projets, vous pourrez piloter la LED Flash. Dans le cas contraire, celle-ci est allumée en permanence dès qu’une carte SD est présente dans le lecteur. C’est un peu dommage car la LED allumée risque de signaler la présence de la caméra ou provoquer une gêne visuelle dans une chambre. C’est aussi problématique si l’on souhaite faire fonctionner l’ESP32-CAM sur batterie ou chaque micro-ampère consommé diminue d’autant l’autonomie.

ESP32_CAM V1.6 seeed studio diagram

Diagramme ESP32-CAM v1.6 disponible sur GitHub

Voici un exemple de code à intégrer à votre projet pour désactiver la LED Flash (uniquement si vous n’enregistrez pas d’image sur la carte micro SD)

int PIN_LED_LED = 4;

setup(){
    pinMode(PIN_LED_LED, OUTPUT);
}

loop(){
   digitalWrite(PIN_LED_LED, LOW);
}

 

Voilà, il ne reste plus qu’à développer votre propre caméra de surveillance IP. Pour être parfait, il faudra pensez à mettre en place une authentification (au moins avec un identifiant et mot de passe). Pour le moment le flux vidéo et l’image sont accessibles sans restriction. Ce n’est pas un (trop gros) problème si la caméra est connectée au réseau WiFi local mais il faudra mettre en place plus de sécurité si le module ESP32-CAM doit être exposé à internet. Je vous conseille de connecter votre flux vidéo à un serveur domotique sécurisé avec un certificat SSL pour ne pas avoir à gérer ce développement.

Avez-vous aimé cet article ?
[Total: 8 Moyenne: 5]
Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

Vous avez aimé ce projet ? Ne manquez plus aucun projet en vous abonnant à notre lettre d’information hebdomadaire!

quel modèle esp8266 choisir
Quel modèle d'ESP8266EX choisir en 2020 ?
guide choix esp32 development board
Quel ESP32 choisir en 2020 ?

Vous rencontrez un problème avec ce sujet ?

Peut-être que quelqu’un a déjà trouvé la solution, visitez le forum avant de poser votre question

71 Commentaires
  1. Bonjour,
    même problème résolu en n’oubliant pas le /stream derrière l’@ dans l’URL

  2. bonjour,
    comme suite au commentaire précédent non encore paru, je complète en disant que l’attribution d’une IP fixe est possible et fonctionne chez moi;
    Le seul truc qui coince encore et c’est incroyable (raison pour laquelle je n’ai pas trouvé tout de suite) c’est que seules les IP impaires fonctionnent …!!!! Si Si !!!
    En revanche il semble que changer le port et remplacer 80 par “otchoz” fonctionne aussi sans restriction.
    ++

  3. Bonjour; Chez moi tout fonctionne bien et je récupère le flux vidéo dans Domoticz;
    Cependant, j’ai tenté de fixer l’IP de chaque module par //WiFi.config(ip, dns, gateway, subnet); et les data qui vont bien;
    Au Reset, l’IP voulue est bien prise en compte cependant aucun flux vidéo ni accès a la page /stream;
    La simple mise en rem de la ligne ci-dessus redonne la main au DHCP et, a nouveau, la page est accessible.
    Avez vous une idée du pourquoi de la chose ?

  4. Bonjour,

    Apparemment la connexion WiFi se réalise puis que le moniteur écrit:

    .I (4302) wifi: connected with **************************, channel 6, BW20
    I (4307) wifi: pm start, type: 1

    ..
    [I][cam_1.ino:262] startCameraServer(): Register URIs and start web server
    [I][cam_1.ino:334] setup(): Camera Stream Ready
    192.168.1.97

    et laisse l’IP !
    Mais la suite des lignes du moniteur, d’après moi, indique qu’il n’ y a plus de dialogue avec le réseau WiFi ou câblé.

    ping de l’url : PING 192.168.1.97 (192.168.1.97) 56(84) bytes of data.

    Essayez avec le port 8080 !

    L’Arsène.

  5. Bonjour ;

    En effet toutes les opérations que vous énumerez ont bien été faites mais le problème reste identique : This URI doesn’t exist.
    J’ai intégré les lignes de code proposées par l’Arsène, mais ça n’a rien changé.

    Par ailleurs l’adresse ip est tout à fait visible dans le service DHCP de la box. Faisant les premiers pas avec ce module, je suis à cours d’inspiration :o)

    Merci de votre attention

    Cordialement.

    • Bonjour Jacques. Je dois dire que moi aussi, évidemment si j’avais la carte dans les mains, ce serait différent 😉 Pourriez vous tester l’exemple HelloServer (exemples -> webserver -> helloserver) disponible dans les exemples des cartes ESP32 pour vérifier si le problème ne viendrait pas de la carte tout simplement. Je n’ai jamais rencontré le problème mais j’imagine qu’une panne de l’émetteur WiFi (ou un antenne défectueuse) n’est pas à exclure. L’idéal serait de tester le code sur un autre ESP32 pour s’assurer qu’il fonctionne correctement puis le téléverser sur l’ESP32-CAM. Si ça fonctionne ça vient du code, sinon, c’est la carte qui est défectueuse.

  6. Bonjour ;

    Voici la sortie sur le moniteur série (raspberry pi -> buster) :

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1216
    ho 0 tail 12 room 4
    load:0x40078000,len:9720
    ho 0 tail 12 room 4
    load:0x40080400,len:6352
    entry 0x400806b8
    I (1794) wifi: wifi driver task: 3ffba4d0, prio:23, stack:3584, core=0
    I (3671) wifi: wifi firmware version: 7997e4b
    I (3671) wifi: config NVS flash: enabled
    I (3672) wifi: config nano formating: disabled
    I (3672) wifi: Init dynamic tx buffer num: 32
    I (3676) wifi: Init data frame dynamic rx buffer num: 32
    I (3681) wifi: Init management frame dynamic rx buffer num: 32
    I (3687) wifi: Init management short buffer num: 32
    I (3692) wifi: Init static rx buffer size: 1600
    I (3696) wifi: Init static rx buffer num: 16
    I (3700) wifi: Init dynamic rx buffer num: 32
    I (3761) wifi: mode : sta (f0:08:d1:76:99:d4)
    I (3885) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
    I (3886) wifi: state: init -> auth (b0)
    I (3890) wifi: state: auth -> assoc (0)
    I (3933) wifi: state: assoc -> run (10)
    .I (4302) wifi: connected with **************************, channel 6, BW20
    I (4307) wifi: pm start, type: 1

    ..
    [I][cam_1.ino:262] startCameraServer(): Register URIs and start web server
    [I][cam_1.ino:334] setup(): Camera Stream Ready
    192.168.1.97

    ping de l’url : PING 192.168.1.97 (192.168.1.97) 56(84) bytes of data.
    64 bytes from 192.168.1.97: icmp_seq=1 ttl=255 time=143 ms
    64 bytes from 192.168.1.97: icmp_seq=2 ttl=255 time=167 ms
    64 bytes from 192.168.1.97: icmp_seq=3 ttl=255 time=190 ms
    64 bytes from 192.168.1.97: icmp_seq=4 ttl=255 time=213 ms
    64 bytes from 192.168.1.97: icmp_seq=5 ttl=255 time=32.5 ms
    64 bytes from 192.168.1.97: icmp_seq=6 ttl=255 time=54.4 ms
    64 bytes from 192.168.1.97: icmp_seq=7 ttl=255 time=77.9 ms
    64 bytes from 192.168.1.97: icmp_seq=8 ttl=255 time=105 ms
    64 bytes from 192.168.1.97: icmp_seq=9 ttl=255 time=126 ms
    64 bytes from 192.168.1.97: icmp_seq=10 ttl=255 time=149 ms
    64 bytes from 192.168.1.97: icmp_seq=11 ttl=255 time=173 ms
    64 bytes from 192.168.1.97: icmp_seq=12 ttl=255 time=197 ms
    64 bytes from 192.168.1.97: icmp_seq=13 ttl=255 time=221 ms
    64 bytes from 192.168.1.97: icmp_seq=14 ttl=255 time=39.3 ms
    64 bytes from 192.168.1.97: icmp_seq=15 ttl=255 time=61.8 ms
    64 bytes from 192.168.1.97: icmp_seq=16 ttl=255 time=85.9 ms
    64 bytes from 192.168.1.97: icmp_seq=17 ttl=255 time=109 ms
    64 bytes from 192.168.1.97: icmp_seq=18 ttl=255 time=133 ms
    64 bytes from 192.168.1.97: icmp_seq=19 ttl=255 time=157 ms
    64 bytes from 192.168.1.97: icmp_seq=20 ttl=255 time=181 ms
    64 bytes from 192.168.1.97: icmp_seq=21 ttl=255 time=204 ms
    64 bytes from 192.168.1.97: icmp_seq=22 ttl=255 time=23.8 ms
    …….

    mais lorsque je tente d’afficher le résultat dans le navigateur :

    This URI doesn’t exist

    Une petite idée ?

    Merci

    • Bonjour Jacques, avez vous modifié le port du serveur ?

      • Bonjour ;

        En premier lieu, merci de m’avoir répondu.

        Non j’ai gardé le port 80 :

        #define WEB_SERVER_PORT 80

        Cordialement

        • Donc si on résume, vous avez conservé le port 80, téléversé avec succès le projet, débranché le jumper entre la broche IO0 et GND, fait un reset de la carte puis tenté d’accéder au serveur vidéo à l’adresse http://192.168.1.97:80 (le 80 n’est pas obligatoire) ? La carte est bien alimentée via une alimentation séparée sur la broche 5V et il n’y a pas de reboot intempestif ?

  7. Bonsoir,

    Pour vous aider, voici vos codes modifiés pour le RAZ si manque connections au WiFi.

    /*********
    projetsdiy.fr – diyprojects.io

    Step by step tutorial
    En français https://projetsdiy.fr/esp32-cam-flash-firmware-test-domoticz-jeedom-home-assistant-nextdom-node-red/

    IMPORTANT BEFORE TO DOWNLOAD SKETCH !!!
    – Install ESP32 libraries
    – Select Board “ESP32 Wrover Module”
    – Select the Partion Scheme “Huge APP (3MB No OTA)”
    – Sélectionner aussi “Core Debug Level:”Verbose””
    – GPIO 0 must be connected to GND to upload a sketch
    – After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files.
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    Modifs:

    20/10/2020 Rajout des lignes du Restart si pas de connection au WiFi selon le temps aloué par la variable “compteur”
    *********/

    #include <esp_event_loop.h>
    #include <esp_log.h>
    #include “esp_timer.h”
    #include “esp_camera.h”

    #include <WiFi.h>
    #include “img_converters.h”
    #include “Arduino.h”
    #include “fb_gfx.h”
    #include “soc/soc.h” //disable brownout problems
    #include “soc/rtc_cntl_reg.h” //disable brownout problems
    //#include “dl_lib.h”
    #include “esp_http_server.h” // API https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/esp_http_server.html

    #include “driver/sdmmc_host.h”
    #include “driver/sdmmc_defs.h”
    #include “sdmmc_cmd.h”
    #include “esp_vfs_fat.h”

    // Remplacez par vos identificants de connexion WiFi
    const char* ssid = “NETGEAR_SALON”;
    const char* password = “NETGEARSALON18”;
    byte compteur = 0; // Pour le reset si pas de connection WiFi

    #define SERIAL_DEBUG true // Activer / désactiver le journal
    #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

    // Web server port – port du serveur web
    #define WEB_SERVER_PORT 8080
    #define URI_STATIC_JPEG “/jpg/image.jpg”
    #define URI_STREAM “/stream”

    // Basic image Settings (compression, flip vertical orientation) – Réglages basiques de l’image (compression, inverse les orientations)
    #define FLIP_V 0 // Inverse l’image verticalement de 180° Pas dans tous les cas du choix de la caméra !!
    #define MIRROR_H 0 // Miroir horizontal Pas dans tous les cas du choix de la caméra !!
    #define IMAGE_COMPRESSION 10 //0-63 Plus de chiffre est petit, meilleure est la qualité de l’image, plus gros est le fichier

    static const char *TAG = “esp32-cam”;

    /*
    Entête pour le flux vidéo
    /
    #define PART_BOUNDARY “123456789000000000000987654321”
    static const char
    _STREAM_CONTENT_TYPE = “multipart/x-mixed-replace;boundary=” PART_BOUNDARY;
    static const char* _STREAM_BOUNDARY = “\r\n–” PART_BOUNDARY “\r\n”;
    static const char* _STREAM_PART = “Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n”;

    // Décommentez votre carte de développement
    // le croquis a été testé uniquement avec le modèle AI Thinker
    //#define CAMERA_MODEL_WROVER_KIT
    //#define CAMERA_MODEL_ESP_EYE
    //#define CAMERA_MODEL_M5STACK_PSRAM
    //#define CAMERA_MODEL_M5STACK_WIDE
    #define CAMERA_MODEL_AI_THINKER

    #if defined(CAMERA_MODEL_WROVER_KIT)
    #define PWDN_GPIO_NUM -1
    #define RESET_GPIO_NUM -1
    #define XCLK_GPIO_NUM 21
    #define SIOD_GPIO_NUM 26 //Flash LED – Flash Light is On if SD card is present
    #define SIOC_GPIO_NUM 27
    #define Y9_GPIO_NUM 35
    #define Y8_GPIO_NUM 34
    #define Y7_GPIO_NUM 39
    #define Y6_GPIO_NUM 36
    #define Y5_GPIO_NUM 19
    #define Y4_GPIO_NUM 18
    #define Y3_GPIO_NUM 5
    #define Y2_GPIO_NUM 4
    #define VSYNC_GPIO_NUM 25
    #define HREF_GPIO_NUM 23
    #define PCLK_GPIO_NUM 22

    #elif defined(CAMERA_MODEL_M5STACK_PSRAM)
    #define PWDN_GPIO_NUM -1
    #define RESET_GPIO_NUM 15
    #define XCLK_GPIO_NUM 27
    #define SIOD_GPIO_NUM 25
    #define SIOC_GPIO_NUM 23
    #define Y9_GPIO_NUM 19
    #define Y8_GPIO_NUM 36
    #define Y7_GPIO_NUM 18
    #define Y6_GPIO_NUM 39
    #define Y5_GPIO_NUM 5
    #define Y4_GPIO_NUM 34
    #define Y3_GPIO_NUM 35
    #define Y2_GPIO_NUM 32
    #define VSYNC_GPIO_NUM 22
    #define HREF_GPIO_NUM 26
    #define PCLK_GPIO_NUM 21

    #elif defined(CAMERA_MODEL_AI_THINKER)
    #define PWDN_GPIO_NUM 32
    #define RESET_GPIO_NUM -1
    #define XCLK_GPIO_NUM 0
    #define SIOD_GPIO_NUM 26 //Flash LED – Flash Light is On if SD card is present
    #define SIOC_GPIO_NUM 27
    #define Y9_GPIO_NUM 35
    #define Y8_GPIO_NUM 34
    #define Y7_GPIO_NUM 39
    #define Y6_GPIO_NUM 36
    #define Y5_GPIO_NUM 21
    #define Y4_GPIO_NUM 19
    #define Y3_GPIO_NUM 18
    #define Y2_GPIO_NUM 5
    #define VSYNC_GPIO_NUM 25
    #define HREF_GPIO_NUM 23
    #define PCLK_GPIO_NUM 22
    #else
    #error “Camera model not selected”
    #endif

    httpd_handle_t stream_httpd = NULL;

    /*
    Cette méthode ne publie qu’une seule image JPEG
    Compatible avec Jeedom / NextDom / Domoticz
    */
    static esp_err_t capture_handler(httpd_req_t *req) {
    camera_fb_t *fb = NULL;
    esp_err_t res = ESP_OK;
    size_t fb_len = 0;
    int64_t fr_start = esp_timer_get_time();

    res = httpd_resp_set_type(req, “image/jpeg”);
    if (res == ESP_OK)
    {
    res = httpd_resp_set_hdr(req, “Content-Disposition”, “inline; filename=image.jpg”); //capture
    }
    if (res == ESP_OK) {
    ESP_LOGI(TAG, “Take a picture”);
    //while(1){
    fr_start = esp_timer_get_time();
    fb = esp_camera_fb_get();
    if (!fb)
    {
    ESP_LOGE(TAG, “Camera capture failed”);
    httpd_resp_send_500(req);
    return ESP_FAIL;
    } else {
    fb_len = fb->len;
    res = httpd_resp_send(req, (const char *)fb->buf, fb->len);

    esp_camera_fb_return(fb); // Décommentez pour connaître le débit //int64_t fr_end = esp_timer_get_time(); //ESP_LOGD(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len / 1024), (uint32_t)((fr_end - fr_start) / 1000)); return res; } //}

    }
    }

    /*
    This method stream continuously a video
    Compatible avec Home Assistant, HASS.IO
    */
    esp_err_t stream_handler(httpd_req_t *req) {
    camera_fb_t * fb = NULL;
    esp_err_t res = ESP_OK;
    size_t _jpg_buf_len;
    uint8_t * _jpg_buf;
    char * part_buf[64];
    static int64_t last_frame = 0;
    if (!last_frame) {
    last_frame = esp_timer_get_time();
    }

    res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
    if (res != ESP_OK) {
    return res;
    }
    ESP_LOGI(TAG, “Start video streaming”);
    while (true) {
    fb = esp_camera_fb_get();
    if (!fb) {
    ESP_LOGE(TAG, “Camera capture failed”);
    res = ESP_FAIL;
    } else {
    if (fb->format != PIXFORMAT_JPEG) {
    bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
    if (!jpeg_converted) {
    ESP_LOGE(TAG, “JPEG compression failed”);
    esp_camera_fb_return(fb);
    res = ESP_FAIL;
    }
    } else {
    _jpg_buf_len = fb->len;
    _jpg_buf = fb->buf;
    }
    }
    if (res == ESP_OK) {
    size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);

    res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } if (res == ESP_OK) { res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); } if (res == ESP_OK) { res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); } if (fb->format != PIXFORMAT_JPEG) { free(_jpg_buf); } esp_camera_fb_return(fb); if (res != ESP_OK) { break; } //Décommentez pour connaître le débit /* int64_t fr_end = esp_timer_get_time(); int64_t frame_time = fr_end - last_frame; last_frame = fr_end; frame_time /= 1000; ESP_LOGD(TAG, "MJPG: %uKB %ums (%.1ffps)", (uint32_t)(_jpg_buf_len/1024), (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time); */

    }

    last_frame = 0;
    return res;
    }

    void startCameraServer() {
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    config.server_port = WEB_SERVER_PORT;

    // endpoints
    static const httpd_uri_t static_image = {
    .uri = URI_STATIC_JPEG,
    .method = HTTP_GET,
    .handler = capture_handler,
    .user_ctx = NULL
    };

    static const httpd_uri_t stream_video = {
    .uri = URI_STREAM,
    .method = HTTP_GET,
    .handler = stream_handler,
    .user_ctx = NULL
    };

    ESP_LOGI(TAG, “Register URIs and start web server”);
    if (httpd_start(&stream_httpd, &config) == ESP_OK) {
    if ( httpd_register_uri_handler(stream_httpd, &static_image) != ESP_OK) {
    ESP_LOGE(TAG, “register uri failed for static_image”);
    return;
    };
    if ( httpd_register_uri_handler(stream_httpd, &stream_video) != ESP_OK) {
    ESP_LOGE(TAG, “register uri failed for stream_video”);
    return;
    };
    }
    }

    void setup() {
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

    Serial.begin(115200);
    Serial.setDebugOutput(SERIAL_DEBUG);
    esp_log_level_set(“*”, ESP_LOG_LEVEL);

    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_sscb_sda = SIOD_GPIO_NUM;
    config.pin_sscb_scl = SIOC_GPIO_NUM;
    config.pin_pwdn = PWDN_GPIO_NUM;
    config.pin_reset = RESET_GPIO_NUM;
    config.xclk_freq_hz = 20000000; //XCLK 20MHz or 10MHz
    config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG
    config.frame_size = FRAMESIZE_SVGA; //UXGA SVGA VGA QVGA Do not use sizes above QVGA when not JPEG
    config.jpeg_quality = 10;
    config.fb_count = 2; //if more than one, i2s runs in continuous mode. Use only with JPEG

    // Ajouter pour RAZ lors du démarrage si pas de connection établie

    // Camera init – Initialise la caméra
    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK) {
    ESP_LOGE(TAG, “Camera init failed with error 0x%x”, err);
    return;
    } else {
    ESP_LOGD(TAG, “Camera correctement initialisée “);
    sensor_t * s = esp_camera_sensor_get();
    s->set_vflip(s, FLIP_V); // Prend en compte l’inverion verticale! Pas dans tous les cas du choix de la caméra
    s->set_hmirror(s, MIRROR_H); // Prend en compte l’inversion horizontale! Pas dans tous les cas du choix de la caméra
    }

    // Wi-Fi connection – Connecte le module au réseau Wi-Fi
    ESP_LOGD(TAG, “Start Wi-Fi connexion “);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);

    //================= Ajouter pour RAZ lors du démarrage si pas de connection établie
    compteur ++;
    if (compteur >= 20){
    Serial.print(“RAZ demandé”);
    ESP.restart();
    }

    }
    Serial.println(“”);
    ESP_LOGD(TAG, “Wi-Fi connected “);

    // Start streaming web server
    startCameraServer();

    ESP_LOGI(TAG, “Camera Stream Ready”);
    Serial.println(WiFi.localIP());
    }

    void loop() {
    delay(1);
    }

    • Bonsoir et merci beaucoup. Je vous propose plutôt de mettre l’ESP32-CAM en mode deep-sleep en cas d’échec ou de perte de connexion afin de ne pas drainer la batterie ou de consommer inutilement du courant. Je viens de publier l’article à l’instant. Bonne soirée

  8. Bonjour,
    Comme Fido qui a des problèmes de déconnection WiFi et lors de la mise sous tension du module, j’ai proposé la modif du programme qui fonctionne très bien dans mon cas!
    Elle est postée en deux versions dans le contenu des commentaires.

    Bonne journée.
    L’Arsène.

    • Merci l’Arsène, j’ai plus qu’à faire la synthèse de tout votre travail alors ! Merci beaucoup, je m’y colle la semaine prochaine 🙂 Merci et bon week end

  9. Bonjour,
    encore un superbe tuto… merci.
    Je rencontre un soucis chez moi…
    Mon routeur, pour une raison que je ne m’explique pas, reboote au moins une fois par jour.
    Du coup, je perd le flux camera….et je suis obligé de le resetter manuellement.
    Saurais tu m’aiguiller pour trouver une boucle/bout de code à insérer pour que régulièrement l’ESP vérifie sa connexion et qu’en cas de perte soit il se reconnecte automatiquement ou il fait un reboot?

    J’ai beau chercher sur le net, je ne trouve rien de satisfaisant ou de compréhensible ou en anglais.
    Merci beaucoup de ton aide.

    • Bonjour Fido. Excellente idée. Je vais regarder ça

      • Ah oui, ce serait vraiment super.. je bloque avec la programmation (et encore plus sur arduino)…
        Si ça peut faire avancer le schmilblick, j’ai trouvé ça sur un site en allemand: https://medium.com/diy-my-smart-home/esp-tipp-wifi-reconnect-einbauen-dc4a7397b741

        de ce que j’en comprend, il s’agit d’un reboot

        void loop() {

        int wifi_retry = 0;
        while(WiFi.status() != WL_CONNECTED && wifi_retry < 5 ) {
        wifi_retry++;
        Serial.println(“WiFi not connected. Try to reconnect”);
        WiFi.disconnect();
        WiFi.mode(WIFI_OFF);
        WiFi.mode(WIFI_STA);
        WiFi.begin(config.ssid.c_str(), config.password.c_str());
        delay(100);
        }
        if(wifi_retry >= 5) {
        Serial.println(“\nReboot”);
        ESP.restart();
        }
        }

        Mais je ne vois pas, où et à quel moment d’une boucle l’intégrer dans un code existant

        • Bonsoir Fido, je viens de publier le tutoriel avec le code source. Comme je viens de l’expliquer à l’Arsène, je vous propose plutôt de mettre le mode deep-sleep et le réveiller pour faire une nouvelle tentative. En cas d’échec, le module retourne en sommeil. Ca évite de consommer inutilement et de drainer la batterie. A très bientôt…je continue sur ma lancée, j’attaque le déplacement de la résistance pour passer sur l’antenne externe, j’ai des problèmes de vidéo saccadée chez moi, ça devrait améliorer les choses…enfin je l’espère. Bonne soirée.

  10. Merci pour l’article. Y’a t’il une caméra plus sensible la nuit que la OV7670 ou la caméra de base OV2640 et qui soit compatible avec l’ESP32?

    • Bonjour et merci. A priori, le code supporte les trois capteurs suivants : OV7670, OV2640 et OV5640-AF (auto-focus) mais aucun n’est vraiment conçu pour la vision nocturne. J’ai fait une chercher avec le mot clé night vision sur le site d’Omni Vision le fabricant des capteurs CMOS utilisés pour les ESP32 CAM. L’OV7850 pourrait convenir, malheureusement on ne le trouve pas sur les boutiques en ligne (Aliexpress, Banggood…) probablement parce qu’il a été remplacé par l’OV10626, qui n’est pas accessible au grand public non plus…bref pour le moment je n’ai rien trouvé pour la vision nocturne. Si quelqu’un a trouvé une solution, n’hésitez pas à nous le dire:)

  11. Bonjour,

    J’ai repris le programme dont il est question du non démarrage du module ESP32 CAM lors de sa mise sous tension par une version plus soft et surement plus plaisante !!

    compteur ++; if (compteur >= 20){ Serial.print("RAZ demandé"); ESP.restart(); }

    L’Arsène.

  12. Bonjour,
    En réponse pour Gilles de son post du 27 aout, chez moi le port pour la caméra est le 8080 et non 80 !

    L’Arsène.

  13. Bonjour,
    Je suppose que comme avec mes ensembles ESP32 Cam et caméras vous avez des soucis de non connection au WiFi lors des mises sous tension ! La Remise A Zéro est souvent nécessaire pour un fonctionnement normal. En rajoutant quelques lignes au programme pour l’exploitation d’un des GPIO accessible et un petit montage à base d’un mosfet, la RAZ sera effectuée selon ces lignes rajoutées si la réponse à la connection WiFi d’abouti pas.

    // Wi-Fi connection – Connecte le module au réseau Wi-Fi
    ESP_LOGD(TAG, “Start Wi-Fi connexion “);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(“.”);

    compteur ++; if (compteur >= 20){ digitalWrite(Restart, HIGH); Serial.print("RAZ demandé"); }

    Après 20 routines de connections et la tempo de 500 ms, le GPIO nommé Restart passera un niveau hight pour effectuer la RAZ. Evidemment il faudra déclarer les variables compteur et Restart !

    Cela fonctionne parfaitement avec mes module ESP32 Cam.
    Cordialement.
    L’Arsène.

  14. Bonjour,
    super travail et très beau contenu partagé sur l’ensemble du site d’ailleurs !

    Est-il possible de faire en sorte que l’ESP32 Cam emette son propre réseau wifi au lieu de se connecter à un réseau existant ?

    Pour être plus clair, le but serait réaliser une caméra pour microscope dont le flux vidéo pourrait être consulter via des tablettes qui se connecteraient directement au wifi de l’ESP32 et non au réseau de l’établissement qui est une vraie plaie.

    Après coup, j’imagine alors ce système pourrait aussi se décliner en version totalement mobile pour les sorties de terrain.

    • Bonsoir, j’ai pris le temps de faire qq tests avant de vous répondre. Il est possible de mettre l’ESP32-CAM en mode Access Point. Il existe un programme déjà tout fait disponible depuis le menu

      Ensuite, il faut mettre en commentaire (ou remplacer) le code de connexion au réseau WiFi
      /* WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(“.”);
      }
      Serial.println(“”);
      Serial.println(“WiFi connected”);*/
      Puis ajouter cette ligne de code
      WiFi.softAP(ssid, password);

      Par contre ne vous attendez pas à des performances exceptionnelles. L’ESP32-CAM ne va pas encaisser la charge et je doute que plus de 2 personnes puissent voir la vidéo. En plus la qualité de la caméra est très limitée.

      Pour votre projet, si vous avez le budget et peut etre le matériel, je vous conseille plutot de partir sur le Raspberry Pi et la nouvelle caméra HQ équipée d’un adaptateur pour objectif à monture C.

      J’ai trouvé votre idée sympa alors j’ai développé un microscope et récupérant des éléments d’un vieille imprimante 3D. Je suis en train de rédiger l’article, il sera en début de semaine prochaine. Je ne peux pas simuler une classe entière mais avec plusieurs navigateurs ouverts sur smartphones et portables des enfants, ça passe crème avec un vieux Raspberry Pi 3.

      Bon week end

      • Merci beaucoup ! C’est très sympa d’avoir pris le temps de me répondre avec autant de détails.
        Certes, la puissance de la machine ne sera pas folle, mais ce sera toujours mieux que les caméras que nous utilisons actuellement et qui nous sont vendues plus de 85€ pour finalement ne pas fonctionner dès qu’on fait une mise à jours sur les machines de l’établissement.
        La caméra ne sera que de 2 MP, mais celles du commerce ne font que 1,3 MP donc encore un point de plus pour l’ESP.

        Le RPI est une bonne idée, c’est ce que j’aurais choisi pour moi, mais le but est aussi de montrer aux collègues comment se fabriquer aussi leur propre outil, ou bien une flotte pour leur établissement, à moindre coût. Je crains que le RPI fasse encore plus peur à ces collègues, qui ne sont pas toujours amis avec le numérique.

        J’ai hâte de voir votre prochain article, ça a l’air très prometteur. Je suis très impatient de voir comment vous allez gérer les lentilles par exemple, en tout cas, si c’est prévu… S’il n’y en n’a pas, et simplement dans un objectif d’exactitude pour votre article, vous allez peut-être fabriquer une “loupe mono ou binoculaire” connectée du coup, ce qui tout aussi intéressant.

        Bon week end !

        • En fait pour répondre plus clairement à votre question, je pense qu’il faut simplement établir les différences qu’il peut y avoir entre un microscope et une loupe binoculaire (comme en on peut en avoir en établissements.
          – Microscope optique : permet d’observer les structures microscopiques, de l’ordre de la cellule ou plus petit. Nous sommes à l’échelle du nanomètre principalement. On peu deviner des structures plus petites, mais cela devient difficile avec les microscopes classiques de l’éducation. l’appareil se caractérise par une source lumineuse qui va traverser la lame d’observation, passer par un objectif (première lentille de x4, x10 ou x40 par exemple), puis une seconde lentille que l’on appelle “oculaire” (x10 le plus souvent). Le grossissement peut donc aller jusqu’à x400, x600, ou x1000 pour les bons modèles. L’observateur place son oeil à la sortie de l’oculaire et choisit l’objectif qu’il utilise selon ce qu’il observe.

          Une loupe permet d’observer des éléments petits, mais non microscopiques. Il peut y avoir une source lumineuse complémentaire, mais celle-ci ne traverse pas l’objet, elle arrive sur l’objet lui-même. L’observation n’est donc pas contrainte d’être sous la forme d’une lame d’observation en verre, traversée par la lumière. On peut par exemple s’intéresser à la cuticule d’un insecte, la surface d’une feuille ou autre. La plupart des “microscopes” mobiles ou gadgets du commerce sont en réalité plutôt des loupes. Ils sont bien plus simples à réaliser et permettent déjà d’initier à la science et à l’observation, de nombreuses personnes.

        • Oui, je suis parfaitement d’accord avec vous. On va plus se rapprocher de la loupe binoculaire que du microscope y compris avec la caméra du Raspberry Pi. J’ai commandé des optiques supplémentaires pour voir s’il est possible de faire un montage économique et performant…

        • Avec plaisir. Et bien le mieux et de faire les 2 projets ! Je termine la version Raspberry Pi en cours et je regarde comment faire un mini-microscope avec l’ESP32-CAM. Pourriez vos m’en dire plus sur le grossissement et les fonctions dont vous avez besoin ?

  15. Bonsoir,
    Déjà évoqué lors un autre commentaire qui n’a pas paru, est il possible de faire une rotation de la vidéo de 90° pour que l’image soit verticale le module ESP32 étant debout ?
    Merci d’avance pour vos réponses.

    • Re-bonsoir, le tutoriel répond aussi à cette question. Par contre impossible de le faire directement sur l’ESP32. Il n’y a aucune méthode, cela semble être un problème de puissance, surtout lorsque l’image fait 2MP.

  16. Bonjour, la réponse concernait le post du 23/08/20 à 23h03..

    J’ai toujours un souci avec la vidéo lorsque l’on change le port 80 par 8680 (ou autre).
    Merci

    PS: j’ai essayé de laisser le serveur vidéo sur la port 81 au lieu de 8680+1 (et le serveur web sur la page 8680) le problème est le même, pas d’affichage vidéo et le moniteur série ne vois pas la demande de vidéo…
    Si quelqu’un à une idée… Merci

  17. Re-Bonjour, à tous et toutes!
    Je reviens avec une nouvelle question j’ai changé le port web (80 d’origine) par 8680 (le port 80 de ma livebox est dédié à un serveur NAS…)
    J’arrive bien à accéder à la page web de l’esp32 en tapant son adresse IP:8680 la page s’affiche,

    Je peux commander la carte,(LED,..) capturer des images, mais le flux vidéo lui ne fonctionne plus…
    j’ai essayé d’autres port, (en les ouvrants dans la box) mais je n’y arrive pas la vidéo ne fonctionne que si l’esp32 est sur le port 80…

    Merci pour toute piste ou solution!

  18. C’est bon j’ai enfin trouvé, il s’agissait d’un problème d’iPhone, sur le PC cela roule. Merci

  19. Bonjour, merci pour ce post.
    Après avoir pas mal galéré avec l’absence du fichier dh_lib.h (résolu en passant de la version 1.04 à la 1.0.2 pour l’esp 32 (menu fichier/préférences/ URL de gestionnaire de carte supplémentaires : https://dl.espressif.com/dl/package_esp32_index.json)

    J’ai le même soucis qu’avant (lorsque je commentait l ligne #include”dh.lib.h” pour éviter l’erreurdu fichier non trouvé… A savoir pas d’URl pour me connecter à l’esp 32 cam : voici ce que donne mon moniteur série :
    ets Jun 8 2016 00:22:57

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1100
    load:0x40078000,len:9232
    load:0x40080400,len:6400
    entry 0x400806a8
    ⸮I (1772) wifi: wifi driver task: 3ffba530, prio:23, stack:3584, core=0
    I (3610) wifi: wifi firmware version: 6d404d4
    I (3611) wifi: config NVS flash: enabled
    I (3613) wifi: config nano formating: disabled
    I (3636) wifi: Init dynamic tx buffer num: 32
    I (3637) wifi: Init data frame dynamic rx buffer num: 10
    I (3637) wifi: Init management frame dynamic rx buffer num: 10
    I (3641) wifi: Init static rx buffer size: 1600
    I (3645) wifi: Init static rx buffer num: 8
    I (3648) wifi: Init dynamic rx buffer num: 10
    I (3717) wifi: mode : sta (f0:08:d1:c7:d4:b0)
    I (3857) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
    .I (4591) wifi: state: init -> auth (b0)
    I (4595) wifi: state: auth -> assoc (0)
    I (4600) wifi: state: assoc -> run (10)
    I (4622) wifi: connected with iPhone Gilles, channel 6
    I (4628) wifi: pm start, type: 1


    172.20.10.5

    Pas d’adresse IP comme dans l’exemple…Et l’adresse 172.20.10.5 ne donne rien..
    Si quelqu’un sait comment résoudre mon problème… Merci d’avance

  20. Bonjour.
    Pas évident a faire quand on ne s’y connais pas comme moi.
    Pour tous ceux qui voudrais se lancer comme moi en 2020, ne prenez pas la dernière version de l’adruino et las le dernier SDK.
    Avec la version de l’IDE 1.8.9 et le SDK 1.0.2 permettent le téléversement sans erreur notamment du fichier dl_lib.h tellement recherché.
    J’ai commencer mes essais sur un PC portable, tout se passe bien sauf a l’appel de l’ip de la caméra, lesp32 rebooter, manque de voltage probablement.

    Sur le un PC fixe j’ai un autre probléme, a l’appel de l’ip j’ai bien le message “This URI doesn’t exist”
    Quand je met ip/stream le navigateur cherche mais ne m’affiche rien.
    L’esp32 detecte bien la demande mais rien : 16:32:11.242 -> [I][ESPcam32.ino:189] stream_handler(): Start video streaming

    Je ne trouve pas pourquoi ?

  21. Bonjour,
    Le problème de la librairie dl_lib.h manquante a t’il été élucidé ?
    J’ai beau chercher, je ne trouve pas cette librairie à par dlib master qui ne donne pas de résultat !
    Merci pour les réponses.
    Bon WE.

  22. Hello,

    Pour ceux qui ont un problème de Time Out, et qui ont cherché toutes les solutions possibles… essayer simplement d’échanger le RT et le TX.

    Chez moi, après une heure de recherche, ça a marché nickel !

  23. Bonjour,

    Dans le but économiser de l’énergie et aussi de plus de discrétion, comme soulevé dans votre article, tout en voulant enregistrer les images sur la Carte SD, peut-on purement et simplement supprimer le Led blanche ?

    Merci de votre réponse

  24. le VCC est en Output selon le datasheet du fabriquant et le reset est nécessaire pour provoquer le upload

  25. Bonjour, je vous ai écrit recemment concernant une erreur lors du téléversement – à savoir : “« A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header “. le probleme est résolu, j’ai du remplacer la carte UART défecteuse…En vous remerciant pour votre réponse et votre support et encore bravo pour votre travail. Cdlt Patrick

    • Bonjour Patrick et merci beaucoup pour le retour. Je suis en train de collecter tous les problèmes que l’on peut rencontrer au moment de flasher un ESP32, c’est une info précieuse. A très bientôt

  26. Bonjour, merci pour cet article, le temps et le travail afferent – tres instructif et tres didactique. Quant à moi j’i un probleme semble t-il trés frequent : “A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header”. Je ne vois pas de probleme dans le cablage. En particulier le bouclage entre GND et IO0 est effectif.
    Le bouton RESET doit il être appuyé tout le temps du reversement?
    Je suis preneur de toute idée pour résoudre ce problème. Merci

    Voici le log complet :
    Arduino: 1.8.13 (Windows 7), Board: “ESP32 Wrover Module, Huge APP (3MB No OTA/1MB SPIFFS), QIO, 40MHz, 115200, None”
    Sketch uses 2100647 bytes (66%) of program storage space. Maximum is 3145728 bytes.
    Global variables use 53552 bytes (16%) of dynamic memory, leaving 274128 bytes for local variables. Maximum is 327680 bytes.
    esptool.py v2.6
    Serial port COM15
    Connecting…….._____….._____….._____….._____….._____….._____….._____
    A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header..

    • Bonjour Patrick. Tout d’abord un grand merci. Il n’est pas nécessaire de maintenir appuyé le bouton RESET, c’est vraiment le pont entre GND et IO0 qui fait passer l’ESP32 en mode bootload. C’est peut être l’origine du problème d’ailleurs.
      Pour aller plus loin, pourriez vous me donner les références de la carte ESP32-CAM que vous utilisez. Merci d’avance

  27. hello,

    du nouveau de ton firmware ?

  28. Bonjour, j’aimerais pouvoir prendre le résultat de la capture et l’envoyer par mail.
    Comment puis-je retrouver le fichier /jpg/image.jpg pour l’envoyer en attachement, avec quelle syntaxe puis le prendre pour dans le esp_vfs_fat.h ?

    • Bonjour Eddy, c’est un peu trop long à expliquer dans un commentaire. Je vais directement en faire un tuto. J’espère que vous pouvez patienter jusqu’à la semaine prochaine.

  29. Bonjour,
    Merci pour votre travail.
    J’ai un problème à la compilation :

    esp32cam_DIY:30:20: fatal error: dl_lib.h: No such file or directory

    Plusieurs bibliothèque trouvées pour “WiFi.h”
    compilation terminated.

    Utilisé : C:\Users\Thierry\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
    Non utilisé : C:\Program Files (x86)\Arduino\libraries\WiFi
    exit status 1
    dl_lib.h: No such file or directory

    Pourriez-vous m’aider ?
    Par avance merci.

    • Bonjour, j’ai rencontré le même probleme avec la dl_lib.h. J’ai telecharger la lib esp-sr-master et je n’ai pris que le contenu de lib/include/ que j’ai mis sous arduino librairies lb_lib que j’ai créé et ça a fonctionné.
      Je l’ai fait pour la m5cam ou il faut changer dans la config le siod_gpio_num a22 au lieu de 25 ainsi que le vsync_gpio_num a 25 au lieu de 22.
      Et ça ronronnent bien.
      Merci pour votre boulot.
      Eddy

    • Bonsoir Thierry, avez-vous sélectionné la carte ESP32 Wroover dans la liste avant de compiler ?

  30. Bonjour à tous;

    Merci pour cette explication!

    En revanche je rencontre aussi le problème avec la librairie dl-lib.h …

    Que peut on faire pour résoudre ce point bloquant ?

    En vous remerciant par avance

    Maxime

  31. Bonjour,
    Impossible de téléverser la démo,:
    ci joint les deux messages d’erreur:

    reset button
    ////////////////////////////////////////////////////////////

    nouvel essai à 115200 bauds

    Arduino : 1.8.10 (Linux), Carte : “ESP32 Wrover Module, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), QIO, 80MHz, 115200, None”

    Le croquis utilise 770410 octets (58%) de l’espace de stockage de programmes. Le maximum est de 1310720 octets.
    Les variables globales utilisent 48712 octets (14%) de mémoire dynamique, ce qui laisse 278968 octets pour les variables locales. Le maximum est de 327680 octets.
    esptool.py v2.6
    Serial port /dev/ttyUSB0
    Connecting…….
    Chip is ESP32D0WDQ5 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    MAC: 24:6f:28:46:ea:bc
    Uploading stub…
    Running stub…
    Stub running…
    Configuring flash size…
    Auto-detected Flash size: 4MB
    Compressed 8192 bytes to 47…

    Writing at 0x0000e000… (100 %)
    Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 4165.0 kbit/s)…
    Hash of data verified.
    Compressed 17392 bytes to 11186…

    Writing at 0x00001000… (100 %)
    Wrote 17392 bytes (11186 compressed) at 0x00001000 in 1.0 seconds (effective 140.6 kbit/s)…
    Hash of data verified.
    Compressed 770528 bytes to 443383…

    Writing at 0x00010000… (3 %)
    Writing at 0x00014000… (7 %)
    Writing at 0x00018000… (10 %)
    Writing at 0x0001c000… (14 %)
    A fatal error occurred: Failed to write compressed data to flash after seq 3 (result was C100)
    A fatal error occurred: Failed to write compressed data to flash after seq 3 (result was C100)

    Ce rapport pourrait être plus détaillé avec
    l’option “Afficher les résultats détaillés de la compilation”
    activée dans Fichier -> Préférences.

    ////////////////////////////////////////////////////////////
    reset bouton
    ////////////////////////////////////////////////////////////

    nouvel essai à 115200 bauds

    Arduino : 1.8.10 (Linux), Carte : “ESP32 Wrover Module, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), QIO, 80MHz, 115200, None”

    Le croquis utilise 770410 octets (58%) de l’espace de stockage de programmes. Le maximum est de 1310720 octets.
    Les variables globales utilisent 48712 octets (14%) de mémoire dynamique, ce qui laisse 278968 octets pour les variables locales. Le maximum est de 327680 octets.
    esptool.py v2.6
    Serial port /dev/ttyUSB0
    Connecting….
    Chip is ESP32D0WDQ5 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    MAC: 24:6f:28:46:ea:bc
    Uploading stub…
    Running stub…
    Stub running…
    Configuring flash size…
    Auto-detected Flash size: 4MB
    Compressed 8192 bytes to 47…

    Writing at 0x0000e000… (100 %)
    Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 4085.8 kbit/s)…
    Hash of data verified.
    Compressed 17392 bytes to 11186…

    Writing at 0x00001000… (100 %)
    Wrote 17392 bytes (11186 compressed) at 0x00001000 in 1.0 seconds (effective 140.6 kbit/s)…
    Hash of data verified.
    Compressed 770528 bytes to 443383…

    Writing at 0x00010000… (3 %)
    Writing at 0x00014000… (7 %)
    Writing at 0x00018000… (10 %)Traceback (most recent call last):
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 2959, in
    _main()
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 2952, in _main
    main()
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 2698, in main
    operation_func(esp, args)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 2158, in write_flash
    esp.flash_defl_block(block, seq, timeout=DEFAULT_TIMEOUT * ratio * 2)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 104, in inner
    return func(*args, **kwargs)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 632, in flash_defl_block
    Une erreur est survenue lors du transfert du croquis
    self.ESP_FLASH_DEFL_DATA, struct.pack(‘<IIII’, len(data), seq, 0, 0) + data, self.checksum(data), timeout=timeout)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 354, in check_command
    val, data = self.command(op, data, chk, timeout=timeout)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 322, in command
    self.write(pkt)
    File “/home/jfj/.arduino15/packages/esp32/tools/esptool_py/2.6.1/esptool.py”, line 285, in write
    self._port.write(buf)
    File “/home/jfj/.local/lib/python2.7/site-packages/serial/serialposix.py”, line 579, in write
    raise writeTimeoutError
    serial.serialutil.SerialTimeoutException: Write timeout

    Ce rapport pourrait être plus détaillé avec
    l’option “Afficher les résultats détaillés de la compilation”
    activée dans Fichier -> Préférences.

    Avez vous une idée de la cause de ces problemes ?
    Merci d’avance pour toute aide

  32. Bonjour,
    merci pour le tutoriel mais en essayant de compiler le code j’ai l’erreur suivante:
    Arduino : 1.8.10 (Windows 7), Carte : “ESP32 Wrover Module, Huge APP (3MB No OTA/1MB SPIFFS), QIO, 80MHz, 921600, Verbose”

    Plusieurs bibliothèque trouvées pour “WiFi.h”
    sketch_oct19a:30:20: error: dl_lib.h: No such file or directory

    compilation terminated.

    Utilisé : C:\Users\Pauline\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
    Non utilisé : C:\Program
    exit status 1
    dl_lib.h: No such file or directory

    Ce rapport pourrait être plus détaillé avec
    l’option “Afficher les résultats détaillés de la compilation”
    activée dans Fichier -> Préférences.

    Pourriez vous me dire comment y remédier?
    Par avance merci

  33. Bonjour,

    je lui vois de suite la fonctionnalité attendue de surveillance dans le jardin alimenté par du 18650 qui se recharge par petit panneau solaire.
    Et qui :
    – envoi un message MQTT pour le mouvement détecté afin d’en enregistrer le jour et l’heure
    – prend uniquement les photos alors chargées sur carte MicroSD (quelle taille microSD Max est supporté par cette carte, à vérifier) suite au détecteur de mouvements
    – la copie du contenu de la microSD pouvant être soit copié en y connectant une cable USB soit par wifi alors uniquement activé sur une tranche horaire prédéfinie (min-max)

  34. Très sympa comme tuto ! Pouvez vous nous dire ou vous l’avez acheté ? J’ai essayé avec celui de l’article de chez Ali mais je n’ai jamais réussi à aller au bout du téléversement. J’ai cru comprendre que le FTDI était source de problème, espressif conseille un CP2102. Bon ça n’a toujours pas résolu mon problème du coup j’en attend un autre d’une autre marque pour voir .
    Pareil pour moi en projet de me fabriquer mon visiophone de portail ^^.

  35. Bonjour et merci pour cet article intéressant.
    Je pense essayer cet ESP32-CAM. Quelle solution d’alimentation simple me conseilleriez-vous pour la poser dans une pièce de la maison (avec et/ou sans prise électrique…) ?
    Merci !

  36. Bonjour,
    quel est la taille maximale supportée pour la carte microSD sur cette carte ?
    Je n’ai pas trouvé l’info ici ni sur les specs du site de la marque du produit.
    D’avance merci de votre réponse.
    Bien à vous.

  37. Et voilà cette fois elle est vraiment active avec Jeedom et un bouton Click Xiaomi. Un coup de sonnette et je reçois un sms et un mail avec 2 photos du gêneur.
    Dommage que lorsque cette miniature est connectée sur Jeedom, on ne puisse plus la connecter directement pour modifier le sens de l’image.

    • Je bosse sur un firmware plus complet avec une interface web pour gérer les paramètres. Encore quelques jours de patience…

  38. Très bel article bien complet !
    “Pour une raison qui m’échappe encore, le plugin RTSP refuse obstinément d’accepter le protocole HTTP.”
    J’ai développé le plugin RTSP, peux-tu m’en dire plus sur le soucis que tu as rencontré ?
    Merci et à bientôt !

    • Bonjour et merci beaucoup de prendre contact directement avec moi, c’est un vrai chance ! Et bien lorsque je sélectionne HTTP comme protocole, les paramètres ne sont pas enregistrés par le plugin au moment de la sauvegarde et les champs sont ré-initialisés. Si le laisse RTSP, les paramètres sont bien enregistrés mais aucun flux n’est récupéré (ce qui semble logique). Je n’ai pas été beaucoup plus loin vu comme je voulais tester sur tous les serveurs domotiques. Je ne suis pas chez moi ce week-end mais on pourrait échanger plus sur le sujet courant de semaine prochaine. Bon week end

  39. sympa cette article, il me manquait une camera à mon portail, mais je ne voulais pas une grosse camera.. cela sera l’occasion de réaliser une petit camera de rue discrète qui s’intégrera a coté du boitier RFID.

    • Merci beaucoup. Oui franchement j’ai été vraiment très agréablement surpris. Le framework ESP-IDF a vraiment fait un bon en avant. Même plus besoin d’utiliser les librairies Arduino. Bon, c’est vrai qu’on perd l’aspect cross-platform mais si on ne développe que des projets à base d’ESP32 / ESP8266, tout est là. Je termine de faire le tour du framework et de l’API caméra pour rédiger quelques articles sur le sujet. Bon week end.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Calculateurs
×
Calculateur loi d'Ohm
Tension (U) - en Volt
Courant (I) - en Ampère
Résistance (R) - en Ohms
Puissance (P) - en Watts

Ce calculateur permet de calculer les relations entre le courant, la tension, la résistance et la puissance dans les circuits résistifs.

Saisir au moins deux valeurs puis cliquer sur calculer pour calculer les valeurs restantes. Réinitialisez après chaque calcul.

Rappel sur la Loi d'Ohm
La loi d'Ohm explique la relation entre la tension, le courant et la résistance en déclarant que le courant traversant un conducteur entre deux points est directement proportionnel à la différence de potentiel entre les deux points.
La loi d'Ohm s'écrit U = IR, où U est la différence de tension, I est le courant en ampère et R est la résistance en Ohms (symbole Ω).
Loi d'Ohm (U=RI)
×
Déchiffrer le code couleur d'une résistance à 4 bandes
Bande 1 Bande 2 Multiplicateur Tolérance
   

Résistance:  

1 000 Ω ±5%

Comment déchiffrer le code couleur d'une résistance à 4 anneaux
Formule : ab*cΩ ±d%
Les deux premières bandes (a, b) permettent de déterminer le chiffre significatif. La première bande correspond au chiffre de la dizaine, le second anneau le chiffre de l'unité. Par exemple Brun(1), Noir (0) donne le nombre 10.
La troisième bande (c) est un coefficient multiplicateur. Par exemple, l'anneau rouge est un coefficient multiplicateur de 100, ce qui donne 10 X 100 = 1000Ω.
Le quatrième anneau (d) indique la tolérance de la valeur nominale de la résistance. Par exemple l'anneau Or correspond à ±5%. Donc le fabricant de la résistance s'engage à ce que sa valeur soit comprise entre 950 Ω et 1050 Ω.
Déchiffrer code couleur 4 bandes
×
Déchiffrer le code couleur d'une résistance à 5 bandes
Bande 1 Bande 2 Bande 3 Multiplicateur Tolérance

Résistance:  

1 000 Ω ±5%

Comment déchiffrer le code couleur d'une résistance à 5 anneaux
Formule : abc*dΩ ±e%
Les trois premières bandes permettent de déterminer le chiffre significatif. La première bande correspond au chiffre de la dizaine, le second anneau le chiffre de l'unité. Par exemple Brun(1), Noir (0), Noir (0) donne le nombre 100
La quatrième bande est un coefficient multiplicateur. Par exemple, l'anneau brun correspond au coefficient multiplicateur 10, ce qui donne 100 X 10 = 1000Ω.
Le cinquième anneau indique la tolérance de la valeur nominale de la résistance. Par exemple l'anneau Or correspond à ±5%. Donc le fabricant de la résistance s'engage à ce que la valeur de la résistance soit comprise entre 950 Ω et 1050 Ω.
Déchiffrer code couleur 5 bandes
×
Calculateur de résistance série pour une ou plusieurs LED
Tension d'alimentation en Volt
Tension directe en Volt
Courant en mA
Résistance calculée en Ω
Puissance estimée en W

Ce calculateur permet de déterminer la résistance requise pour piloter une ou plusieurs LED connectées en série à partir d'une source de tension à un niveau de courant spécifié.

Remarque. Il est préférable d'alimenter le circuit avec une puissance nominale comprise entre 2 et 10 fois la valeur calculée afin d'éviter la surchauffe
Couleur Longueur d'onde (nm) Tension (V) pour LED ⌀3mm Tension(V) pour LED ⌀5mm
Rouge 625-630  1,9-2,1 2,1-2,2
Bleu 460-470 3,0-3,2 3,2-3,4
Vert 520-525 2,0-2,2 2,0-2,2
Jaune 585-595 2,0-2,2 3,0-3,2
Blanc 460-470 3,0-3,2 1,9-2,1
Résistance en série pour une ou plusieurs LED
×
Calculateur durée de vie d'une batterie
Capacité de la batterie
Consommation de l'appareil ou objet connecté

Ce calculateur estime la durée de vie d'une batterie, en fonction de sa capacité nominale et du courant ou de la puissance qu'une charge en tire.

La durée de vie de la batterie est une estimation idéalisée. La durée de vie réelle peut varier en fonction de l'état de la batterie, de son âge, de la température, du taux de décharge et d'autres facteurs. C'est le mieux que vous pouvez espérer obtenir.

Autonomie de la batterie = capacité de la batterie en mAh / courant de charge en mA

Durée de vie batterie
Publicité
À lire aussi
Composants
Sur le Forum
Domotique et objets connectés à faire soi-même
Domotique et objets connectés à faire soi-même
Vous avez aimé ce tutoriel

Ne manquez plus les prochains projets

Recevez chaque semaine le récapitulatif des tutoriels et projets.

Vous pouvez vous désabonner à tout moment.