ESP32-CAM HTTP POST Photos sur serveur (PHP et Arduino IDE)

ESP32-CAM HTTP POST Photos sur serveur (PHP et Arduino IDE)

Dans ce guide, vous apprendrez à faire des requêtes HTTP POST à ​​l’aide de la carte ESP32-CAM avec Arduino IDE pour envoyer des photos à un serveur. Nous montrerons comment publier une image JPG sur un serveur local (serveur Raspberry Pi LAMP) ou sur un serveur cloud (auquel vous pouvez accéder de n’importe où). Pour enregistrer les images sur le serveur, nous utiliserons PHP.

Carte de caméra ESP32-CAM Envoyer des images de requête HTTP Post à un serveur local ou cloud à l'aide d'Arduino IDE

Pour construire ce projet, vous devez suivre les étapes suivantes. Suivez les instructions du serveur LAMP ou du serveur d’hébergement selon si vous souhaitez accéder aux photos localement ou depuis n’importe où.

  1. Hébergement de votre application PHP
    1. Serveur Raspberry Pi LAMP (accès local)
    2. Serveur d’hébergement (accès de n’importe où)
  2. Scripts PHP pour enregistrer et afficher des photos sur le serveur
    1. Serveur Raspberry Pi LAMP (accès local)
    2. Serveur d’hébergement (accès de n’importe où)
  3. Programmer l’ESP32-CAM avec Arduino IDE
  4. Essais et démonstration finale

1. Hébergement de votre application PHP

Le but de ce projet est d’avoir un serveur local ou cloud pour stocker et accéder à vos photos ESP32-CAM.

1. Serveur local Raspberry Pi:

Avec un serveur Raspberry Pi LAMP, vous pouvez accéder à vos images localement (comme illustré ci-dessous).

Carte de caméra ESP32-CAM Envoyer une image photo au serveur Raspberry Pi LAMP Script PHP Arduino

Configurer le serveur local RPi LAMP »

2. Serveur Cloud (solution d’hébergement Bluehost)

Vous pouvez également visualiser les photos ESP32-CAM de n’importe où dans le monde en accédant à votre propre serveur + domaine. Voici un aperçu de haut niveau de son fonctionnement :

Carte de caméra ESP32-CAM Envoyer une image photo au serveur Cloud Script PHP Arduino
  • Bluehost (convivial avec cPanel) : nom de domaine gratuit lors de votre inscription au forfait 3 ans. Je recommande de choisir l’option de sites Web illimités ; Notez que tout service d’hébergement qui propose PHP fonctionnera avec ce tutoriel. Si vous n’avez pas de compte d’hébergement, je vous recommande de vous inscrire à Bluehost.

Obtenez un hébergement et un nom de domaine avec Bluehost »

Lors de l’achat d’un compte d’hébergement, vous devrez également acheter un nom de domaine. C’est ce qui rend ce projet intéressant : vous pourrez aller sur votre nom de domaine (http://example.com) et voir vos photos ESP32-CAM. Si vous aimez nos projets, vous pourriez envisager de vous inscrire à Bluehost, car vous soutiendrez notre travail.

2.1. Préparer votre .php Fichier et téléchargements Dossier (Raspberry Pi LAMP Server)

Cette section prépare votre .php fichier et téléchargements dossier pour votre serveur Raspberry Pi LAMP. Si vous utilisez votre propre serveur + nom de domaine, passez à la section suivante.

Ayant un Raspberry Pi exécutant Apache et PHP, dans la fenêtre du terminal de la carte Raspberry Pi, accédez au /var/www/html/ annuaire:

[email protected]:~ $ cd /var/www/html/

Créez un nouveau dossier appelé téléchargements:

[email protected]:/var/www/html $ mkdir uploads
[email protected]:/var/www/html $ ls
uploads

En ce moment, /var/www/html appartient à root, utilisez les commandes suivantes pour passer à l’utilisateur pi et donnez-lui toutes les autorisations afin que vous puissiez enregistrer des photos à l’aide d’un script PHP ultérieurement.

sudo chown -R pi:pi /var/www/html
chmod -R 777 /var/www/html/

Enfin, créez un nouveau upload.php déposer:

[email protected]:/var/www/html $ nano upload.php

Ce script PHP est chargé de recevoir les images entrantes de l’ESP32-CAM, de renommer les images avec un horodatage et de les stocker dans le téléchargements dossier. Modifiez le fichier nouvellement créé (upload.php) et copiez l’extrait suivant :

<?php
// Rui Santos
// Complete project details at https://Raspberryme.com/esp32-cam-post-image-photo-server/
// Code Based on this example: w3schools.com/php/php_file_upload.asp

$target_dir = "uploads/";
$datum = mktime(date('H')+0, date('i'), date('s'), date('m'), date('d'), date('y'));
$target_file = $target_dir . date('Y.m.d_H:i:s_', $datum) . basename($_FILES["imageFile"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
  $check = getimagesize($_FILES["imageFile"]["tmp_name"]);
  if($check !== false) {
    echo "File is an image - " . $check["mime"] . ".";
    $uploadOk = 1;
  }
  else {
    echo "File is not an image.";
    $uploadOk = 0;
  }
}

// Check if file already exists
if (file_exists($target_file)) {
  echo "Sorry, file already exists.";
  $uploadOk = 0;
}

// Check file size
if ($_FILES["imageFile"]["size"] > 500000) {
  echo "Sorry, your file is too large.";
  $uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
  echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
  $uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
  echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
}
else {
  if (move_uploaded_file($_FILES["imageFile"]["tmp_name"], $target_file)) {
    echo "The file ". basename( $_FILES["imageFile"]["name"]). " has been uploaded.";
  }
  else {
    echo "Sorry, there was an error uploading your file.";
  }
}
?>

Afficher le code brut

Enregistrez votre fichier et quittez (Ctrl+X, Y et touche Entrée) :

2.2. Préparer votre .php Fichiers et téléchargements Dossier (Service d’hébergement)

Si vous préférez exécuter votre serveur à distance et accéder aux photos de n’importe où, vous avez besoin d’un compte d’hébergement. Après avoir créé un compte d’hébergement et configuré un nom de domaine, vous pouvez vous connecter à votre cPanel ou à un tableau de bord similaire. Après cela, ouvrez le gestionnaire de fichiers.

Ouvrez le « Avancéeonglet  » et sélectionnez « Gestionnaire de fichiers » :

Bluehost ouvre les fichiers avancés et du gestionnaire de fichiers pour créer le fichier upload.php et le dossier de téléchargement

Ensuite, sélectionnez le public_html option. Appuyez sur la « + Fichier” pour créer un nouveau upload.php fichier et un nouveau galerie.php déposer. Ensuite, cliquez sur le « +Dossier” pour créer le Téléchargements dossier.

Carte de caméra ESP32-CAM CPanel Créer un nouveau dossier de téléchargement de fichiers PHP de téléchargement

Une fois les trois éléments créés, modifiez le upload.php déposer:

nouveaux fichiers créés PHP cPanel et dossier de téléchargement

Ce script PHP est chargé de recevoir les images entrantes de l’ESP32-CAM, de renommer les images avec un horodatage et de les stocker dans le téléchargements dossier. Modifiez le fichier nouvellement créé (upload.php) et copiez l’extrait ci-dessous. Enregistrez votre fichier et quittez.

<?php
// Rui Santos
// Complete project details at https://Raspberryme.com/esp32-cam-post-image-photo-server/
// Code Based on this example: w3schools.com/php/php_file_upload.asp

$target_dir = "uploads/";
$datum = mktime(date('H')+0, date('i'), date('s'), date('m'), date('d'), date('y'));
$target_file = $target_dir . date('Y.m.d_H:i:s_', $datum) . basename($_FILES["imageFile"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
  $check = getimagesize($_FILES["imageFile"]["tmp_name"]);
  if($check !== false) {
    echo "File is an image - " . $check["mime"] . ".";
    $uploadOk = 1;
  }
  else {
    echo "File is not an image.";
    $uploadOk = 0;
  }
}

// Check if file already exists
if (file_exists($target_file)) {
  echo "Sorry, file already exists.";
  $uploadOk = 0;
}

// Check file size
if ($_FILES["imageFile"]["size"] > 500000) {
  echo "Sorry, your file is too large.";
  $uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
  echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
  $uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
  echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
}
else {
  if (move_uploaded_file($_FILES["imageFile"]["tmp_name"], $target_file)) {
    echo "The file ". basename( $_FILES["imageFile"]["name"]). " has been uploaded.";
  }
  else {
    echo "Sorry, there was an error uploading your file.";
  }
}
?>

Afficher le code brut

3. ESP32-CAM HTTP Post Images/Photos sur le serveur

Maintenant que votre serveur est prêt (serveur Raspberry Pi LAMP ou serveur cloud), il est temps de préparer l’ESP32-CAM avec le code pour publier une nouvelle image sur votre serveur toutes les 30 secondes. Avant de poursuivre ce didacticiel, assurez-vous de remplir les conditions préalables suivantes.

Pièces requises

Pour suivre ce tutoriel, vous avez besoin des composants suivants :

Vous pouvez utiliser les liens précédents ou aller directement sur MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

1641479051 780 ESP32 CAM HTTP POST Photos sur serveur PHP et Arduino IDE

IDE Arduino

Nous allons programmer le ESP32-CAM en utilisant Arduino IDE, assurez-vous donc que le module complémentaire ESP32 est installé.

Vérifiez l’URL PHP

Vous devriez essayer d’ouvrir l’adresse IP locale du Raspberry Pi ou votre nom de domaine externe example.com, suivi de /upload.php qui devrait retourner :

Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.
ESP32-CAM Test de l'URL upload.php

Si vous voyez ce message enregistrer votre URL/nom de domaine et chemin, votre serveur devrait être prêt et vous pouvez continuer avec ce guide.

Code ESP32-CAM

L’esquisse suivante publie l’image sur un serveur à l’aide de HTTP POST. Copiez le code ci-dessous dans votre IDE Arduino.

/*
  Rui Santos
  Complete project details at https://Raspberryme.com/esp32-cam-post-image-photo-server/
  
  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 <Arduino.h>
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

String serverName = "192.168.1.XXX";   // REPLACE WITH YOUR Raspberry Pi IP ADDRESS
//String serverName = "example.com";   // OR REPLACE WITH YOUR DOMAIN NAME

String serverPath = "/upload.php";     // The default serverPath should be upload.php

const int serverPort = 80;

WiFiClient client;

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

const int timerInterval = 30000;    // time between each HTTP POST image
unsigned long previousMillis = 0;   // last time image was sent

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("ESP32-CAM IP Address: ");
  Serial.println(WiFi.localIP());

  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;
  config.pixel_format = PIXFORMAT_JPEG;

  // init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 10;  //0-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_CIF;
    config.jpeg_quality = 12;  //0-63 lower number means higher quality
    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);
    delay(1000);
    ESP.restart();
  }

  sendPhoto(); 
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= timerInterval) {
    sendPhoto();
    previousMillis = currentMillis;
  }
}

String sendPhoto() {
  String getAll;
  String getBody;

  camera_fb_t * fb = NULL;
  fb = esp_camera_fb_get();
  if(!fb) {
    Serial.println("Camera capture failed");
    delay(1000);
    ESP.restart();
  }
  
  Serial.println("Connecting to server: " + serverName);

  if (client.connect(serverName.c_str(), serverPort)) {
    Serial.println("Connection successful!");    
    String head = "--Raspberryme.comnContent-Disposition: form-data; name="imageFile"; filename="esp32-cam.jpg"rnContent-Type: image/jpegrnrn";
    String tail = "rn--Raspberryme.com--rn";

    uint32_t imageLen = fb->len;
    uint32_t extraLen = head.length() + tail.length();
    uint32_t totalLen = imageLen + extraLen;
  
    client.println("POST " + serverPath + " HTTP/1.1");
    client.println("Host: " + serverName);
    client.println("Content-Length: " + String(totalLen));
    client.println("Content-Type: multipart/form-data; boundary=Raspberryme.com");
    client.println();
    client.print(head);
  
    uint8_t *fbBuf = fb->buf;
    size_t fbLen = fb->len;
    for (size_t n=0; n<fbLen; n=n+1024) {
      if (n+1024 < fbLen) {
        client.write(fbBuf, 1024);
        fbBuf += 1024;
      }
      else if (fbLen%1024>0) {
        size_t remainder = fbLen%1024;
        client.write(fbBuf, remainder);
      }
    }   
    client.print(tail);
    
    esp_camera_fb_return(fb);
    
    int timoutTimer = 10000;
    long startTimer = millis();
    boolean state = false;
    
    while ((startTimer + timoutTimer) > millis()) {
      Serial.print(".");
      delay(100);      
      while (client.available()) {
        char c = client.read();
        if (c == 'n') {
          if (getAll.length()==0) { state=true; }
          getAll = "";
        }
        else if (c != 'r') { getAll += String(c); }
        if (state==true) { getBody += String(c); }
        startTimer = millis();
      }
      if (getBody.length()>0) { break; }
    }
    Serial.println();
    client.stop();
    Serial.println(getBody);
  }
  else {
    getBody = "Connection to " + serverName +  " failed.";
    Serial.println(getBody);
  }
  return getBody;
}

Afficher le code brut

Avant de télécharger le code, vous devez insérer vos identifiants réseau dans les variables suivantes :

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Assurez-vous de sélectionner le bon module de caméra. Dans ce cas, nous utilisons le modèle AI-THINKER. Si vous utilisez un autre modèle de caméra, vous pouvez lire ce guide Cartes caméra ESP32-CAM : affectation des broches et des GPIO.

Ajoutez votre adresse IP Raspberry Pi ou utilisez le nom de domaine du serveur :

String serverName = "192.168.1.XXX";   // REPLACE WITH YOUR Raspberry Pi IP ADDRESS
//String serverName = "example.com";   // OR REPLACE WITH YOUR DOMAIN NAME
String serverPath = "/upload.php";     // The default serverPath should be upload.php

Télécharger le code sur ESP32-CAM

Vous pouvez maintenant télécharger le code sur votre carte ESP32-CAM. Connectez la carte ESP32-CAM à votre ordinateur à l’aide d’un programmeur FTDI.

Suivez le schéma suivant :

Téléchargement de la carte de caméra Code ESP32-CAM nouveau code de téléchargement de croquis Programmeur FTDI

De nombreux programmeurs FTDI ont un cavalier qui vous permet de sélectionner 3,3 V ou 5 V. Assurez-vous que le cavalier est au bon endroit pour sélectionner 5V.

Important: GPIO 0 doit être connecté à GND afin que vous puissiez télécharger du code.

ESP32-CAM Programmeur FTDI
GND GND
5V VCC (5V)
U0R Émission
U0T Réception
GPIO 0 GND

Pour télécharger le code, suivez les étapes suivantes :

  1. Aller à Outils > Conseil et sélectionnez AI-penseur ESP32-CAM.
  2. Aller à Outils > Port et sélectionnez le port COM auquel l’ESP32 est connecté.
  3. Ensuite, cliquez sur le bouton de téléchargement pour télécharger le code.
  4. Lorsque vous commencez à voir ces points sur la fenêtre de débogage, comme indiqué ci-dessous, appuyez sur le bouton RST intégré de l’ESP32-CAM.
La carte de caméra ESP32-CAM télécharge un nouveau croquis Arduino IDE appuyez sur le bouton RESET

Après quelques secondes, le code devrait être téléchargé avec succès sur votre tableau.

Si vous rencontrez des problèmes pour télécharger le code, lisez notre guide de dépannage ESP32-CAM.

Comment fonctionne le code

Voici une explication rapide sur le fonctionnement du code :

  • Importe toutes les bibliothèques ;
  • Définit les variables nécessaires ;
  • Définit les broches de la caméra ;
  • Dans le mettre en place() vous établissez une connexion Wi-Fi et initialisez la caméra ESP32.
  • le boucler() a une minuterie qui appelle le envoyer une photo() fonction toutes les 30 secondes. Vous pouvez modifier ce délai dans le timerInterval variable.

le envoyer une photo() La fonction est la partie qui prend réellement une photo et l’envoie à votre serveur. Vous pouvez utiliser cette fonction dans d’autres de vos projets qui nécessitent de prendre et de publier une photo sur un serveur.

4. Tests et démonstration finale

Après avoir téléchargé le code sur votre carte, ouvrez le moniteur série Arduino IDE et vous devriez voir un message similaire s’imprimer toutes les 30 secondes :

The file esp32-cam.jpg has been uploaded.
Le fichier ESP32-CAM esp32-cam.jpg a été téléchargé Projet de test du moniteur série Arduino IDE

Si vous accédez à l’URL de votre serveur local http://Adresse-IP/uploads, ou à l’URL de votre serveur cloud http://example.com/uploads vous devriez avoir un dossier avec toutes vos photos stockées.

La carte de caméra ESP32-CAM télécharge les images de dossier stockées sur le serveur Démonstration

Vous pouvez cliquer sur chaque lien pour ouvrir une nouvelle page avec l’image complète :

ESP32-CAM Télécharger une photo ou une image sur le serveur PHP Arduino IDE

Conclusion

C’est ça! Maintenant, vous pouvez envoyer vos photos ESP32-CAM à n’importe quel serveur en utilisant HTTP POST. Modifiez ce projet pour l’adapter au mieux à vos besoins, par exemple prenez une photo et envoyez-la à un serveur lorsqu’un mouvement est détecté.

Autres tutoriels ESP32 qui pourraient vous intéresser :

En savoir plus sur l’ESP32-CAM :

Merci d’avoir lu.