ESP32-CAM hacer foto automáticamente

Hola,

El programado el módulo ESP32-CAM para que al realizar fotografía la suba a un servidor.

La fotografía la realiza pulsando un botón de Reset que lleva incorporado el módulo, quisiera incluir en el código Arduino la manera de que al conectarla a 5V, realice la fotografía automáticamente sin necesidad de pulsar el botón.

Dejo parte del código.

Gracias de antemano.
Jose.

.....

void initCamera() {
  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;
  } 
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  } 
}
void takePhoto() {
   
  camera_fb_t * fb = NULL;
 
  // Take Picture with Camera
  fb = esp_camera_fb_get(); 
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  /*
   * Upload to ftp server
   */
  ftp.ChangeWorkDir(ftp_path);
  ftp.InitFile("Type I");
 

  String diaSemana = daysOfTheWeek[timeClient.getDay()];
 
  Serial.println("Dia "+diaSemana);


  String nombreArchivo = diaSemana+timeClient.getFormattedTime()+".jpg";
 
  Serial.println("Subiendo "+nombreArchivo);
  int str_len = nombreArchivo.length() + 1;
 
  char char_array[str_len];
  nombreArchivo.toCharArray(char_array, str_len);
 
  ftp.NewFile(char_array);
  ftp.WriteData( fb->buf, fb->len );
  ftp.CloseFile();
 
  /*
   * Free buffer
   */
  esp_camera_fb_return(fb);
}
void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = rtc.now();
  printDate(now);
  timeClient.update();
  takePhoto();
  delay(10000);
}

Estas equivocado, esto

void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = rtc.now();
  printDate(now);
  timeClient.update();
  takePhoto();
  delay(10000);
}

toma una foto cada 10 segundos asi que te esta llenando el servidor con una foto cada 10 segundos.
Si quieres que se tome solo 1, coloca todo menos el delay en el setup y deja el loop solo

algo asi

void initCamera() {
  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;
  }
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}
void takePhoto() {
   
  camera_fb_t * fb = NULL;
 
  // Take Picture with Camera
  fb = esp_camera_fb_get();
  if (!fb) {
      Serial.println("Camera capture failed");
      return;
  }

  /*
   * Upload to ftp server
   */
  ftp.ChangeWorkDir(ftp_path);
  ftp.InitFile("Type I");
 

  String diaSemana = daysOfTheWeek[timeClient.getDay()];
 
  Serial.println("Dia "+diaSemana);


  String nombreArchivo = diaSemana+timeClient.getFormattedTime()+".jpg";
 
  Serial.println("Subiendo "+nombreArchivo);
  int str_len = nombreArchivo.length() + 1;
 
  char char_array[str_len];
  nombreArchivo.toCharArray(char_array, str_len);
 
  ftp.NewFile(char_array);
  ftp.WriteData( fb->buf, fb->len );
  ftp.CloseFile();
 
  /*
   * Free buffer
   */
  esp_camera_fb_return(fb);
  // put your main code here, to run repeatedly:
  DateTime now = rtc.now();
  printDate(now);
  timeClient.update();
  takePhoto();          // toma una foto y no hace mas nada
}
void loop() {

}

Hola,

Muchas gracias por la respuesta.

Lo he hecho como dices, sacando el hacer foto del loop, todo colocado en el setup y el loop vacío, pero hace fotos continuamente.

En el monitor serie, veo que una vez enviada la foto al servidor, se reinicia de nuevo el módulo y toma una segunda foto, la envía de nuevo al servidor, se reinicia de nuevo … y no consigo que deje de hacer fotos. He puesto un contador, para que ejecute cuando sea 0, y cuando hace la primera foto, obtengo un 1, pero como se inicia de nuevo en 0, continua haciendo fotos.

Dejo el código que he puesto hasta el setup.

Muchas gracias por la ayuda.

#include <RTClib.h>
#include <Wire.h>
#include <ETH.h>
#include <WiFi.h>
#include <WiFiAP.h>
#include <WiFiClient.h>
#include <WiFiGeneric.h>
#include <WiFiMulti.h>
#include <WiFiScan.h>
#include <WiFiServer.h>
#include <WiFiSTA.h>
#include <WiFiType.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include "time.h"

#include "esp_camera.h"
#include "Arduino.h"
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <WiFiClient.h>
#include "ESP32_FTPClient.h"

RTC_DS3231 rtc;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", (3600*1), 60000);
//NTPClient timeClient(ntpUDP, "pool.ntp.org", (-3600*3), 60000);
//
// WARNING!!! Make sure that you have either selected ESP32 Wrover Module,
//            or another board which has PSRAM enabled
//

// Select camera model
//#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


#include "camera_pins.h"


char* ftp_server = "ftp.xxxxxxxxxxxxx.com";
char* ftp_user = "xxxxxxxxx";
char* ftp_pass = "xxxxxxxxx";
char* ftp_path = "www/Arduino/";

const char* ssid = "xxxxxxx";
const char* password = "xxxxxxxxxxx";

RTC_DATA_ATTR int bootCount = 0;
int conta = 0 ;


String daysOfTheWeek[7] = { "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado"};
String monthsNames[12] = { "Enero", "Febrero", "Marzo", "Abril", "Mayo",  "Junio", "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre" };

// Pin definition for 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



void startCameraServer();

void setup() {
  ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass, 5000, 2);
  Serial.println("conta");
....

Si envia fotos continuamente es porque continuamente se esta reiniciando pero si te das cuenta he puesto el código en el setup() y eso ocurre solo una vez y es cuando se reinicia.
El loop() esta vacío. O sea no hay nada contínuo.

Ahora no es correcto que presiones reset para tomar una foto, pero es tu decisión.

Evidentemente tienes un problema y lo mejor sería que vayas aislando o separado partes del código hasta detectar aquella que no reinicia el ESP32.

Gracias!!

Iré probando como dices a ver si encuentro la solución.

De momento, al conectarlo a la fuente de 5V envía fotos contínuamente, sin darle al botón de reset, así que para empezar lo conectaré a la placa de arduino y con un relé que controlo cuando el PIR detecta presencia, se alimentará y enviará fotos al servidor.

Si encuentro la solución sin la placa de arduino, la comento.

Saludos!.