ARDUINO
LA CARTE ESP32-CAM

Introduction

L'ESP32-CAM est une carte de développement dotée de capacités Wi-Fi et Bluetooth, comprenant une petite caméra, un lecteur de carte micro SD, un flash.

Quelques caractéristiques

La carte ESP32-CAM possède :

Cette carte ESP32-CAM peut se programmer via :

Alimentation de la carte

Cette carte s'alimente en 5 V et peut consommer jusqu'à 2 A.

Mise en route

Configuration de l'EDI

Il s'agit d'ajouter le module adéquat.

  1. Ouvrir l’EDI Arduino, aller dans Fichier / Préférences.
  2. Dans URL de gestionnaire de cartes supplémentaires, entrer :
         https://dl.espressif.com/dl/package_esp32_index.json
  3. Cliquer sur OK.
  4. Aller ensuite dans Outils / Type de carte / Gestionnaire de carte.
  5. Installer esp32.
  6. Dans le menu Outils, sélectionner la carte Al Thinker ESP32-CAM, penser également à vérifier le port.

Repérage des connecteurs

Les repères des connecteurs sont indiqués sur le dessin ci-dessous.

Complément

Modes de fonctionnement

Certains adaptateurs ne requièrent pas de démarche particulière. On branche, on téléverse, on teste. D'autres adaptateurs nécessitent de suivre une procédure. La carte branchée sur son adaptateur fonctionne alors selon deux modes différents :

Démarrer l’ESP32-CAM en mode Transfert

Passer au mode normal d’exécution de programme

Premiers pas

Clignotement d'une DEL

La carte comporte une DEL rouge associée à la sortie 33. Pour la faire clignoter :

void setup() {
  pinMode(33, OUTPUT);
}
void loop() {
  digitalWrite(33, HIGH);
  delay(1500);
  digitalWrite(33, LOW);
  delay(500);
}

Pour que clignote la DEL servant de flash :

void setup() {
  pinMode(4, OUTPUT);
}
void loop() {
  digitalWrite(4, HIGH);
  delay(1500);
  digitalWrite(4, LOW);
  delay(500);
}

Test de la caméra

Il s'effectue avec l'exemple proposé par l'EDI Arduino :

  1. Récupérer cet exemple :
  2. Commenter la ligne 10, décommenter la ligne 14, compléter les lignes 18 et 19.
  3. Transférer le programme sur la carte.
  4. Lire l'adresse IP du serveur web (exemple : 192.168.0.111) à l'aide du moniteur série.
  5. Taper l'adresse IP du serveur web dans la barre d'adresse d'un navigateur pour obtenir le résultat :

Notes :

Exemple de serveur Web et d'IHM

Programme

Ici, la carte se comporte en point d'accès Wi-Fi, au lieu de se connecter à un point d'accès Wi-Fi comme précédemment. Particularités de cette solution :

#include "esp_camera.h"
#include <WiFi.h>

// Paramètres du point d'accès WiFi auquel se connecter
const char* ssid = "camera";
const char* password = "";  // Mot de passe avec soit 0 caractères soit 8 ou plus

WiFiServer server(80);
#define B_FLASH 4  // Numéro de la broche pour le flash

void startWifi() {
  WiFi.softAP(ssid,password);
  Serial.println("\nPoint d'accès WiFi démarré");
  Serial.print("Adresse IP du point d'accès WiFi : ");
  Serial.println(WiFi.softAPIP());
}

void startCamera() {
  // Configuration de la caméra
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = 5;
  config.pin_d1 = 18;
  config.pin_d2 = 19;
  config.pin_d3 = 21;
  config.pin_d4 = 36;
  config.pin_d5 = 39;
  config.pin_d6 = 34;
  config.pin_d7 = 35;
  config.pin_xclk = 0;
  config.pin_pclk = 22;
  config.pin_vsync = 25;
  config.pin_href = 23;
  config.pin_sscb_sda = 26;
  config.pin_sscb_scl = 27;
  config.pin_pwdn = 32;
  config.pin_reset = -1;
  config.xclk_freq_hz = 20000000;  // Augmenter la fréquence de l'horloge XCLK
  config.pixel_format = PIXFORMAT_JPEG;
  config.frame_size = FRAMESIZE_QVGA;  // Réduire la taille de l'image
  config.jpeg_quality = 15;  // Réduire la qualité pour une meilleure vitesse
  config.fb_count = 2;  // Augmenter le nombre de tampons d'image
  // Initialisation
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.print("Erreur caméra : 0x");
    Serial.print(err, HEX);
  }
  else { Serial.println("Caméra en marche"); }
}

void setup() {
  Serial.begin(9600);
  pinMode(B_FLASH, OUTPUT);  // Initialiser la broche du flash
  digitalWrite(B_FLASH, LOW);  // Éteindre le flash au démarrage
  startWifi();
  startCamera();
  server.begin();
  Serial.println("Serveur Web démarré");
}

void loop() {

  // Vérifier si le client est connecté
  WiFiClient client = server.available();
  if (!client) { return; }
  Serial.println("Client connecté");
  Serial.println();
  
  // Attendre que le client envoie sa requête
  while (!client.available()) { delay(100); }
  
  // Lire la première ligne de la requête
  String request = client.readStringUntil('\n');
  Serial.println("Requête reçue :");
  Serial.println(request);
  Serial.println();
  while (client.available()!=0) { client.read(); } // vider la mémoire tampon
  
  // Traiter la requête
  if (request.indexOf("flash_on") >= 0) {
    // Allumer le flash
    digitalWrite(B_FLASH, HIGH);
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/plain; charset=UTF-8");
    client.println();
    client.println("Flash allumé");
    Serial.println("Flash allumé");
    Serial.println();
  }
  else if (request.indexOf("flash_off") >= 0) {
    // Éteindre le flash
    digitalWrite(B_FLASH, LOW);
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/plain; charset=UTF-8");
    client.println();
    client.println("Flash éteint");
    Serial.println("Flash éteint");
    Serial.println();
  }
  else if (request.indexOf("capture.jpg") >= 0) {
    // Capturer et envoyer l’image JPEG
    camera_fb_t * fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Erreur capture image");
      client.println("HTTP/1.1 500 Internal Server Error");
      client.println("Content-Type: text/plain");
      client.println();
      client.println("Erreur capture");
      return;
    }
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: image/jpeg");
    client.println("Cache-Control: no-cache");
    client.println();
    client.write(fb->buf, fb->len);
    esp_camera_fb_return(fb);
    Serial.println("Image envoyée");
    Serial.println();
  }
  else {
    // Envoyer la page HTML
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println();
    client.println("<!DOCTYPE html><html><head><meta charset=\"utf-8\"><script>");
    client.println("async function allumer() {");
    client.println("let response = await fetch('/flash_on');");
    client.println("let text = await response.text();");
    client.println("document.getElementById(\"etat_flash\").innerHTML=text;");
    client.println("}");
    client.println("async function eteindre() {");
    client.println("let response = await fetch('/flash_off');");
    client.println("let text = await response.text();");
    client.println("document.getElementById(\"etat_flash\").innerHTML=text;");
    client.println("}");
    client.println("var nb=0;");
    client.println("recharge=function() {");
    client.println("nb++;");
    client.println("document.images[0].src=\"capture.jpg?nb=\"+nb;");
    client.println("};");
    client.println("window.onload=function() { setInterval(recharge,1000); };");
    client.println("</script><style>");
    client.println("body { text-align: center; }");
    client.println("</style></head><body>");
    client.println("<h1>Caméra ESP32</h1>");
    client.println("<img src=\"/capture.jpg\"><br><br>");
    client.println("<input type= \"button\" value=\"Allumer le flash\" onclick=\"allumer();\">");
    client.println("<input type= \"button\" value=\"Eteindre le flash\" onclick=\"eteindre();\">");
    client.println("<p id=\"etat_flash\">Flash éteint</p>");
    client.println("</body></html>\r\n");
    Serial.println("Page HTML envoyée.");
    Serial.println();
  }
  client.stop();
} 

Rendu

L'affichage s'obtient comme précédemment à l'aide d'un navigateur.

L'expérience montre que l'alimentation via le port USB, limitée à 500 mA, ne suffit pas. Une alimentation extérieure plus puissante s'impose.

Retrouver l'adresse IP

Sous Linux, l'adresse IP de l'ESP32-CAM se retrouve à l'aide de deux commandes :

Exemple :

Flux vidéo avec la caméra

Documentation

Exemples de projets