×

ARDUINO

Control d’accés amb contrasenya. Orgue de llums. Comparativa de editors Arduino. Projecte bon Nadal. Sensor de gas i de fums. Control de la qualitat del aire interior (CO2) amb semàfor LED.

NodeMCU

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 llum de casa des de 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. ESP8266-BME280 Firebase. La bàscula. ESP8266 NodeMCU amb cèl·lula de càrrega..

ESP32

ESP32-CAM, exemple de prova. Esp32-Cam captura fotos per ser vistes en la WEB. Pujar fotos a un servidor FTP amb ESP32-CAM. Foto amb ESP32-CAM i Telegram. Alarma amb avis a Telegram, utilitzant la placa ESP32-CAM.

PROGRAMACIÓ

Matemàtiques. App Inventor tutorial. MicroPython en ESP8266. Visual Estudio Code per Arduino

Intel·ligència artificial

Classificador d’imatges.

SERVIDORS

Instal·lar i configurar Apache en Ubuntu. Accés a un servidor Linux remotament. Client i Servidor FTP.

MÀQUINES VIRTUALS

Màquina virtual UBUNTU. WindowsXP en Virtualbox.

ELECTRÒNICA

Simulador Multisim. Simulador Proteus.

BASE DE DADES

MySQL. Instal·lació. MySQL. Aplicacions.

JAVA

Netbeans Maven MySQL. Java+Netbeans+Maven+EclipseLink+MySQL Aplicació d’escriptori JavaFX App JavaFX amb SceneBuilder App Java-Swing
favicon
logo

Tresavis

Benvinguts al blog de tresavis de noves tecnologies i més.

Correu : tresavis3@gmail.com

facebook   Instagram   youtube   x   tiktok

☰ Pràctiques   ☰ Articles

Pujar fotos a un servidor FTP amb ESP32-CAM.

Descripció.

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.

Contingut:

ftp1

Imatge de https://www.gsampallo.com/category/esp32-cam/

Estudis previs.

Per informació de la placa ESP32-CAM cal visitar la pagina:

esp32-cam.php

Per saber com instal·lar i configurar un client - servidor FTP, podeu visitar la següent pagina del blog de tresavis:

client-servidor-FTP.php

ESP32-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.

Components per desenvolupar la practica.

ESP32-CAM amb càmera OV2640.
Programador FTDI.
IDE de Arduino.
Cable USB-miniUSB.

         
ftp2

Llibreries.

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 ftp3

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.

ftp4-cam

CODI.

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;
    }  
  }

Explicacions del codi.

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); 
}

Resultat.

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ó.

monitor

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.

filezilla

Descarreguem les imatges al nostre ordinador i el resultat es el seguent:

ftp5

Vídeo Timelapse.

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.

ftp6

El vídeo Timelapse resultant te el títol de Dog’s Dream:

Contingut.


Nosaltres

castell
carrer
carabera
corbs
nubols1
nubols2
nubols3
mar
nubols4
maxims
nubols5

Tags

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