ESP32-CAM

L’ESP32-CAM est un module caméra très compact équipé de la puce ESP32-S, vendu aux alentours de 10 Euros. Outre la caméra OV2640 et plusieurs GPIO pour connecter des périphériques, il dispose également d’un emplacement pour carte microSD, utile pour stocker des images prises avec la caméra ou des fichiers à servir aux clients.

Le module peut fonctionner de manière autonome comme le plus petit système, avec une taille de seulement 27*40.5*4.5mm, et un courant de veille profonde aussi bas que 6mA.

 L’ESP32-CAM peut être largement utilisé dans diverses applications IoT, adapté aux appareils domestiques intelligents, au contrôle sans fil industriel, à la surveillance sans fil, à l’identification sans fil par QR code, au positionnement sans fil et à d’autres applications IoT. C’est une solution idéale pour les applications IoT.

ESP32-CAM Brochage

L’image suivante montre le brochage de l’ESP32-CAM (module AI-Thinker).

  • Il y a trois broches GND et trois broches d’alimentation : 3.3V, 5V et soit 3.3V, soit 5V.
  • GPIO 1 et GPIO 3 sont les broches série. Vous avez besoin de ces broches pour téléverser du code sur votre carte.
  • De plus, GPIO 0 joue également un rôle important, car il détermine si l’ESP32 est en mode flash ou non. Lorsque GPIO 0 est connecté à GND, l’ESP32 est en mode flash.

Les broches suivantes sont connectées en interne au lecteur de carte microSD :

  • GPIO 14 : CLK
  • GPIO 15 : CMD
  • GPIO 2 : Data 0
  • GPIO 4 : Data 1 (également connecté à la LED intégrée)
  • GPIO 12 : Data 2
  • GPIO 13 : Data 3

Remarque

  • Veuillez vous assurer que l’alimentation en entrée du module est d’au moins 5V 2A, sinon l’image pourrait présenter des lignes d’eau.
  • La broche GPIO32 de l’ESP32 contrôle l’alimentation de la caméra. Lorsque la caméra est en fonctionnement, veuillez tirer GPIO32 vers le bas.
  • Étant donné que GPIO0 est connecté à l’horloge XCLK de la caméra, veuillez laisser GPIO0 en l’air lors de son utilisation, et ne pas le connecter à un niveau haut ou bas.
  • Le firmware par défaut est déjà inclus en usine, et aucun téléchargement supplémentaire n’est fourni. Veuillez faire attention si vous avez besoin de reprogrammer un autre firmware.

Pour IDE PlatformIO dans VsCode, voire https://entraide-francophone.org/esp32-ide-vscode/

Pour IDE arduino, voire https://entraide-francophone.org/esp32-cam-ide-arduino/

Pour la phase de programmation, les connexions étaient les suivantes:

  • Sortie 5 V du convertisseur USB-série:  Entrée 5 V de l’ESP32-CAM
  • Broche GND du convertisseur USB-série: Broche GND de l’ESP32-CAM
  • Broche TXD du convertisseur USB-série: Broche UDR de l’ESP32-CAM
  • Broche RXD du convertisseur USB-série: Broche UDT de l’ESP32-CAM
  • Broche IO0 branchée à GND

Mise en place d’un model de code dans votre IDE

Ide arduino : (en cour de réalisation)

ide VsCode voire :

https://entraide-francophone.org/esp32-cam-platformio-ide-pour-vscode

Téléversez le code sur l’ESP32-CAM

  1. Attendez que le téléversement soit terminé
  2. Déconnecter la broche IO0 de la carte ESP32-CAM à la broche GND de la carte ESP32-CAM
  1. Ouvrir le moniteur série
  2. Appuyer sur le bouton RESET de la carte ESP32-CAM
  3. On observe le moniteur série pour voir l’adresse IP de l’ESP32-CAM.

Ouvrez un navigateur web sur votre ordinateur et entrez l’adresse IP de l’ESP32-CAM dans la barre d’adresse.

La page web affichée par l’ESP32-CAM devrait contenir un flux vidéo en direct provenant de la caméra OV2640.

Exemple de code (serveur de streaming simple)

#include "esp_camera.h"
#include <WiFi.h>
#include "esp_timer.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 "esp_http_server.h"

//Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

#define PART_BOUNDARY "123456789000000000000987654321"

// This project was tested with the AI Thinker Model, M5STACK PSRAM Model and M5STACK WITHOUT PSRAM
#define CAMERA_MODEL_AI_THINKER

#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
  #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

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";

httpd_handle_t stream_httpd = NULL;

static 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 = 0;
  uint8_t * _jpg_buf = NULL;
  char * part_buf[64];

  res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  if(res != ESP_OK){
    return res;
  }

  while(true){
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Camera capture failed");
      res = ESP_FAIL;
    } else {
      if(fb->width > 400){
        if(fb->format != PIXFORMAT_JPEG){
          bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
          esp_camera_fb_return(fb);
          fb = NULL;
          if(!jpeg_converted){
            Serial.println("JPEG compression failed");
            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){
      esp_camera_fb_return(fb);
      fb = NULL;
      _jpg_buf = NULL;
    } else if(_jpg_buf){
      free(_jpg_buf);
      _jpg_buf = NULL;
    }
    if(res != ESP_OK){
      break;
    }
    //Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
  }
  return res;
}

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

  httpd_uri_t index_uri = {
    .uri       = "/",
    .method    = HTTP_GET,
    .handler   = stream_handler,
    .user_ctx  = NULL
  };
  
  //Serial.printf("Starting web server on port: '%d'\n", config.server_port);
  if (httpd_start(&stream_httpd, &config) == ESP_OK) {
    httpd_register_uri_handler(stream_httpd, &index_uri);
  }
}

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
 
  Serial.begin(115200);
  Serial.setDebugOutput(false);
  
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; 
  
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  
  // Camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
  // Wi-Fi connection
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  Serial.print("Camera Stream Ready! Go to: http://");
  Serial.print(WiFi.localIP());
  
  // Start streaming web server
  startCameraServer();
}

void loop() {
  delay(1);
}

Modifier les lignes suivante

const char* ssid = "REMPLACE_par_ton_SSID";
const char* password = "REMPLACE_par_ta_Clée_Wifi";

Téléverser le code à l’ESP.

ouvre ton terminal, l’ESP donne son adresse IP au démarrage.

Redémarre l’ESP puis connecte ton navigateur internet à son adresse IP exemple http://192.168.xxx.xxx

Laisser un commentaire


Entraide francophone
Résumé de la politique de confidentialité

Ce site utilise des cookies afin que nous puissions vous fournir la meilleure expérience utilisateur possible. Les informations sur les cookies sont stockées dans votre navigateur et remplissent des fonctions telles que vous reconnaître lorsque vous revenez sur notre site Web et aider notre équipe à comprendre les sections du site que vous trouvez les plus intéressantes et utiles.