Thejulfi

ESP32cam_videoMonitoring

Feb 16th, 2020
74
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*********
  2.   Julfi
  3.  
  4.   Ce code a été réalisé à partir de celui de Rui Santos.
  5.   Vous pouvez retrouver les détails du projet ici :
  6.  
  7.   Vous pouvez retrouver le copyright juste en dessous.
  8.   L'aide mémoire pour charger un programme dans l'ESP32cam
  9.   a été traduit en francais mais sinon cette partie reste
  10.   inchangé.
  11.  
  12.   You can find bellow the copyright text. The memo for upload
  13.   sketch into the ESP32cam has been translated in french but
  14.   this part is still unchanged.
  15.  
  16. *********/
  17.  
  18. /*********
  19.   Rui Santos
  20.   Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-display-web-server/
  21.  
  22.   IMPORTANT!!!
  23.    - Selectionné la carte "AI Thinker ESP32-CAM"
  24.    - GPIO 0 doit être connecté à la masse pour charger le programme
  25.    - Après avoir connecté le GPIO 0 à la masse veuillez appuyer sur le bouton reset pour passer la carte en mode "flashing"
  26.  
  27.  
  28.   The above copyright notice and this permission notice shall be included in all
  29.   copies or substantial portions of the Software.
  30. *********/
  31.  
  32. #include "WiFi.h"
  33. #include "esp_camera.h"
  34. #include "esp_timer.h"
  35. #include "img_converters.h"
  36. #include "Arduino.h"
  37. #include "soc/soc.h"
  38. #include "soc/rtc_cntl_reg.h"
  39. #include "driver/rtc_io.h"
  40. #include <ESPAsyncWebServer.h>
  41. #include <StringArray.h>
  42. #include <SPIFFS.h>
  43. #include <FS.h>
  44. #include <stdio.h>
  45. #include <time.h>
  46.  
  47. const char* NTP_SERVER = "ch.pool.ntp.org"; //adresse des serveurs NTP
  48. const char* TZ_INFO    = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";  // Changer votre fuseau horaire en allant sur (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)
  49.  
  50.  
  51. const char* ssid = "SSID";
  52. const char* password = "PASSWORD";
  53.  
  54. //Déclarations pour récupérer l'heure
  55. tm timeinfo;
  56. time_t now;
  57. long unsigned lastNTPtime;
  58. unsigned long lastEntryTime;
  59.  
  60. // Création d'un objet AsyncWebServer sur le port 80
  61. AsyncWebServer server(80);
  62.  
  63. boolean takeNewPhoto = false;
  64.  
  65. const int Photoresistance = 13;
  66. const int PIRsensor = 14;
  67.  
  68.  
  69. int numero_photo = 1;
  70. boolean goPhoto = false;
  71.  
  72. // OV2640 broches du module caméra (CAMERA_MODEL_AI_THINKER)
  73. #define PWDN_GPIO_NUM     32
  74. #define RESET_GPIO_NUM    -1
  75. #define XCLK_GPIO_NUM      0
  76. #define SIOD_GPIO_NUM     26
  77. #define SIOC_GPIO_NUM     27
  78. #define Y9_GPIO_NUM       35
  79. #define Y8_GPIO_NUM       34
  80. #define Y7_GPIO_NUM       39
  81. #define Y6_GPIO_NUM       36
  82. #define Y5_GPIO_NUM       21
  83. #define Y4_GPIO_NUM       19
  84. #define Y3_GPIO_NUM       18
  85. #define Y2_GPIO_NUM        5
  86. #define VSYNC_GPIO_NUM    25
  87. #define HREF_GPIO_NUM     23
  88. #define PCLK_GPIO_NUM     22
  89.  
  90. //Code de la page web
  91. const char index_html[] PROGMEM = R"rawliteral(
  92. <!DOCTYPE HTML><html>
  93. <head>
  94.  
  95.  <meta name="viewport" content="width=device-width, initial-scale=1">
  96.  <style>
  97.    body { text-align:center; }
  98.    .vert { margin-bottom: 10%; }
  99.    .hori{ margin-bottom: 0%; }
  100.  </style>
  101. </head>
  102. <body style="background-color:#1f1f1f;color:white;">
  103.   <div id="container" style="font-family: 'Source Sans Pro', sans-serif;">
  104.     <h2>Home - Video surveillance</h2>
  105.     <p>Les photos sont actualisees toute les 5 secondes.</p>
  106.     <p>
  107.      
  108.     </p>
  109.   </div>
  110.   <div style="display:flex;flex-direction: row;justify-content: center;">
  111.     <div><img src="saved-photo/photo1" id="photo1" width="100%"></div>
  112.     <div><img src="saved-photo/photo2" id="photo2" width="100%"></div>
  113.     <div><img src="saved-photo/photo3" id="photo3" width="100%"></div>
  114.   </div>
  115. </body>
  116. <script >
  117.   function refresh() {
  118.      var tmp = new Date();
  119.      var img1 = document.getElementById("photo1");
  120.      var img2 = document.getElementById("photo2");
  121.      var img3 = document.getElementById("photo3");
  122.      img1.src = img1.src + '?' + tmp.getTime();
  123.      img2.src = img2.src + '?' + tmp.getTime();
  124.      img3.src = img3.src + '?' + tmp.getTime();
  125.   }
  126.    
  127.   window.onload = function() {
  128.     setInterval(refresh,5000);
  129.    };
  130.   var deg = 0;
  131.   function capturePhoto() {
  132.     var xhr = new XMLHttpRequest();
  133.     xhr.open('GET', "/capture", true);
  134.     xhr.send();
  135.   }
  136.   function rotatePhoto() {
  137.     var img = document.getElementById("photo");
  138.     deg += 90;
  139.     if(isOdd(deg/90)){ document.getElementById("container").className = "vert"; }
  140.     else{ document.getElementById("container").className = "hori"; }
  141.     img.style.transform = "rotate(" + deg + "deg)";
  142.   }
  143.   function isOdd(n) { return Math.abs(n % 2) == 1; }
  144. </script>
  145. </html>)rawliteral";
  146.  
  147. void setup() {
  148.  Serial.begin(115200);
  149.  
  150.  // Connect to Wi-Fi
  151.  WiFi.begin(ssid, password);
  152.  while (WiFi.status() != WL_CONNECTED) {
  153.    delay(1000);
  154.    Serial.println("Connecting to WiFi...");
  155.  }
  156.  if (!SPIFFS.begin(true)) {
  157.    Serial.println("An Error has occurred while mounting SPIFFS");
  158.    ESP.restart();
  159.  }
  160.  else {
  161.    delay(500);
  162.    Serial.println("SPIFFS mounted successfully");
  163.  }
  164.  
  165.  configTime(0, 0, NTP_SERVER);
  166.  // Regarder ici https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv pour connaitre les codes du fuseau associés à votre région
  167.  setenv("TZ", TZ_INFO, 1);
  168.  
  169.  if (getNTPtime(10)) {  // Attendez 10sec pour la synchronisation
  170.  } else {
  171.    Serial.println("Time not set");
  172.    ESP.restart();
  173.  }
  174.  
  175.  lastNTPtime = time(&now);
  176.  lastEntryTime = millis();
  177.  
  178.  // Affichage de l'adresse IP du module
  179.  Serial.print("IP Address: http://");
  180.   Serial.println(WiFi.localIP());
  181.  
  182.  
  183.  
  184.   // Coupe le 'brownout detector'
  185.   WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
  186.  
  187.   // OV2640 camera module
  188.   camera_config_t config;
  189.   config.ledc_channel = LEDC_CHANNEL_0;
  190.   config.ledc_timer = LEDC_TIMER_0;
  191.   config.pin_d0 = Y2_GPIO_NUM;
  192.   config.pin_d1 = Y3_GPIO_NUM;
  193.   config.pin_d2 = Y4_GPIO_NUM;
  194.   config.pin_d3 = Y5_GPIO_NUM;
  195.   config.pin_d4 = Y6_GPIO_NUM;
  196.   config.pin_d5 = Y7_GPIO_NUM;
  197.   config.pin_d6 = Y8_GPIO_NUM;
  198.   config.pin_d7 = Y9_GPIO_NUM;
  199.   config.pin_xclk = XCLK_GPIO_NUM;
  200.   config.pin_pclk = PCLK_GPIO_NUM;
  201.   config.pin_vsync = VSYNC_GPIO_NUM;
  202.   config.pin_href = HREF_GPIO_NUM;
  203.   config.pin_sscb_sda = SIOD_GPIO_NUM;
  204.   config.pin_sscb_scl = SIOC_GPIO_NUM;
  205.   config.pin_pwdn = PWDN_GPIO_NUM;
  206.   config.pin_reset = RESET_GPIO_NUM;
  207.   config.xclk_freq_hz = 20000000;
  208.   config.pixel_format = PIXFORMAT_JPEG;
  209.  
  210.   if (psramFound()) {
  211.     config.frame_size = FRAMESIZE_UXGA;
  212.     config.jpeg_quality = 10;
  213.     config.fb_count = 2;
  214.   } else {
  215.     config.frame_size = FRAMESIZE_SVGA;
  216.     config.jpeg_quality = 12;
  217.     config.fb_count = 1;
  218.   }
  219.   // Camera init
  220.   esp_err_t err = esp_camera_init(&config);
  221.   if (err != ESP_OK) {
  222.     Serial.printf("Camera init failed with error 0x%x", err);
  223.     ESP.restart();
  224.   }
  225.  
  226.   // Page racine "/"
  227.   server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
  228.     request->send_P(200, "text/html", index_html);
  229.   });
  230.  
  231.   server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
  232.     takeNewPhoto = true;
  233.     request->send_P(200, "text/plain", "Taking Photo");
  234.   });
  235.  
  236.   //Chemin d'accès aux photos pour les balises images
  237.   server.on("/saved-photo/photo1", HTTP_GET, [](AsyncWebServerRequest * request) {
  238.     request->send(SPIFFS, "/photo1.jpg", "image/jpg", false);
  239.   });
  240.  
  241.       server.on("/saved-photo/photo2", HTTP_GET, [](AsyncWebServerRequest * request) {
  242.     request->send(SPIFFS, "/photo2.jpg", "image/jpg", false);
  243.   });
  244.     server.on("/saved-photo/photo3", HTTP_GET, [](AsyncWebServerRequest * request) {
  245.     request->send(SPIFFS, "/photo3.jpg", "image/jpg", false);
  246.   });
  247.  
  248.  
  249.   // Démarrage du serveur web
  250.   server.begin();
  251.  
  252. }
  253.  
  254. void loop() {
  255.   //Vrai s'il est plus de 22h mais moins de 5h
  256.   if(showTime(timeinfo, 1) >= 8 and showTime(timeinfo, 1) <= 17){
  257.     //Vrai si la photorésistance détecte de la lumière
  258.     if(!digitalRead(Photoresistance)){
  259.       //Vrai si le détecteur PIR ne détecte pas de présence et que la variable goPhoto est égale à 0
  260.       if(digitalRead(PIRsensor) && !goPhoto){
  261.         goPhoto = true;
  262.         takeNewPhoto = true;
  263.        //Vrai si le détecteur PIR détecte une présence
  264.       }else if(!digitalRead(PIRsensor)){
  265.         goPhoto = false;
  266.       }
  267.       if (takeNewPhoto) {
  268.         //Vrai le numéro de photo est supérieur à 1
  269.         if(numero_photo > 3){
  270.           numero_photo = 1;
  271.         }
  272.         capturePhotoSaveSpiffs(numero_photo); //Prise de le l'image numéro "numero_photo"
  273.         numero_photo++; //Incrémentation du numéro de photo
  274.         takeNewPhoto = false;
  275.          
  276.       }
  277.     }
  278.   }
  279.  
  280.   delay(1);
  281.   getNTPtime(10); //Récupération des données sur le temps
  282. }
  283.  
  284. // Vérification que l'enregistrement de la photo c'est bien passé
  285. bool checkPhoto( fs::FS &fs, int number ) {
  286.    char name[50];
  287.   sprintf(name, "/photo%d.jpg", number);
  288.   File f_pic = fs.open( name );
  289.   unsigned int pic_sz = f_pic.size();
  290.   return ( pic_sz > 100 );
  291. }
  292.  
  293. bool getNTPtime(int sec) {
  294.  
  295.   {
  296.     uint32_t start = millis();
  297.     do {
  298.       time(&now);
  299.       localtime_r(&now, &timeinfo);
  300.       delay(10);
  301.     } while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
  302.     if (timeinfo.tm_year <= (2016 - 1900)) return false;  // L'appel NTP à échoué
  303.     char time_output[30];
  304.     strftime(time_output, 30, "%a  %d-%m-%y %T", localtime(&now)); //Mise sous forme de string de la date et de l'heure
  305.   }
  306.   return true;
  307. }
  308.  
  309.  
  310. int showTime(tm localTime, int heure) {
  311.   if(heure == 1){
  312.     return localTime.tm_hour;
  313.   }else{
  314.     return localTime.tm_min;
  315.   }
  316. }
  317.  
  318.  
  319. // Prise d'une photo sauvegardé dans la mémoire SPIFFS
  320. void capturePhotoSaveSpiffs( int number ) {
  321.   camera_fb_t * fb = NULL; // pointer
  322.   bool ok = 0; // Boolean qui indique si la capture de photo a été réalisé
  323.   char name[50];
  324.   sprintf(name, "/photo%d.jpg", number);
  325.   do {
  326.     // Prise d'une photo avec la caméra
  327.     Serial.println("Taking a photo...");
  328.  
  329.     fb = esp_camera_fb_get();
  330.     if (!fb) {
  331.       Serial.println("Camera capture failed");
  332.       return;
  333.     }
  334.  
  335.     // Affichage du nom de la photo prise
  336.     Serial.printf("Picture file name: %s\n", name);
  337.     File file = SPIFFS.open(name, FILE_WRITE);
  338.  
  339.     // Insertion de données dans le fichier de la photo
  340.     if (!file) {
  341.       Serial.println("Failed to open file in writing mode");
  342.     }
  343.     else {
  344.       file.write(fb->buf, fb->len); // charge utile (image), longueur de la charge
  345.       Serial.print("The picture has been saved in ");
  346.       Serial.print(name);
  347.       Serial.print(" - Size: ");
  348.       Serial.print(file.size());
  349.       Serial.println(" bytes");
  350.     }
  351.     // Fermeture du fichier
  352.     file.close();
  353.     esp_camera_fb_return(fb);
  354.  
  355.     // Vérfification pour savoir si le fichier a correctement été enregistré
  356.     ok = checkPhoto(SPIFFS, number);
  357.   } while ( !ok );
  358. }
RAW Paste Data