En aquesta practica fem servir la placa ESP32-CAM per capturar fotos i pujar-les a in servidor FTP. Amb les fotos obtingudes realitzem un vídeo de prova del tipus Timelapse.
Per informació de la placa ESP32-CAM cal visitar la pagina:
esp32-cam.phpPer saber com instal·lar i configurar un client - servidor FTP, podeu visitar la següent pagina del blog de tresavis:
client-servidor-FTP.phpESP32-CAM te la possibilitat de emmagatzemar les fotos en una targeta de memòria en la mateixa placa, també la possibilitat de guardar les fotos en el sistema intern de fitxers SPIFFS: Esp32-foto-web.php
En aquesta practica guardem les imatges en un servidor FTP. Per recuperar les imatges guardades utilitzem el client FTP Filezilla.
El vídeo Timelapse o vídeo amb fotos consecutives consisteix en una tècnica de utilitzar una successió de fotos entre intervals de temps i muntar-les com a fotogrames de un vídeo. Es pot editar el vídeo afegint àudio i text.
El resultat del vídeo Timelapse es mostrar en càmera rapida i pocs segons un esdeveniment que passa en un temps molt mes gran. Per exemple una sortida de sol, el moviment dels núvols, etc.
ESP32-CAM amb càmera OV2640.
Programador FTDI.
IDE de Arduino.
Cable USB-miniUSB.

Per poder pujar les imatges de ESP32-CAM al servidor FTP de una manera simple, utilitzem la llibreria ESP32_FTPClient. Pagina de descarrega:
https://github.com/blackcodetavern/ESP32_FTPClient
La llibreria permet canviar de carpeta, llistar el contingut, pujar i descarregar fitxers. En aquesta practica ens limitem a pujar les fotos capturades al servidor FTP.
Podem instal·lar la llibreria de la següent manera:
En el IDE de Arduino anar a Esbós/Inclou biblioteca/Afegeix una biblioteca .ZIP... i seleccionar la carpeta descarregada.
Per obtenir la data actual fem servir la llibreria: NTPClient
Per instal·lar NTFClient ho fem des del gestor de biblioteques.

esp32-cam-ftp.ino
/* * IMPORTANT!!! - Placa "AI Thinker ESP32-CAM" - GPIO 0 connectat a GND per programar ESP32 - Despres de connectar GPIO 0 a GND, prem el RESET de ESP32-CAM per posar la placa en flashing mode - Per executar el programa, desfer el pont de GPIO0 a GND i prem el reset de la placa. */ #include "esp_camera.h" #include "soc/soc.h" // Desactiva apagades per falta de potencia #include "soc/rtc_cntl_reg.h" // Desactiva apagades per falta de potencia #include "driver/rtc_io.h" #include <WiFi.h> #include <WiFiClient.h> #include "ESP32_FTPClient.h" // Per les peticions de dia i hora. #include <NTPClient.h> #include <WiFiUdp.h> #include "time.h" // Servidor FTP char* ftp_server = "192.168.1.165"; char* ftp_user = "*******"; char* ftp_pass = "********"; char* ftp_path = "/home/josep/fotosEsp32/"; // WiFi const char* WIFI_SSID = "mirablau"; const char* WIFI_PASS = "********"; // Horari local, son 2 hores mes, en segons WiFiUDP ntpUDP; NTPClient horariClient(ntpUDP, "pool.ntp.org", (+3600*2), 60000); // Iniciem el client FTP ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass, 5000, 2); // Pins de la camera 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 // Variable config que servirà per configurar els parametres de la camera camera_config_t config; // ///////////// setup() ///////////////////////////// void setup() { // Desactiva apagades per falta de potencia WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector // Iniciem el monitor serie Serial.begin(115200); // Iniciem WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); Serial.println("Connectan a la Wifi..."); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("..."); } Serial.println("\nIP address: "); Serial.println(WiFi.localIP()); // Iniciem la camera amb la funció iniciaCamera(); // Iniciem i actualitzem el horari horariClient.begin(); horariClient.update(); // Obrim la connexio amb el servidor FTP ftp.OpenConnection(); } // ////////// loop() ///////////////////////////// void loop() { horariClient.update(); capturaFoto(); delay(60000); // 1 minut } // Funció capturaFoto() void capturaFoto() { // punter al bufer *fb camera_fb_t * fb = NULL; // Captura la foto fb = esp_camera_fb_get(); if(!fb) { Serial.println("La captura de la foto a fallat."); return; } /* * Pujem al servidor ftp */ // Camviem el directori de treball FTP ftp.ChangeWorkDir(ftp_path); ftp.InitFile("Type I"); // Format del nomFitxer 2018-04-30T16:00:13Z.jpg String nomFitxer = horariClient.getFormattedDate()+".jpg"; Serial.println("Pujant "+nomFitxer); // Longitut del fitxer nomFitxer int str_len = nomFitxer.length() + 1; // Convertim el nomFitxer de String a array de chars char char_array[str_len]; nomFitxer.toCharArray(char_array, str_len); // NewFile de FTP accepta nomes array de chars com a parametre ftp.NewFile(char_array); // Escrivim el buffer en el servidor FTP ftp.WriteData( fb->buf, fb->len ); // Tanquem ftp.CloseFile(); /* * Buidem el buffer */ esp_camera_fb_return(fb); } // Funció iniciaCamera() void iniciaCamera() { 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; if(psramFound()){ config.frame_size = FRAMESIZE_UXGA;//FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 12; config.fb_count = 1; } // Inicia Camera esp_err_t error = esp_camera_init(&config); if (error != ESP_OK) { Serial.printf("Camera ha fallat amb el error 0x%x", error); return; } }
Després de incloure les llibreries necessàries, inicialitzem els paràmetres del servidor FTP, la IP, el usuari amb la contrasenya i la ruta on es guardaran les imatges:
// Servidor FTP char* ftp_server = "192.168.1.165"; char* ftp_user = "*******"; char* ftp_pass = "******"; char* ftp_path = "/home/josep/fotosEsp32/"; // WiFi const char* WIFI_SSID = "mirablau"; const char* WIFI_PASS = "**********";
Configurem el clientNTP per obtenir la data hora local. En el nostre cas la diferencia horària, anem 2 hores per endavant del horari solar. En segons son +3600*2.
// Horari local, son 2 hores mes, en segons WiFiUDP ntpUDP; NTPClient horariClient(ntpUDP, "pool.ntp.org", (+3600*2), 60000);
Iniciem el client FTP, que pujarà les imatges al servidor, l’anomenem ftp i té com a paràmetres la IP del servidor, el usuari i la contrasenya.
// Iniciem el client FTP ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass, 5000, 2);
Definim els GPIO utilitzats per la càmera, es copiar i enganxar. Definim la variable config que fem servir per configurar els paràmetres de la càmera.
// Variable config que servirà per configurar els parametres de la camera camera_config_t config;
En el setup(), les clàssiques rutines de desactivar el detector de apagades, iniciar el monitor sèrie, iniciar WiFi.:
void setup() { // Desactiva apagades per falta de potencia WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector // Iniciem el monitor serie Serial.begin(115200); // Iniciem WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); Serial.println("Connectan a la Wifi..."); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("..."); } Serial.println("\nIP address: "); Serial.println(WiFi.localIP());
També en el setup tenim la funció iniciaCamera() que s’implementa apart.
Iniciar i actualitzar la data-hora amb la variable horariClient:
// Iniciem la camera amb la funció iniciaCamera(); // Iniciem i actualitzem el horari horariClient.begin(); horariClient.update();
Obrir la connexió amb el servidor FTP:
// Obrim la connexio amb el servidor FTP ftp.OpenConnection();
En el loop() cada minut actualitzem la data-hora i capturem una foto:
void loop() { horariClient.update(); capturaFoto(); delay(60000); // 1 minut }
La funció capturaFoto() realitza tres operacions, primer es captura la foto i es guarda en el buffer fb, segon s'anomena el fitxer amb la hora de la captura i es puja al servidor FTP, tercer es tanca la connexió amb el servidor i es buida el buffer.
// Funció capturaFoto() void capturaFoto() { // punter al bufer *fb camera_fb_t * fb = NULL; // Captura la foto fb = esp_camera_fb_get(); if(!fb) { Serial.println("La captura de la foto a fallat."); return; } /* * Pujem al servidor ftp */ // Camviem el directori de treball FTP ftp.ChangeWorkDir(ftp_path); ftp.InitFile("Type I"); // Format del nomFitxer 2018-04-30T16:00:13Z.jpg String nomFitxer = horariClient.getFormattedDate()+".jpg"; Serial.println("Pujant "+nomFitxer); // Longitut del fitxer nomFitxer int str_len = nomFitxer.length() + 1; // Convertim el nomFitxer de String a array de chars char char_array[str_len]; nomFitxer.toCharArray(char_array, str_len); // NewFile de FTP accepta nomes array de chars com a parametre ftp.NewFile(char_array); // Escrivim el buffer en el servidor FTP ftp.WriteData( fb->buf, fb->len ); // Tanquem ftp.CloseFile(); /* * Buidem el buffer */ esp_camera_fb_return(fb); }
Recordar que per que funcioni el programa carregat a la placa, es te que desfer el pont GPIO0-GND, nomes realitzat per pujar el codi, i després fer un Reset a la placa.
Una vegada comença a executar-se el programa, les imatges comencen a pujar de seguida.
El monitor sèrie mostra la següent informació:
La IP donada pel el router. Connectant amb el servido FTP en el nostre cas es 192.168.1.165. Envia al servidor el USER, PASSWORD i altres paràmetres. Am la connexió establerta el ESP32-CAM envia la primera foto de nom “data-hora.jpg”.Escriu el buffer i taca la connexió.

Per veure el resultat de les fotos capturades per la placa ESP32-CAM, tenim que anar al servidor FTP i obrir la carpeta contenidora de les fotos o accedir remotament al servidor utilitzant un client FTP. Nosaltres utilitzem Filezilla.
Descarreguem les imatges al nostre ordinador i el resultat es el seguent:

Per realitzar el vídeo utilitzem el editor de vídeos: Wondershare Filmora
Agafem les fotos del gos capturades amb ESP32-CAM, quan dormia, intercalem altres imatges i posem text i àudio.

El vídeo Timelapse resultant te el títol de Dog’s Dream:
El mar.
Havaneres.
Lloret antic.
Lloret avui.
De cala Morisca a Sa Carabera.
De Sa Carabera a Treumal.
Lloret en kayak.
Vígilancia remota.
Caixa-tpv.
Cambrer-app.
Client webApp.
Relats del banc del si no fos
Històries d'ahir
Vídeos antics de Lloret
El caiac
Contes de l'avi.
Control d’accés amb contrasenya.
Orgue de llums.
Comparativa de editors Arduino.
Projecte bon Nadal.
Control de la qualitat del aire interior (CO2) amb semàfor LED.
NodeMCU-ThingSpeak
ThingSpeak.
NodeMCU com AccessPoint.
Control de la llum de casa per web.
Control de un led per el mòbil.
Sistema de fitxers en ESP8266.
Altura del nivell d'aigua.
Avis d’alarma a Telegram.
Control de la intensitat de llum de un LED per Internet.
Magatzematge de temperatura i humitat en Thinger.
Publicar temperatura i humitat en Google Sheets.
ESP8266 i Firebase.
La bàscula. ESP8266 NodeMCU amb cèl·lula de càrrega.
ESP32-CAM
ESP32-CAM captura fotos per ser vistes en la WEB.
Pujar fotos a un servidor FTP amb ESP32-CAM.
MicroPython en ESP8266.
Visual Estudio Code per Arduino.
Classificador d’imatges.
Instal·lar i configurar Apache en Ubuntu.
Accés a un servidor Linux remotament.
Client i Servidor FTP.
Màquina virtual UBUNTU.
WindowsXP en Virtualbox.
Multisim, simulador de circuits electrònics.
Proteus, simulador de circuits electrònics.
MySQL. Instal·lació.
MySQL. Aplicacions.
Netbeans Maven MySQL.
Java+Netbeans+Maven+EclipseLink+Mysql
Aplicació d’escriptori JavaFX
App JavaFX amb SceneBuilder
App Java-Swing











Noves tecnologies WEB Arduino Domótica MycroPython NodeMCU IoT Java ESP8266 Lora C++ Programació Server-Client