ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time (timestamp)

In this tutorial, you’ll learn to take a picture with the ESP32-CAM and save it to the microSD card. We’ll include the current date and time on the filename. Including the date and time on the filename is useful because each picture will have a unique filename, which means no issues with overwriting existing files; you’ll know when each photo was taken; and it will be easier to organize or retrieve your files later on.

ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time Timestamp

New to the ESP32-CAM? Check our eBook: Build ESP32-CAM Projects.

Prerequisites

Before proceeding with this guide, check the following prerequisites.

ESP32-CAM

For this project, we’ll be using an ESP32-CAM AI-Thinker board.

ESP32-CAM Board

If you’re not familiar with the ESP32-CAM, you can follow the next tutorials:

You can also use a different ESP32 Camera board, you just need to make sure it supports a microSD card and that you adjust the right pinout on the code. This is only compatible with OV2640 cameras.

Arduino IDE

Arduino IDE 2 logo

We’ll program the ESP32 board using Arduino IDE. So you need the Arduino IDE installed as well as the ESP32 add-on. You can follow the next tutorial to install the ESP32 add-on, if you haven’t already:

MicroSD Card

We’ll save the photos taken with the ESP32-CAM on the microSD card. Your microSD card must be formatted as FAT32.

To get familiar with handling files with the microSD card and the ESP32, you can take a look at the following tutorial:

Getting Date and Time with the ESP32 (Accurate Timezone and Daylight Saving Time)

We’ll use the current date and time on the pictures’ filenames. We have a detailed tutorial explaining how to set timezone and daylight saving time when getting time from an NTP server using the ESP32:

Project Overview

The following diagram shows a high-level overview of the example we’ll build.

ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time project overview

In this tutorial, we’ll show you a simple example that does the following:

  1. The ESP32-CAM connects to your router via Wi-Fi (this is needed so that we can get time from an NTP server);
  2. The ESP32 connects to an NTP server to initialize the date and time with the correct timezone;
  3. It initializes the camera and the microSD card;
  4. The camera takes a new picture;
  5. It gets the current date and time from the NTP server;
  6. The photo is saved to the microSD card – its filename contains the date and time
    it was taken (it’s a unique filename);
  7. Repeat steps 4 to 6 every 10 seconds. For demonstration purposes, the ESP32-CAM will do this task over and over again on the loop(). The idea is to apply the concepts you’ll learn with this example to your own projects.

Using date and time on the picture filename has several advantages:

  • all pictures will have a different filename—you won’t have problems with overwriting previous files when the ESP32 resets;
  • you’ll know when each picture was taken;
  • it will be easier to organize your pictures later on.

Parts Required

To follow this tutorial you need an ESP32 camera module that supports a microSD card, the microSD card itself, and hardware to upload code to the board (it can be the ESP32-CAM MB programmer, or an FTDI programmer).

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Code

Copy the following code to your Arduino IDE. Before uploading the code to your board, you need to insert your SSID and password, and timezone string to set the correct timezone for your location (more about setting the timezone string below).

/*********
  Rui Santos
  Complete instructions at https://RandomNerdTutorials.com/esp32-cam-photo-microsd-card-timestamp
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/

#include "esp_camera.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"
#include <WiFi.h>
#include "time.h"

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE WITH YOUR TIMEZONE STRING: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
String myTimezone ="WET0WEST,M3.5.0/1,M10.5.0";

// Pin definition for CAMERA_MODEL_AI_THINKER
// Change pin definition if you're using another ESP32 camera module
#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

// Stores the camera configuration parameters
camera_config_t config;

// Initializes the camera
void configInitCamera(){
  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; //YUV422,GRAYSCALE,RGB565,JPEG
  config.grab_mode = CAMERA_GRAB_LATEST;

  // Select lower framesize if the camera doesn't support PSRAM
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //0-63 lower number means higher quality
    config.fb_count = 1;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  
  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}

// Connect to wifi
void  initWiFi(){
  WiFi.begin(ssid, password);
  Serial.println("Connecting Wifi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
}

// Function to set timezone
void setTimezone(String timezone){
  Serial.printf("  Setting Timezone to %s\n",timezone.c_str());
  setenv("TZ",timezone.c_str(),1);  //  Now adjust the TZ.  Clock settings are adjusted to show the new local time
  tzset();
}

// Connect to NTP server and adjust timezone
void initTime(String timezone){
  struct tm timeinfo;
  Serial.println("Setting up time");
  configTime(0, 0, "pool.ntp.org");    // First connect to NTP server, with 0 TZ offset
  if(!getLocalTime(&timeinfo)){
    Serial.println(" Failed to obtain time");
    return;
  }
  Serial.println("Got the time from NTP");
  // Now we can set the real timezone
  setTimezone(timezone);
}

// Get the picture filename based on the current ime
String getPictureFilename(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return "";
  }
  char timeString[20];
  strftime(timeString, sizeof(timeString), "%Y-%m-%d_%H-%M-%S", &timeinfo);
  Serial.println(timeString);
  String filename = "/picture_" + String(timeString) +".jpg";
  return filename; 
}

// Initialize the micro SD card
void initMicroSDCard(){
  // Start Micro SD card
  Serial.println("Starting SD Card");
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    return;
  }
  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }
}

// Take photo and save to microSD card
void takeSavePhoto(){
  // Take Picture with Camera
  camera_fb_t * fb = esp_camera_fb_get();
 
  //Uncomment the following lines if you're getting old pictures
  //esp_camera_fb_return(fb); // dispose the buffered image
  //fb = NULL; // reset to capture errors
  //fb = esp_camera_fb_get();
  
  if(!fb) {
    Serial.println("Camera capture failed");
    delay(1000);
    ESP.restart();
  }

  // Path where new picture will be saved in SD Card
  String path = getPictureFilename();
  Serial.printf("Picture file name: %s\n", path.c_str());
  
  // Save picture to microSD card
  fs::FS &fs = SD_MMC; 
  File file = fs.open(path.c_str(),FILE_WRITE);
  if(!file){
    Serial.printf("Failed to open file in writing mode");
  } 
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved: %s\n", path.c_str());
  }
  file.close();
  esp_camera_fb_return(fb); 
}

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector

  Serial.begin(115200);
  delay(2000);

  // Initialize Wi-Fi
  initWiFi();
  // Initialize time with timezone
  initTime(myTimezone);    
  // Initialize the camera  
  Serial.print("Initializing the camera module...");
  configInitCamera();
  Serial.println("Ok!");
  // Initialize MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();
}

void loop() {    
  // Take and Save Photo
  takeSavePhoto();
  delay(10000);
}

View raw code

How the Code Works

Continue reading to learn how the code works, or skip to the Demonstration section.

Include Libraries

First, include the required libraries to handle the camera, microSD card, and time.

#include "esp_camera.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"
#include <WiFi.h>
#include "time.h"

Network Credentials

Insert your network credentials on the following variables.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Timezone String

Insert your timezone string on the myTimezone variable. You can check a list of timezone string variables here. For example, I live in Porto. The timezone is Europe/Lisbon. From the list of timezone string variables, I see that the timezone string variable for my location is WET0WEST,M3.5.0/1,M10.5.0

//REPLACE WITH YOUR TIMEZONE STRING: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
String myTimezone ="WET0WEST,M3.5.0/1,M10.5.0";

Camera Pinout and Configurations

Then, include the pin definition for the camera model we’re using. For the ESP32‑CAM AI-Thinker module, this is the pin definition (change it if you’re using a different ESP32 camera model):

// Pin definition for CAMERA_MODEL_AI_THINKER
// Change pin definition if you're using another ESP32 camera module
#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

You can find the pin definition for several different ESP32 camera boards here: ESP32-CAM Camera Boards: Pin and GPIOs Assignment Guide.

The following line is needed to save the camera configurations. We’ll add the pin definition and the image settings later in the code.

// Stores the camera configuration parameters
camera_config_t config;

Configure and Initialize the Camera

The configInitCamera() function, starts by assigning the GPIOs you’ve defined earlier as well as the picture format.

// Initializes the camera
void configInitCamera(){
  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; //YUV422,GRAYSCALE,RGB565,JPEG
  config.grab_mode = CAMERA_GRAB_LATEST;

The picture format is defined in the following line

config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG

It can be set to one of the following formats:

  • PIXFORMAT_JPEG
  • PIXFORMAT_YUV422
  • PIXFORMAT_GRAYSCALE
  • PIXFORMAT_RGB565
  • PIXFORMAT_JPEG (format that we’re using)

Define the frame size, image quality, and the number of pictures saved in the frame buffer:

  // Select lower framesize if the camera doesn't support PSRAM
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //0-63 lower number means higher quality
    config.fb_count = 1;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

In case the camera model supports PSRAM, we set the frame size to UXGA (1600×1200) and the image quality to 1.

You can set the frame size to one of these options:

  • FRAMESIZE_UXGA (1600 x 1200)
  • FRAMESIZE_QVGA (320 x 240)
  • FRAMESIZE_CIF (352 x 288)
  • FRAMESIZE_VGA (640 x 480)
  • FRAMESIZE_SVGA (800 x 600)
  • FRAMESIZE_XGA (1024 x 768)
  • FRAMESIZE_SXGA (1280 x 1024)

The image quality can be a number between 0 and 63. A lower number means higher quality.

Important: very low numbers for image quality, especially at higher resolution, can make the ESP32-CAM crash, or it may not be able to take the photos correctly. So, if you notice that the images taken with the ESP32-CAM are cut in half or with strange colors, that’s probably a sign that you need to lower the quality (select a higher number like 10).

The following lines initialize the camera with the configurations you’ve set up previously. If the camera doesn’t initialize successfully, this will return an error message.

  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

Initialize WiFi

The initWiFi() function connects your board to your local network using the credentials you’ve set up previously.

// Connect to wifi
void  initWiFi(){
  WiFi.begin(ssid, password);
  Serial.println("Connecting Wifi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
}

Initialize Time and Set the Timezone

The setTimezone() function will set the TZ environmental variable with the correct timezone. call setenv(“TZ”, timezone, 1), where timezone is one of the timezones listed here. Then, call tzset() to update to that timezone. You should already have defined your timezone earlier in the code (myTimezone variable).

// Function to set timezone
void setTimezone(String timezone){
  Serial.printf("  Setting Timezone to %s\n",timezone.c_str());
  setenv("TZ",timezone.c_str(),1);  //  Now adjust the TZ.  Clock settings are adjusted to show the new local time
  tzset();
}

The initTime() function connects the ESP32-CAM to the NTP server and sets the correct timezone.

// Connect to NTP server and adjust timezone
void initTime(String timezone){
  struct tm timeinfo;
  Serial.println("Setting up time");
  configTime(0, 0, "pool.ntp.org");    // First connect to NTP server, with 0 TZ offset
  if(!getLocalTime(&timeinfo)){
    Serial.println(" Failed to obtain time");
    return;
  }
  Serial.println("Got the time from NTP");
  // Now we can set the real timezone
  setTimezone(timezone);
}

Get Current Time and Picture Filename

The whole purpose of this tutorial is to save pictures to the microSD card that include the date and time in the picture filename. The filename will be in the following format:

picture_YYYY-MM-DD_HH-MM-SS.jpg

The getPictureFilename() function gets the current date and time and outputs a string that can be used as a name for the picture filename.

String getPictureFilename(){

First, we get the date and time:

struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
  Serial.println("Failed to obtain time");
  return "";
}

Then, we convert the timeinfo variable to a String in the following format Y-m-d_H-M-S and print the result:

strftime(timeString, sizeof(timeString), "%Y-%m-%d_%H-%M-%S", &timeinfo);
Serial.println(timeString);

After having the date and time in a String format, we can concatenate it with “picture” and “.jpg”, which is the picture format.

String filename = "/picture_" + String(timeString) +".jpg";

Finally, we return the filename:

return filename;

Initialize the microSD Card

The initMicroSDCard() function initializes the microSD card. It returns an error message in case the initialization is not successful.

// Start Micro SD card
Serial.println("Starting SD Card");
if(!SD_MMC.begin()){
  Serial.println("SD Card Mount Failed");
  return;
}

The next lines return an error in case there isn’t a microSD card attached.

uint8_t cardType = SD_MMC.cardType();
if(cardType == CARD_NONE){
  Serial.println("No SD Card attached");
  return;
}

Take and Save a Picture

To take and save a picture, we created the takeSavePhoto() function.

First, it starts by taking a picture using the esp_camera_fb_get() function.

camera_fb_t * fb = esp_camera_fb_get();

This previous line creates a frame buffer fb that contains the image.

If you’re getting old pictures when you take a photo, it might mean that the picture buffer is saving more than one picture. To prevent that, you can uncomment the following lines in the code:

//esp_camera_fb_return(fb); // dispose the buffered image
//fb = NULL; // reset to capture errors
//fb = esp_camera_fb_get();

In case the capture fails, we print an error message and restart the board (restarting the board is optional, you can handle the error differently if you prefer, like trying to take another picture).

if(!fb) {
  Serial.println("Camera capture failed");
  delay(1000);
  ESP.restart();
}

After taking the picture, we’ll call the getPictureFilename() function to get a filename for the picture with the current timestamp.

  // Path where new picture will be saved in SD Card
  String path = getPictureFilename();
  Serial.printf("Picture file name: %s\n", path.c_str());

Now that we have the picture (frame buffer fb), and the picture filename we can save it on the micro SD card.

Open the microSD card in writing mode and create a file with the filename we’ve defined previously (it’s on the path variable):

fs::FS &fs = SD_MMC; 
File file = fs.open(path.c_str(),FILE_WRITE);

In case we’re not able the open the file (due to an error on the microSD card, or in creating the file), we print an error message.

if(!file){
  Serial.printf("Failed to open file in writing mode");
} 

Save the image by passing as arguments the frame buffer and its length to the write() method.

 file.write(fb->buf, fb->len); // payload (image), payload length

After that, close the file:

file.close();

Finally, call esp_camera_fb_return(fb) to clear the fb buffer, so that it’s available to use for the next picture.

esp_camera_fb_return(fb);

setup()

In the setup(), initialize the Serial Monitor, initialize Wi-Fi, set the timezone, configure and initialize the camera, and initialize the microSD card.

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector

  Serial.begin(115200);
  delay(2000);

  // Initialize Wi-Fi
  initWiFi();
  // Initialize time with timezone
  initTime(myTimezone);    
  // Initialize the camera  
  Serial.print("Initializing the camera module...");
  configInitCamera();
  Serial.println("Ok!");
  // Initialize MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();
}

loop()

In the loop(), call the takeSavePhoto() function to take a picture and save it on the microSD card. The picture name will already include the current timestamp.

void loop() {    
  // Take and Save Photo
  takeSavePhoto();
  delay(10000);
}

This function is called over and over again in the loop() every 10 seconds.

We do this for demonstration purposes. Now, you should be able to use the takeSavePhoto() function in your own projects to take pictures with a unique filename.

Demonstration

After inserting your network credentials and timezone string, upload the code to your board.

If you have an ESP32-CAM AI-Thinker, you should select AI Thinker ESP32-CAM in the Tools> Board menu.

Selecting the ESP32-CAM Ai Thinker in the Arduino IDE

After that, select the COM port in Tools > Port.

Finally, upload the code.

Arduino 2.0 Upload Button

If you’re having issues uploading the code, check our troubleshooting guide: ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed.

After successfully uploading the code to the board, open the Serial Monitor at a baud rate of 115200. Press the RST button so that it restarts the board and it starts running the code.

Don’tn forget to insert a microSD card on the ESP32-CAM microSD card slot.

Every 10 seconds, the flash will go on and it will save a picture to the microSD card. Let the code run for a while so that you get a considerable amount of pictures.

In the Serial Monitor, you should get something as shown below.

ESP32-CMA Take Pictures with Timestamp Serial Monitor Demonstration

Then, insert the microSD card into your computer to see the captured photos.

ESP32-CAM Pictures Folder on microSD Card

The photos should have the date and time in its name. For example:

picture_2023-01-17_17-31-40.jpg

This means that this picture was taken on:

  • Year: 2023
  • Month: 01 (January)
  • Day: 17th
  • Time: 17:31:40 (5:31:40 PM)

Wrapping Up

In this project, you learned how to request the date and time (with the correct timezone and daylight saving time) from the internet using the ESP32-CAM and use that information to name your pictures. This way, you know what time and date a certain picture was taken, and you don’t have to worry about overwriting photos on the microSD card.

For a detailed tutorial about getting date and time with the ESP32 and setting the timezone, we recommend the following tutorial:

To learn more about the ESP32-CAM and build more projects, we take a look at our eBook:

We hope you found this tutorial interesting.

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

41 thoughts on “ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time (timestamp)”

  1. It’s the first time I see, SD card with read IOT NTP time storage, really cool, superb, thanks Rui Santos and Sara Santos

    Reply
  2. sketch_mar09a:69:22: error: ‘CAMERA_GRAB_LATEST’ was not declared in this scope
    config.grab_mode = CAMERA_GRAB_LATEST;

    Wat to do ?:-)

    Reply
  3. Hi Sarah can you help me please with this error

    E (309) esp_core_dump_⸮͡⸮ Incorrect size of core dump image: 327685

    Reply
  4. Hello,
    I have tried the sketch, and after same problems resolved with cables and FDTI !!!, it’s taken pictures. It’s OK, uffffa.

    I try to open the web server in my web browser to but …
    “Hmmm… não é possível aceder a esta páginaO 192.168.1.161 recusou-se a estabelecer ligação.
    Tente o seguinte:…
    ERR_CONNECTION_REFUSED”.

    In this mode of taken pictures the esp32 can’t be access by the web page??

    Thanks
    Obrigado

    Reply
  5. Hi Sara,
    Some changes (warning) that should be made from ESP32 FW Version 2.6 .
    Arduino version 1.8.19 – Not tested on Arduino 2.X

    ‘camera_config_t::::pin_sscb_sda’ is deprecated: please use pin_sccb_sda instead

    camera_config_t::::pin_sscb_scl’ is deprecated: please use pin_sccb_scl instead

    This applies to all tutorials that use Arduino ESP32CAM.

    Change to : (see that only one letter has been changed)

    config.pin_sccb_sda = SIOD_GPIO_NUM;
    config.pin_sccb_scl = SIOC_GPIO_NUM;

    Thanks for the excellent tutorials.

    Reply
  6. Hi,
    Thanks for your tutorials they are detailed and I’m enjoying them.

    I’ve been trying to load this one but I keep on getting an error message which I can’t figure out.

    C:\Users\Admin\Documents\Arduino\ESP32-CAM-Save-Time-Date\ESP32-CAM-Save-Time-Date.ino:69:22: error: ‘CAMERA_GRAB_LATEST’ was not declared in this scope
    config.grab_mode = CAMERA_GRAB_LATEST;
    ^
    exit status 1
    Compilation error: ‘struct camera_config_t’ has no member named ‘grab_mode’

    Any idea as to what I’m doing wrong?

    Reply
    • Hi.
      Check that you have your ESP32 boards installation updated.
      Go to tools > Board > Boards Manager, search for ESP32 and check the version.
      Regards,
      Sara

      Reply
    • Roy,
      This message is related to image storage. Does your ESP32 CAM board have external PSRAM? If so, make sure that this memory has been configured in your program.

      Reply
  7. Hi Jose,

    It’s a ESP32-CAM with ESP32-S processor and external memory. I thought that the external PSRAM is automaticaly configured with ” if(psramFound()){ “

    Reply
  8. Hi Rui and Sara

    Thank you for this project
    I do appreciate it
    I wish you the best and berkah. amin
    btw, when can you upgrade to 5MP camera? ov5640?

    Reply
  9. Hi, great tutorial.
    1) How can I prevent the Flash from triggering each time the photo is taken?
    2) Is there a way to adjust the camera exposure time so that I can take night photos – I’m using the 850nm camera?
    thanks

    Reply
    • The tutorial really helped me too! Thanks @SaraSantos!
      I did find out how to disable the flash, however I do not completely understand why.
      I replaced: “if(!SD_MMC.begin()){” with:
      “if(!SD_MMC.begin(“/sdcard”, true)){ //adding “/sdcard”, true turns the LED that is used as flash off, removing this enables the flash”

      Reference: reddit.com/r/esp32/comments/nvgt1p/disabling_auto_flash_on_the_esp32_cam/

      Reply
  10. once the SD card is full of pictures, do you have/do you know a function or an additional code which erase the oldest pictures/overwrite on it?

    Reply
  11. This is cool! Great tutorial.

    Let’s say I am lazy and don’t want to remove the SD card and view/download pictures from remote host. Is there any option to implement some FTP/SMB server that will allow me to do that?

    Reply
  12. Hello Sara and Rui! Another great project. Thank you. Like many others have tried to use a RTC (internal or external) to grab the time from for the file name, so the camera can be used with a IR trigger where there is no WiFi. Is it a lost cause, because of the limited pins available when using the SD card? If there was a way, the internal RTC could be used while taking photos, and updated once in a while when it comes within wifi? Thank you!

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.