Esp32-Cam e sensore di movimento: ricevere foto per email

Ecco come programmare il modulo Esp32-Cam, per mandare una foto per email ad ogni movimento rilevato dal sensore.

Attraverso questa guida e pochi economici componenti, riuscirete a costruire un semplice sistema di sorveglianza capace di mandarvi una foto per email, ogni volta che verrà attivato il sensore di movimento. Questo è uno dei molteplici esempi di applicazione della Esp32-Cam , interessante modulo elettronico trattato già precedentemente qui su info4blog.it. Ecco un’interessante integrazione dell’Esp32-Cam e il sensore di movimento.

Con un semplice progetto compatibile con l’interfaccia grafica di programmazione Arduino IDE riusciremo a configurare i componenti in modo adeguato.

Requisiti Hardware

Lo schema

Esp32-Cam e sensore di movimento

Lo schema del progetto è molto semplice, dovrete solo collegare il pin del sensore di movimento al GPIO_NUM_13 del modulo Esp32-Cam, oltre naturalmente all’alimentazione.

Per quanto riguarda l’alimentazione, dipenderà dal tipo di sensore di movimento che avrete: i Pin di 5V o 3V3 sono già presenti sulla scheda, nell’esempio dello schema la VCC IN sarà di 5V poiché il Sensore di Movimento che userò sarà il HC-SR501.

Esp32-Cam e sensore di movimento

Prima di fare questo però, dovrete comunque scaricare il programma nella memoria del modulo, collegandolo correttamente come nello schema in foto con l’adattatore seriale FTDI per poter comunicare con il PC.

Esp32-Cam e sensore di movimento

Necessaria anche un piccola SD Card, anche di pochi giga, per inserirla nello slot del modulo. Infatti la scheda Esp32-Cam è dotata anche dello slot per leggere le SD Card. Con questo programma prima di inviarla per email, la foto verrà memorizzata anche su questo dispositivo, con un numero sequenziale. Conservandone così una copia di tutte le foto anche su storage locale.

Prerequisiti Software

Dopo aver installato Arduino IDE, per installare l’ADD-ON delle schede ESP32, dovrete incollare la seguente stringa nella scheda delle IMPOSTAZIONI che troverete sotto il menu FILE il primo a destra, e precisamente dovrete inserire questo testo accanto alla dicitura “URL aggiuntive per il gestore di schede”:

https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json

Successivamente in STRUMENTI, sotto nel primo menù a tendina troverete il GESTORE DI SCHEDE. Qui dovrete cercare, tramite la parola chiave “ESP32” il modulo “ESP32 by Espressif Systems e installarlo.

Dopo l’installazione, in STRUMENTI, dentro il menù SCHEDA: XXXX, troverete anche la voce “ESP32 Arduino” e all’interno la scheda che più si avvicinerà alla vostra. Nel mio caso “AI Thinker ESP32-Cam“. Dopo aver selezionato la Porta COM corrispondente, dovreste essere pronti per caricare l’esempio.

Questo programma utilizza anche la libreria ESP32 Mail Client by Mobizt. Dovrete quindi installare questa libreria semplicemente andando su STRUMENTI > Gestione librerie e inserendo nel campo di ricerca “ESP32 Mail Client”. Cliccare quindi su Installa per concludere l’installazione.

Il programma

Il programma di esempio completo potrete scaricarlo qui:

L’algoritmo fa in modo che quando viene attivato il Sensore di Movimento, la scheda NodeMCU riceva l’impulso e attiva di conseguenza la Esp32-Cam facendola uscire dalla modalità Sleep e scattando automaticamente una foto che verrà salvata nella scheda SD del modulo. Successivamente questa foto verrà allegata automaticamente ad un email che verrà inviata ad un indirizzo di posta elettronica preciso specificato precedentemente.

/*
 Esp32-Cam con Sensore di movimento info4blog.it
 Questo programma è la modifica di uno degli esempi che si può trovare nella libreria "ESP32 Mail Client" By Mobizt
 è necessario quindi installare questa libreria per poter eseguire correttamente l'algoritmo
 */
 /****
 Board Settings:
 Board: "ESP32 Wrover Module"
 Upload Speed: "921600"
 Flash Frequency: "80MHz"
 Flash Mode: "QIO"
 Partition Scheme: "Hue APP (3MB No OTA/1MB SPIFFS)"
 Core Debug Level: "None"
 COM Port: Depends On Your System
 */ 
 include "esp_camera.h"
 include "FS.h"
 include "SPI.h"
 include "SD.h"
 include "EEPROM.h"
 include "driver/rtc_io.h"
 include "ESP32_MailClient.h"
 // Selezionare il modello della camera (una voce sola senza //)
 //#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  // Modello della camera del modulo come quella dell'esempio nella pagina di info4blog.it
 include "camera_pins.h"
 define ID_ADDRESS            0x00
 define COUNT_ADDRESS         0x01
 define ID_BYTE               0xAA
 define EEPROM_SIZE           0x0F
 uint16_t nextImageNumber = 0;
 define WIFI_SSID             "NOME_DELLA_TUA_WIFI"
 define WIFI_PASSWORD         "PASSWORD_DELLA_TUA_WIFI"
 define emailSenderAccount    "EMAIL_CREATA_PER_MITTENTE@gmail.com"    //Per poter inviare un'e-mail dal servizio Gmail alla porta 465 (SSL), è necessario abilitare l'opzione "Consenti app meno sicure" https://myaccount.google.com/lesssecureapps?pli=1
 define emailSenderPassword   "PASSWORD_EMAIL_CREATA_PER_MITTENTE"
 define emailRecipient        "TUA_EMAIL_DI_DESTINAZIONE@gmail.com"
 //#define emailRecipient2     "recipient2@email.com"
 //The Email Sending data object contains config and data to send
 SMTPData smtpData;
 //Callback function to get the Email sending status
 void sendCallback(SendStatus info);
 void setup() 
 {
   Serial.begin(115200);
   Serial.println();
   Serial.println("Booting…");
 pinMode(4, INPUT);              //GPIO for LED flash
   digitalWrite(4, LOW);
   rtc_gpio_hold_dis(GPIO_NUM_4);  //diable pin hold if it was enabled before sleeping
 //connect to WiFi network
   Serial.print("Connecting to AP");
   WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
   while (WiFi.status() != WL_CONNECTED)
   {
     Serial.print(".");
     delay(200);
   }
 Serial.println("");
   Serial.println("WiFi connected.");
   Serial.println("IP address: ");
   Serial.println(WiFi.localIP());
   Serial.println();
 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_UXGA;
     config.jpeg_quality = 10;
     config.fb_count = 2;
   } else 
   {
     config.frame_size = FRAMESIZE_SVGA;
     config.jpeg_quality = 12;
     config.fb_count = 1;
   }
 if defined(CAMERA_MODEL_ESP_EYE)
 pinMode(13, INPUT_PULLUP);
   pinMode(14, INPUT_PULLUP);
 endif
 //initialize camera
   esp_err_t err = esp_camera_init(&config);
   if (err != ESP_OK) 
   {
     Serial.printf("Camera init failed with error 0x%x", err);
     return;
   }
 //set the camera parameters
   sensor_t * s = esp_camera_sensor_get();
  // s->set_contrast(s, 2);    //min=-2, max=2
  // s->set_brightness(s, 2);  //min=-2, max=2
  // s->set_saturation(s, 2);  //min=-2, max=2
   s->set_vflip(s, 1);//flip it back
   s->set_brightness(s, 1);//up the blightness just a bit
   s->set_saturation(s, -2);//lower the saturation
 delay(100);               //wait a little for settings to take effect
 //mount SD card
   Serial.println("Mounting SD Card…");
   MailClient.sdBegin(14,2,15,13);
 if(!SD.begin())
   {
     Serial.println("Card Mount Failed");
     return;
   }
 //initialize EEPROM & get file number
   if (!EEPROM.begin(EEPROM_SIZE))
   {
     Serial.println("Failed to initialise EEPROM"); 
     Serial.println("Exiting now"); 
     while(1);   //wait here as something is not right
   }
 /*
   EEPROM.get(COUNT_ADDRESS, nextImageNumber);
   Serial.println(nextImageNumber);
   nextImageNumber += 1;
   EEPROM.put(COUNT_ADDRESS, nextImageNumber);
   EEPROM.commit();
   while(1);
   */
 /ERASE EEPROM BYTES START/
   /*
   Serial.println("Erasing EEPROM…");
   for(int i = 0; i < EEPROM_SIZE; i++)
   {
     EEPROM.write(i, 0xFF);
     EEPROM.commit();
     delay(20);
   }
   Serial.println("Erased");
   while(1);
 /   /ERASE EEPROM BYTES END*/  
 if(EEPROM.read(ID_ADDRESS) != ID_BYTE)    //there will not be a valid picture number
   {
     Serial.println("Initializing ID byte & restarting picture count");
     nextImageNumber = 0;
     EEPROM.write(ID_ADDRESS, ID_BYTE);  
     EEPROM.commit(); 
   }
   else                                      //obtain next picture number
   {
     EEPROM.get(COUNT_ADDRESS, nextImageNumber);
     nextImageNumber +=  1;    
     Serial.print("Next image number:");
     Serial.println(nextImageNumber);
   }
 //take new image
   camera_fb_t * fb = NULL;
 //obtain camera frame buffer
   fb = esp_camera_fb_get();
   if (!fb) 
   {
     Serial.println("Camera capture failed");
     Serial.println("Exiting now"); 
     while(1);   //wait here as something is not right
   }
 //save to SD card
   //generate file path
   String path = "/IMG" + String(nextImageNumber) + ".jpg";
 fs::FS &fs = SD;
 //create new file
   File file = fs.open(path.c_str(), FILE_WRITE);
   if(!file)
   {
     Serial.println("Failed to create file");
     Serial.println("Exiting now"); 
     while(1);   //wait here as something is not right    
   } 
   else 
   {
     file.write(fb->buf, fb->len); 
     EEPROM.put(COUNT_ADDRESS, nextImageNumber);
     EEPROM.commit();
   }
   file.close();
 //return camera frame buffer
   esp_camera_fb_return(fb);
   Serial.printf("Image saved: %s\n", path.c_str());
 //send email
   Serial.println("Sending email…");
   //Set the Email host, port, account and password
   smtpData.setLogin("smtp.gmail.com", 587, emailSenderAccount, emailSenderPassword);
 //Set the sender name and Email
   smtpData.setSender("ESP32-CAM", emailSenderAccount);
 //Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
   smtpData.setPriority("Normal");
 //Set the subject
   smtpData.setSubject("Motion Detected - ESP32-CAM");
 //Set the message - normal text or html format
   smtpData.setMessage("
Foto eseguita ed inviata.
", true);
 //Add recipients, can add more than one recipient
   smtpData.addRecipient(emailRecipient);
   //smtpData.addRecipient(emailRecipient2);
 //Add attach files from SD card
   smtpData.addAttachFile(path);
 //Set the storage types to read the attach files (SD is default)
   smtpData.setFileStorageType(MailClientStorageType::SD);
 smtpData.setSendCallback(sendCallback);
 //Inizia a inviare e-mail, può essere impostata la funzione Callback (sendCallback) per monitorare lo stato
   if (!MailClient.sendMail(smtpData))
     Serial.println("Errore durante l'invio dell'e-mail, " + MailClient.smtpErrorReason());
 //Cancella tutti i dati dall'oggetto Email per liberare memoria
   smtpData.empty();
 pinMode(4, OUTPUT);              //GPIO per il LED flash
   digitalWrite(4, LOW);            //disattiva il LED flash
   rtc_gpio_hold_en(GPIO_NUM_4);    //si assicura che il flash sia tenuto in posizione LOW durante la modalità di sospensione
   Serial.println("Accesso alla modalità di sospensione deep sleep");
   Serial.flush(); 
   esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1);   //modalità di sospensione, si riattiva quando il pin 13 diventa HIGH (1, alto nel caso del componente HC-SR501, mentre 0, basso nel caso dell'AM312)
   delay(10000);                                   //attendere 10 secondi per consentire al sensore PIR di stabilizzarsi
   esp_deep_sleep_start();
 }
 void loop() 
 {
 }
 //sendCallback è la funzione che viene richiamata per ottenere lo stato finale della spedizione dell'email
 void sendCallback(SendStatus msg)
 {
   //Print the current status
   Serial.println(msg.info());
 //Do something when complete
   if (msg.success())
   {
     Serial.println("----------------Email_Correttamente_inviata");
   }
 }

Ricordatevi di modificare il file principale per inserire il (1)nome e la (2)password della Wifi, la vostra (3)Email MITTENTE e relativa (4)password, e un’email(5) di destinazione.

Potrete creare con Gmail un’email mittente che utilizzerete esclusivamente per questo servizio. Oppure potrete usare una vostra email, ricordatevi che dovrete abilitare la modalità “Consenti app meno sicurehttps://myaccount.google.com/lesssecureapps?pli=1 per poter tranquillamente utilizzare l’email recipiente come mittente. Come destinazione può invece essere usato qualsiasi indirizzo di email funzionante.

Come potete vedere il programma è molto semplice, si basa su programmi già utilizzati come esempio per il modulo ESP32-CAM. L’unico accorgimento è quello del Sensore di Movimento, che collegheremo al pin GPIO_NUM_13 del modulo NodeMCU.

Dopo aver collegato correttamente il modulo all’adattatore FTDI USB, come nello schema in foto, e individuato la porta COM da selezionare nel menu Strumenti>Porta dell’Arduino IDE, sarete in grado poi di caricare il programma sulla Esp32-Cam cliccando sulla freccina ‘carica’.

Dopo aver caricato correttamente il programma, potrete collegare il Sensore di movimento al Modulo nella sua versione definitiva.

Se avrete eseguito i passaggi correttamente, nel momento in cui passerete davanti al sensore di movimento, la camera del modulo invierà una foto all’indirizzo di mail destinatario inserito. Per verificare l’effettivo invio, nella Gmail di test con l’opzione “Consenti app meno sicure” attiva, all’interno della cartella ‘inviate’ dovrebbe comparirvi la lista delle email con le foto inviate.

Continuate a seguirci e non esitate a scrivere sotto questo articolo se avete dubbi o problemi pertinenti all’argomento.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.