ESP32-CAM Take Photo and Save to MicroSD Card

Learn how to take photos with the ESP32-CAM board and save them to a microSD card using Arduino IDE. When you press the ESP32-CAM RESET button, it wakes up, takes a photo and saves it in the microSD card.

ESP32-CAM: Take Photo and Save to MicroSD Card

We’ll be using the ESP32-CAM board labelled as AI-Thinker module, but other modules should also work by making the correct pin assignment in the code.

The ESP32-CAM board is a $9 device (or less) that combines an ESP32-S chip, an OV2640 camera, a microSD card slot and several GPIO pins.

ESP32-CAM board is a $9 device with an OV2640 camera, microSD card slot and several GPIO pins

For an introduction to the ESP32-CAM, you can follow the next tutorials:

Watch the Video Tutorial

To learn how to take photos with the ESP32-CAM and save them in the microSD card, you can watch the following video tutorial or keep reading this page for the written instructions and all the resources.

Parts Required

To follow this tutorial you need the following components:

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!

Project Overview

Here is a quick overview on how the project works.

take photo save to micro sd card ESP32-CAM
  • The ESP32-CAM is in deep sleep mode
  • Press the RESET button to wake up the board
  • The camera takes a photo
  • The photo is saved in the microSD card with the name: pictureX.jpg, where X corresponds to the picture number
  • The picture number will be saved in the ESP32 flash memory so that it is not erased during RESET and we can keep track of the number of photos taken.

Formatting MicroSD Card

The first thing we recommend doing is formatting your microSD card. You can use the Windows formatter tool or any other microSD formatter software.

1. Insert the microSD card in your computer. Go to My Computer and right click in the SD card. Select Format as shown in figure below.

Formatting your microSD card Windows

2. A new window pops up. Select FAT32, press Start to initialize the formatting process and follow the onscreen instructions.

Formatting your microSD card Windows

Note: according to the product specifications, the ESP32-CAM should only support 4 GB SD cards. However, we’ve tested with 16 GB SD card and it works well.

Installing the ESP32 add-on

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:

Take and Save Photo Sketch

Copy the following code to your Arduino IDE.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-save-microsd-card
  
  IMPORTANT!!! 
   - Select Board "AI Thinker ESP32-CAM"
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
  
  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 "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

// define the number of bytes you want to access
#define EEPROM_SIZE 1

// 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

int pictureNumber = 0;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
 
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  //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_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_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_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    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;
  }
  
  //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;
  }
    
  camera_fb_t * fb = NULL;
  
  // Take Picture with Camera
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";

  fs::FS &fs = SD_MMC; 
  Serial.printf("Picture file name: %s\n", path.c_str());
  
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  } 
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  esp_camera_fb_return(fb); 
  
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);
  
  delay(2000);
  Serial.println("Going to sleep now");
  delay(2000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  
}

View raw code

The code starts by including the necessary libraries to use the camera. We also include the libraries needed to interact with the microSD card:

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

And the EEPROM library to save permanent data in the flash memory.

#include <EEPROM.h>

If you want to learn more about how to read and write data to the flash memory, you can follow the next tutorial:

Define the number of bytes you want to access in the flash memory. Here, we’ll only use one byte that allows us to generate up to 256 picture numbers.

#define EEPROM_SIZE 1

Then, define the pins for the AI-THINKER camera module.

// 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

Note: you might need to change the pin definition depending on the board you’re using. Wrong pin assignment will result in a failure to init the camera.

Initialize an int variable called pictureNumber that that will generate the photo name: picture1.jpg, picture2.jpg, and so on.

int pictureNumber = 0;

All our code is in the setup(). The code only runs once when the ESP32 wakes up (in this case when you press the on-board RESET button).

Define the camera settings:

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; 

Use the following settings for a camera with PSRAM (like the one we’re using in this tutorial).

if(psramFound()){
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  config.jpeg_quality = 10;
  config.fb_count = 2;
}

If the board doesn’t have PSRAM, set the following:

else {
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;
}

Initialize the camera:

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

Initialize the microSD 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;
}

More information about how to use the microSD card can be found in the following project:

The following lines take a photo with the camera:

camera_fb_t * fb = NULL;

// Take Picture with Camera
fb = esp_camera_fb_get();  
if(!fb) {
  Serial.println("Camera capture failed");
  return;
}

After that, initialize the EEPROM with the size defined earlier:

EEPROM.begin(EEPROM_SIZE);

The picture number is generated by adding 1 to the current number saved in the flash memory.

pictureNumber = EEPROM.read(0) + 1;

To save the photo in the microSD card, create a path to your file. We’ll save the photo in the main directory of the microSD card and the file name is going to be (picture1.jpg, picture2.jpg, picture3.jpg, etc
).

String path = "/picture" + String(pictureNumber) +".jpg";

These next lines save the photo in the microSD card:

fs::FS &fs = SD_MMC; 
Serial.printf("Picture file name: %s\n", path.c_str());

File file = fs.open(path.c_str(), FILE_WRITE);
if(!file){
  Serial.println("Failed to open file in writing mode");
} 
else {
  file.write(fb->buf, fb->len); // payload (image), payload length
  Serial.printf("Saved file to path: %s\n", path.c_str());
  EEPROM.write(0, pictureNumber);
  EEPROM.commit();
}
file.close();

After saving a photo, we save the current picture number in the flash memory to keep track of the number of photos taken.

EEPROM.write(0, pictureNumber);
EEPROM.commit();

When the ESP32-CAM takes a photo, it flashes the on-board LED. After taking the photo, the LED remains on, so we send instructions to turn it off. The LED is connected to GPIO 4.

pinMode(4, OUTPUT);
digitalWrite(4, LOW);
rtc_gpio_hold_en(GPIO_NUM_4);

Finally, we put the ESP32 in deep sleep.

esp_deep_sleep_start();

Because we don’t pass any argument to the deep sleep function, the ESP32 board will be sleeping indefinitely until RESET.

ESP32-CAM Upload Code

To upload code to the ESP32-CAM board, connect it to your computer using an FTDI programmer. Follow the next schematic diagram:

ESP32-CAM connected to an FTDI Programmer to upload program using Arduino IDE

Many FTDI programmers have a jumper that allows you to select 3.3V or 5V. Make sure the jumper is in the right place to select 5V.

Important: GPIO 0 needs to be connected to GND so that you’re able to upload code.

ESP32-CAMFTDI Programmer
GNDGND
5VVCC (5V)
U0RTX
U0TRX
GPIO 0GND

To upload the code, follow the next steps:

1) Go to Tools > Board and select AI-Thinker ESP32-CAM.

2) Go to Tools > Port and select the COM port the ESP32 is connected to.

3) Then, click the upload button to upload the code.

4) When you start to see these dots on the debugging window as shown below, press the ESP32-CAM on-board RST button.

After a few seconds, the code should be successfully uploaded to your board.

Demonstration

After uploading the code, remove the jumper that connects GPIO 0 from GND.

Open the Serial Monitor at a baud rate of 115200. Press the ESP32-CAM reset button. It should initialize and take a photo. When it takes a photo it turns on the flash (GPIO 4).

ESP32-CAM Take Photo and Save to MicroSD Card Demonstration

Check the Arduino IDE Serial Monitor window to see if everything is working as expected. As you can see, the picture was successfully saved in the microSD card.

ESP32-CAM Take Photo and Save to MicroSD Card Arduino IDE Serial Monitor Demonstration

Note: if you’re having issues with the ESP32-CAM, take a look at our troubleshooting guide and see if it helps: ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed

After making sure that everything is working as expected, you can disconnect the ESP32-CAM from the FTDI programmer and power it using an independent power supply.

ESP32-CAM powered with powerbank / independent power supply

To see the photos taken, remove the microSD card from the microSD card slot and insert it into your computer. You should have all the photos saved.

ESP32-CAM photo pictures examples saved in MicroSD Card

The quality of your photo depends on your lighting conditions. Too much light can ruin your photos and dark environments will result in many black pixels.

Troubleshooting

If you’re getting any of the following errors, read our ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed

  • Failed to connect to ESP32: Timed out waiting for packet header
  • Camera init failed with error 0x20001 or similar
  • Brownout detector or Guru meditation error
  • Sketch too big error – Wrong partition scheme selected
  • Board at COMX is not available – COM Port Not Selected
  • Psram error: GPIO isr service is not installed
  • Weak Wi-Fi Signal
  • No IP Address in Arduino IDE Serial Monitor
  • Can’t open web server
  • The image lags/shows lots of latency

Learn how to program and build 17 projects with the ESP32-CAM using Arduino IDE DOWNLOAD »

Learn how to program and build 17 projects with the ESP32-CAM using Arduino IDE DOWNLOAD »

Wrapping Up

We hope you’ve found this tutorial useful and you are able to use it in your projects. If you don’t have an ESP32-CAM board, you can click here to get one.

As mentioned previously, we have other tutorials about the ESP32-CAM that you may like:

Thank you 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!

221 thoughts on “ESP32-CAM Take Photo and Save to MicroSD Card”

  1. Good! Congratulations!!
    I’m findig how to make this but instead using reset to take photo, program a time lapse photo, from 5 to 60 sec, storaging them in SDcard.
    Can you think about it?
    Thanks!

    Reply
    • Hi Frank.
      That’s a very interesting project.
      I think you just need to create a timer that triggers a function that takes the photo and saves to the microSD card. And put everything in the loop.
      I’ll think about your project, and maybe create a tutorial in the future.
      REgards,
      Sara

      Reply
      • Hi Sara!
        Have you created that project yet? I tried to make the esp32 cam take a picture then save SD card automatically in 5 seconds by keeping the original code and adding this function: esp_sleep_enable_timer_wakeup(5 * 1000000);
        Esp32 cam can still take a picture then save to SD card, but I couldn’t open those files in laptop.
        Thank you.

        Reply
  2. Rui,i m so sorry ,i m radio man no digital 🙂 when i try to compile this sketch ,arduino 1.8.5 tell me :
    Board esp32wrover (platform esp32, package esp32) is unknown

    Error compiling for board ESP32 Wrover Module.

    Reply
    • Hi Mikele.
      I’m sorry for the delay in my response.
      Were you able to fix this issue?
      What other information do you get in the serial monitor?
      Regards,
      Sara

      Reply
      • no no Sara,everything is ok….
        now i can compile sketch and waiting esp32-cam board from ebay,all is ok 😉 🙂
        all the best for you and Rui ,see you 😉
        73 de 9a3xz-Mikele-Croatia

        Reply
  3. Hello Rui,
    I’m a great fan of your blog, and bought several of your books and courses.
    I found this post if this can help for shutting down the LED :
    https://www.esp32.com/viewtopic.php?t=4040

    Also I would like to build a system that takes a picture of animal passing by a path. I was thinking to add an IR motion sensor or an external command by a light barrier to the SD card recording system you described.
    Could you please make a post of such a system ?
    Thanks in advance,
    Claude

    Reply
    • Thank you for sharing that solution.
      At the moment, we weren’t able to interface the PIR sensor with the EPS32-CAM. But we’ll try again and create a new tutorial about that if we succeed.
      Regards,
      Sara

      Reply
  4. LED pin output needs to be set LOW then HOLD to keep it off during sleep. Disable HOLD after wakeup to use the pin again.

    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    rtc_gpio_hold_en(GPIO_NUM_4);
    delay(500);
    esp_deep_sleep_start();

    Reply
  5. rtc & digital io pin state can be maintained during hibernation with these two functions:
    rtc_gpio_hold_en
    rtc_cntl_dg_pad_force_hold

    More info:
    esp32.com/viewtopic.php?t=1966

    Reply
    • Thanks for sharing.
      I’ve included the following:
      #include “driver/rtc_io.h”

      Then, used:
      rtc_gpio_hold_en(GPIO_NUM_4);

      To keep GPIO LOW during deep sleep as you suggested in your previous comment.

      It worked! So, I updated the code!

      Thank you 😀

      Reply
  6. Very nice! Could the sketch be modified to be triggered by connecting one of the gpio pins to ground instead of pressing the reset button? This would make it useful in an application in which a remote switch is used to trigger.

    Reply
  7. I am struggling getting a PIR sensor to wake the esp32 from deep sleep. Is it possible the camera configuration is interfering with it?

    Reply
    • Thank you for your comment.
      We’ve tried interfacing the camera with the PIR motion sensor. But when using the SD card, there are almost no pins left to connect the PIR motion sensor. The pins left didn’t work with the sensor: the ESP-CAM crashed.
      So, we weren’t successful yet to interface a PIR. But will try again.
      Regards,
      Sara

      Reply
  8. Instead of pressing the reset button’ I owuld like to activate the camera by a movement sensor for example in order to watch the house…
    Thanks for an interesting project.

    Reply
  9. Good afternoon. Excellent example. But the author did not adjust the matrix OV2640. I added this code:

    // Set camera sensor
    sensor_t * s = esp_camera_sensor_get();

    s->set_framesize(s, MY_FRAMESIZE);
    s->set_quality(s, MY_QUALITY);
    s->set_contrast(s, 0);
    s->set_brightness(s, 0);
    s->set_saturation(s, 0);
    s->set_gainceiling(s, GAINCEILING_16X);
    s->set_colorbar(s, 0);
    s->set_whitebal(s, 0);
    s->set_hmirror(s, 0);
    s->set_vflip(s, 0);
    s->set_ae_level(s, 0);
    s->set_special_effect(s, 0);
    s->set_wb_mode(s, 2);
    s->set_awb_gain(s, 1);
    s->set_bpc(s, 1);
    s->set_wpc(s, 1);
    s->set_raw_gma(s, 1);
    s->set_lenc(s, 0);
    s->set_agc_gain(s, 1);
    s->set_aec_value(s, 600);
    s->set_gain_ctrl(s, 0);
    s->set_exposure_ctrl(s, 0);
    s->set_aec2(s, 1);
    s->set_dcw(s, 0);

    Reply
  10. Thanks for this great tutorial.
    Could you explain how to connect external spi device (ex: tft ST7735)
    I have tryied multiple pin conbinaison without success.

    Reply
    • Hi.
      You need to check what pins are being used by the camera. You can’t use those.
      Then, if you’re using the microSD card, you can’t also use those pins. So, there are little pins left to connect an external SPI device.
      Take a look at the pins used by the board and see if you have some left that can be used with your peripherals. Here are the pins (page 3): loboris.eu/ESP32/ESP32-CAM%20Product%20Specification.pdf
      Regards,
      Sara

      Reply
    • Please let me know if you figure out what pins to use that dont cause a crash. I am having trouble getting the SD card to mount after deep sleep.

      Reply
      • Hi. You need to add

        rtc_gpio_hold_dis(GPIO_NUM_4);

        before initializing the microSD card, to “unhold” the state of GPIO 4.

        Regards,
        Sara

        Reply
  11. Hello, very cool the design of the camera. Thank you for sharing another project and increasing our field of knowledge.

    Reply
  12. In regards to waking after deep sleep and the SD card not mounting:

    The code you have posted forces GPIO4 to hold its value in this line:

    rtc_gpio_hold_en(GPIO_NUM_4);

    This pin is used for SD card interface. You need to un-hold it after deep sleep wakeup if you want to use the pin again.

    Reply
    • I used gpio 13 pin D3 to make the PIR sensor work. I also removed the light hold.. I would like the light to be off during deep sleep. When I figure it out I will post some pictures of what I rigged up if people want. Thanks again.

      Reply
      • Hi David.
        Yes, please share your results with us.
        Were you able to use GPIO 13 as an interrupt without the ESP crashing?
        Regards,
        Sara

        Reply
        • bit.ly/2IZ7Kjz
          here is a schematic of what I did. I am new to schematics so I hope everything is right. Anyway, the board pin is pulled low instead of floating by this circuit. Although I’ve been told this is not a good pin to use because it is HIGH on boot. However it seems to work OK for me.

          then ofcourse I use this code before deep sleep:
          esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

          cheers,
          David

          Reply
          • Hi, I am doing the exact same project ,but i have problems with SD card.Can you send me your code?

        • bit.ly/2IZ7Kjz
          here is a schematic of what I did. I am new to schematics so I hope everything is right. Anyway, the board pin is pulled low instead of floating by this circuit. Although I’ve been told this is not a good pin to use because it is HIGH on boot. However it seems to work OK for me.

          then of course I use this code before deep sleep:
          esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

          cheers,
          David

          Reply
          • looking at it now I am not sure what the 10k resistor does. I have tested it multiple times and it is definitely how i have it wired up though…

          • Hi David.
            Thank you so much for sharing.
            I would like to give it a try and maybe create a tutorial about that.
            Can you share the code that you are running on the ESP32-CAM? You can use pastebin for example to share your code.
            Would you mind if we used that information to create a new tutorial?
            Regards,
            Sara

          • yes ofcourse make a tutorial if you want. Honestly though I was unable to get the PIR sensor to work well in sunlight but that may not be a problem for your project.

            Unfortunately I do not have the exact code on hand right now, but it is simply your code without the LED hold and with:
            esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

            I will make double sure that is right when I get home tomorrow morning. I was thinking of testing it again with a simple push button on the same pin just to be sure.

            Thanks,
            David

  13. Hello,
    I’ve succeed to compile successfuly the sketch in IDE following your instructions but I’m confused about loading in ESP32.
    How to power the ESP32 module please, because with the FTDI connected alone to USB, back pin 3.3V is around 4V and 5.0V is around 6V , Is the FTDI defective ?
    Or should the ESP32 powered with a separate power supply ?
    thanks for claryfying this point,
    Rgds,

    Reply
    • Hi.
      In our example, we’re powering the ESP32 using the 3.3V from the FTDI programmer connected to the 3.3V of the ESP32-CAM and it works well.
      Some people reported that the ESP32-CAM only worked well when powering with 5V through the 5V pin.
      You can also use a separated power supply up to 5V.
      Regards,
      Sara

      Reply
  14. Hi.. can you helpme? SD 2G . Fat32 formated. like tutorial. the board works ok with the proyect (ESP32-CAM Video Streaming and Face Recognition)

    18:57:51.475 -> Picture file name: /picture1.jpg
    18:57:51.475 -> E (2403) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0xffffffff
    18:57:51.475 -> E (2404) diskio_sdmmc: sdmmc_read_blocks failed (-1)
    18:57:52.500 -> E (3409) sdmmc_req: sdmmc_host_wait_for_event returned 0x107
    18:57:52.500 -> E (3409) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
    18:57:52.500 -> E (3410) diskio_sdmmc: sdmmc_read_blocks failed (263)

    Thanks.

    Reply
    • Hi Wido.
      That will be one of our next projects.
      But at the moment, we don’t have anything about that subject.
      Regards,
      Sara

      Reply
  15. The article says an a.i. thinker module is being used….but top of code say “Wrover”. Please explain?
    Thanks, Curt Wells

    Reply
    • Hi.
      In our first ESP32-CAM projects, the AI-thinker module wasn’t defined in the Boards menu at the time.
      Now, you should be able to find the AI-Thinker module on the Boards menu.
      However, you can select either board and it should work.
      Regards,
      Sara

      Reply
  16. I tried to make the ESP32-CAM to wake up after some time (1 minute), I upload the sketch and put it to work.
    The first picture is taken by the ESP32-CAM, then it goes to sleep. When it wakes up, the ESP32-CAM tries to access the MicroSD Card and returns the message:

    E (7143) sdmmc_sd: sdmmc_check_scr: send_scr returned 0xffffffff
    SD Card Mount Failed

    But if I press Reset, it works normally (the picture is taken).

    Reply
    • Hi Eduardo.
      Try to add the following at the beginning of the setup():
      pinMode(4, INPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_dis(GPIO_NUM_4);
      Then, tell me if it solved your issue.
      Regards,
      Sara

      Reply
      • Hi Sara, first of all thanks for sharing all those projects.

        I had the same error as reported by Eduardo but with a different error number:

        E (2635) sdmmc_sd: sdmmc_check_scr: send_scr returned 0xffffffff

        Can’t figure out how to fix that. Do you have any suggestion?

        thanks again

        Reply
      • Hi Sara,

        I have same problem but first of all I don’t use sleep mode so reset button as well. Only It takes a photo in each 3 seconds and save it to SD card as refering your source code .Apart from that no diffrerence in code. And then I applied to code your suggestion above for this error. But it didn’t work.
        Do you have another solution ??

        Also I wonder whether there is an relationship between gpio 2 and SD card or bootloader mode or not. If you can explain me or give a clue, I would be very happy,

        Best Regards,
        GS.

        Reply
  17. In order to upload a photo to a server, how can a post request be added to one of the esp32-cam projects ?
    I know how to add a received file manager to the server, but all the examples I find with a google search use a client form to upload – which requires a human to select a file on the client.

    Reply
  18. I have the same doubt from Curt Wells. The solution which I figured myself was to save the picture taken by the camera in the SPIFFS and show the picture in the web server. I’m using Ngrok to publish my web server on the internet and so far it’s working.

    Reply
  19. I really sorry for doing that, but right now this is the only thing I can do…
    But by sunday or monday I can write some more neater and post on my github.

    I think that it won’t be difficult to get some help with the other guys in this weekend.

    Again, sorry for the mess. But I assure that it works (its working right now)

    Reply
      • Hi Curt! As I promissed, I made something much more neater and uploaded to a repo in my github. You can download, comment, ask change the code, or whaterever in it. Fell free to make you questions there, I will answer then.

        https://github.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT

        For Rui and Sara: PLEASE, ERASE THE OTHER POST WHICH I PUT A VERY LONG CODE. THAT CODE IS A REAL MESS.
        ALSO, YOU CAN USE THE CODE I UPLOADED TO GITHUB FOR WHATEVER YOU WANT. AS YOU GUYS CAN SEE, MANY YTHINGS ARE DERIVED FROM THE CODE SHOWN IN RUI’S BOIOK ‘LEARN ESP32 IN ARDUINO IDE’.

        Reply
        • Hi Eduardo.
          Thank you so much for sharing.
          We’ll take a look at your code and probably build a project about that.
          Regards,
          Sara

          Reply
    • try first putting the header (dl_lib.h) in brackets: #include “dl_lib.h” > #include . If that doesn’t work, try commenting the line: //#include “dl_lib.h”. For some people the first solution worked, for me, the second, without visible bad effects, the program work normally. I don’t know what function prototypes are in that header, since I don’t have it.

      Reply
  20. fail to compile with arduino 1.8.9 here is the error message I get:
    Arduino: 1.8.9 (Linux), Board: “ESP32 Wrover Module, Huge APP (3MB No OTA), QIO, 80MHz, 921600, None”

    Build options changed, rebuilding all
    /home/david/Arduino/espcam/espcam.ino: In function ‘void setup()’:
    espcam:130:28: error: ‘rtc_gpio_hold_en’ was not declared in this scope
    rtc_gpio_hold_en(GPIO_NUM_4);
    ^
    exit status 1
    ‘rtc_gpio_hold_en’ was not declared in this scope

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.
    Arduino: 1.8.9 (Linux), Board: “ESP32 Wrover Module, Huge APP (3MB No OTA), QIO, 80MHz, 921600, Non
    I cannot find the problem. Can you help Thank you for any help David Nelson

    Reply
  21. Good afternoon, dear Sarah. Could you please tell me two main points to operate ESP32-CAM. I’m interested in how to lower the flash power or turn it off? It is not the best, but the energy demands and the problem I have is that the flash does not go off at all sometimes! Also you can show me how from *FB the picture to break into arrays on 10 bytes in order that I could send them on UART? Please help as soon as possible.

    Reply
    • Hi Dimka.
      To turn off the flash:
      include the following library:

      #include “driver/rtc_io.h”

      Then, add this in your setup():

      pinMode(4, INPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_dis(GPIO_NUM_4);

      before going to sleep use to keep the LED off:

      pinMode(4, OUTPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_en(GPIO_NUM_4);

      I hope this helps.
      At the moment I don’t have any example to break the picture into arrays.
      Regads,
      Sara

      Reply
  22. I know I can disable the library:
    #include “driver/rtc_io.h”
    And the led will not work.
    Another question is did photos 200 pictures become black with ripples, what to do?

    Reply
  23. Hi thanks a lot for spending time to complete this project and sharing it. I’m having an esp32 module an ov7670 module and an SD CARD MODULE. Can I connect all these three as per code and use your code. Or is this code only for esp32cam module?

    Reply
    • Hi.
      I believe that if you make the same connections between the camera and the sd card as they are in the ESP32-CAM, the code should work, but I haven’t tried it.
      Regards,
      Sara

      Reply
  24. Hi, I have a problem compiling the sketch which is the following: C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: In function ‘char * dstrdup (str_t)’:

    C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: 232: 11: error: expected unqualified-id before ‘new’

         str_t new = dalloc (len);

               ^

    C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: 233: 29: error: expected type-specifier before ‘,’ token

         return (str_t) memcpy (new, s, len);

    Could you help me with this library or with this problem

    Thanks in advance 🙂

    Reply
    • Hi Joel.
      Some readers suggested the following to solve that issue:
      “For dl_lib.h: No such file or directory is because ESP32 Board Version 1.03 does’nt seem to include this anymore. Downgrade your ESP32 Board Version down to 1.02 in Andruino IDE or comment that line using version 1.03”.
      I hope this helps.
      Regards,
      Sara

      Reply
      • This issue happened here a while ago, but I solved in a much faster way than downgrading the “ESP32 boards” library.

        I don’t know why but (at least in my Arduino IDE) the ESP32 boards list appears twice in the Tools>Board menu.

        When I chose the “AI Thinker ESP32-CAM” in the first menu, I got this error.
        Then, I chose this board in the second menu and, like magic, everything worked like a charm.

        Don’t ask me why, but it worked…

        Reply
  25. Hello, I would like to know if it is possible that after taking the photo do not send the esp32 to sleep, but the possibility of taking more photos without the need to restart the esp32

    Reply
    • Yes Joel, its possible!
      I already asked something like that and got anwered here.

      I encapsulated the lines which takes a picture in a function (see it below):

      void take_picture(){
      digitalWrite(4, HIGH); //Turn on the flash
      camera_fb_t * fb = NULL; // FB pointer

      if(!fb) {
      Serial.println(“Camera capture failed”);
      return;
      }
      // initialize EEPROM with predefined size
      EEPROM.begin(EEPROM_SIZE);
      pictureNumber = EEPROM.read(0) + 1;

      // Path where new picture will be saved in SD Card
      String path = “/foto_” + String(pictureNumber) +”.jpg”;

      fs::FS &fs = SD_MMC;
      Serial.printf(“Picture file name: %s\n”, path.c_str());

      File file = fs.open(path.c_str(), FILE_WRITE);
      if(!file){
      Serial.println(“Failed to open file in writing mode”);
      }
      else {
      file.write(fb->buf, fb->len); // payload (image), payload length
      Serial.printf(“Saved file to path: %s\n”, path.c_str());
      EEPROM.write(0, pictureNumber);
      EEPROM.commit();
      }
      file.close();
      esp_camera_fb_return(fb);

      // Turns off the flash
      pinMode(4, OUTPUT);
      digitalWrite(4, LOW);
      }

      Then, in the loop() fucntion, I asked it to call the take_picture() function every 60 seconds.

      void loop() {
      take_picture();

      // Wait 1 min
      delay(60000);
      }

      Reply
        • Hi Joel,
          You just need to copy the sketch presented in this tutorail here and delete the repeated lines which I encapsulated in the function.

          Also, in the setup() function, delete these lines below:

          “`
          rtc_gpio_hold_en(GPIO_NUM_4);
          delay(2000);
          Serial.println(“Going to sleep now”);
          delay(2000);
          esp_deep_sleep_start();
          Serial.println(“This will never be printed”);
          “`

          And nothing more! Rui and Sara did an excellent tutorial.
          Then you just need to upload the sketch and go ahead!

          Just let me know if you got any trouble.

          Reply
          • Hi Eduardo ;), when compiling the sketch it prints me on the serial port: “Camera capture failed” and does not save the photo in the sd, it is more I believe that it does not save it. I don’t know if you could help me with that ;).

          • Thank you friend, the esp32 cam already works and take the photos and save them :), I send you a hug and take care

          • You’re welcome!
            I’m glad that now it works.

            Any new ideias about how to extend this, feel free to ask or sugest. Just access the repo in the link that I sent before, and then open a new topic in the “issues tab” (the tab beside the selected tab, ” Code”);

            You don’t have to worry about it. New ideas are always welcome!

            Hugs for you too and take care!

    • Hi Joel,
      To access the pictures of the SDcard in a webpage, probably is the same way that you access in a web page a picture saved in the SPIFFS of the ESP32.

      I already made a web page which takes a picture every minute and saves it in the SPIFFS of the ESP32-CAM and shows it on the web page.
      When I buit it, I didn’t figured any solution to work with many names and, so, when the ESP32-CAM took a picture, it overwritten the last one and showed in the web page only the newest one.

      You can check this project here: https://github.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT

      Reply
      • I already reviewed your Eduardo project, but I don’t know if you know if there is any way to read the file in binary and send it to the server on request http and decode it and save it on the server.
        Or some other way to do the same, I would appreciate any suggestions 🙂

        Reply
        • Hi Joel,
          about reading the pictures in binary and sending/receiving it in http requests is a part beyond my knowledge… it is something in my wish list of next steps.
          If you know some place on web where teach this, I really will appreciate!
          Unfortunatelly this time I can’t help neither give any hints… but if you need anything else which I know or I which can find a solution more easily, don’t hesitate in asking me!

          Reply
      • Good afternoon.
        Very thank you for creating such a describe, am asking you suggest the what its feet on fare are free for organizations exchange data? “UnR” and “UOT” can not be used, since when the camera is working, so at 115200 speed technical information is sent to the port monitor, which makes the receiving side react to the data correctly. What two pins can I use to organize data transfer and how do I turn off the flash, since I do not need it, there is a sub-socket.

        Reply
  26. Good afternoon.
    Very thank you for creating such a describe, am asking you suggest the what its feet on fare are free for organizations exchange data? “UnR” and “UOT” can not be used, since when the camera is working, so at 115200 speed technical information is sent to the port monitor, which makes the receiving side react to the data correctly. What two pins can I use to organize data transfer and how do I turn off the flash, since I do not need it, there is a sub-socket.

    Reply
  27. Again, a Great tutorial! Code works fine…picture quality not the best, but, I bet soon they’ll come up with a camera with more megapixels.

    Reply
  28. Hi, I can’t include #include “esp_camera.h”, it tells me No such file or directory. What should I do? I’ve written to you several times. I use arduino 1.8.10 and can’t find it
    Huge App (3Mb no OTA), but no OTA (large APP) which one should I use? Thanks and congratulations for your wonderful and functional projects.

    Reply
  29. Bonjour,
    eh oui, un français ! (et en français)
    Tout d’abord MERCI pour vos trĂšs bons tutos !
    Petit problĂšme sur la dl_lib.h … qui n’existe plus :
    https://forum.arduino.cc/index.php?topic=637231.0
    New ESP32 Arduino version (v 1.03) remove this file “dl_lib.h” (and some others). Depending the sketch, probabily you can just remove this line because in the examples I have been used this library is beeing included but no method or function from this files is used.

    Reply
  30. Thanks for the tutorial! I did have a little trouble uploading my code to the ESP32, but after checking everything including the connections, ports. Checked the voltage I checked it all! On the final check, I found it, sometime during all my checking, I crossed the TX & RX connections, I wouldn’t have found if not for that final check. Thanks for what you do!

    Reply
  31. I had problem with brownout for the camerawebserver example. I tried adding the lines from this example to make it work but the board kept shutting down.

    I plugged 5V on the 5V pin on top of the 3.3V on the 3.3V pin, and it solved the problem. I just wanted to let you know.

    Thanks for your tutorials !

    Reply
  32. Hello everyone

    I would like to modify this example in order to catch a video and save it on the flash in 1min duration parts.
    when the flash card is full, the program delete the oldest video ans continue to record.
    If somebody can help me I will be gratefull
    regards

    Reply
  33. Great project..thanks for sharing work flawlessly..
    One question instead of pressing reset button to take picture, can we use momentary button and put the button outside. Use any free pin as button to reset and take picture..

    Reply
  34. thinking of a really cool mashup:
    – add a PIR sensor to the wakup pin
    – save the photo to SPIFFS (youtu.be/PAZUG7oSAwA)
    – send the photo over telegram (based on: instructables.com/id/Automation-With-Telegram-and-ESP32/ )
    – delete the photo from the SPIFFS (it is now in the archive at Telegram)
    – optionally: send a command from telegram to trigger the camera to take a photo (might have to disable the sleep mode then)

    Reply
  35. Hello everyone,
    Very interesting and useful project. It works very well. I would like to increase the number of photos taken (256) per SD card. Since I am not a programmer, I wonder if this is possible?

    Reply
      • Hi Sara and KR_edn,
        When there is no internet connection, the solution presented in this post restricts the maximum number for a picture name to 255 bacause the number of the picture is saved on 1 byte on the EEPROM memory.

        So, I ask the following question: when there is no internet connection, to save a higher number of pictures is it better to save two values in EEPROM (one number for 0 to 255 and the other one a letter form ‘a’ to ‘Z’) or save the number in a text file in SPIFFS or in SD card?

        Also, there are some restrictions about the length of the file names, or these just apply for the names saved in SPIFFS?

        Reply
        • That’s exactly what I meant to ask, but I probably didn’t express myself well. I want to save a large number of images to an SD card, as for my purposes I want to capture an image every 10-15 seconds. There is enough space on the SD card, I just run out of knowledge :).

          Reply
          • A very simple approach is a modification which I did of the project in this post and I’m sharing it on github: https://github.com/dualvim/BasicESP32-CAM

            Probably will do the job that you need KR_edn.

            This solution, the picture number ALWAYS STARTS IN 0. And then the value is incremented for each picture (and the maximum value is well beyond 255).

            The other solutions I told here involves other resources from the ESP32-CAM and makes the code a little larger than this one.

      • Hi Sara,

        I love your tutorials, used already some in my projects.

        To increase the number of pictures on the SD card without overwriting older ones, I’ve just I added a random number to the file name:

        // create a random nr of 4 digits
        int randomNumber = random(1000,10000);

        // Path where new picture will be saved in SD Card
        String path = “/picture” + String(pictureNumber) + “_” + String(randomNumber) + “.jpg”;

        The chance that the combination of the picturnr and the random number are the same twice is very small.

        Regards,
        Cor

        Reply
        • Hi.
          that’s an idea.
          You can also get date and time and include it in the name of the file.
          This way, you won’t have files with the same name.
          Regards,

          Sara

          Reply
  36. Hello Eduardo Alvim, my camera works exactly with your modified sketch “ESP-32_NoSleep”. However, when 254 images are stored on the SD card, the overwriting starts again with “0.jpg” …
    If I understand correctly, it is not possible to exceed the numbering of images up to 254 without concrete revision of the sketch?
    Is it possible to create predefined directories on the SD card, such as “DIR1”, “DIR2” … where the camera would store images DIR1 = 0-254, DIR2 = 255-510 … etc, which would of course be specified in the program by some command?
    Just thinking 🙂

    Reply
  37. Eduardo Alvim,
    thank you so much for this, this is it!!!
    Now, I can make some TimeLapse video width ESP32-CAM.
    Maybe just a small correction for someone like me:

    “line 210: pictureNumber = pictureNumber +1;”

    I wish you all the best and many more good projects, of course for Sara and Rui too.

    Reply
  38. I am unable to flash this code to ESP-32 CAM board.
    Tried to erase flash memory. The board is not connecting in both the cases.

    PS C:\Users\HP1> esptool.py erase_flash
    esptool.py v2.8
    Found 1 serial ports
    Serial port COM4
    Connecting…….._____….._____….._____….._____….._____….._____….._____
    COM4 failed to connect: Failed to connect to Espressif device: Invalid head of packet (0x48)

    A fatal error occurred: Could not connect to an Espressif device on any of the 1 available serial ports.
    PS C:\Users\HP1>

    Can you please help me out here ? Any fixes?

    Reply
  39. Hey,
    Thanks for the projekt and tutorial above. It works perfectly.
    Now I wanted my esp32-cam to take one picture every ten minutes and save it to the sd card. I thought/hoped, that it would work if i put your code just in the loop() with a delay of ten minutes and without the deep sleep. First it seems, that it would work, the camera took pictures (the LED flashes). But when I want access to the SD-Card on my PC it is not possible to watch the pictures “file or directory is corrupt and unreadable”. If I reformat the SD – Card the card is fine again.
    Does anyone know what is the problem/wrong? I used the same code as from above.
    Or do you know another way to take a picture every 10minutes and save them on a sd-card?

    Reply
  40. Hi
    Thanks for this project.
    How can I send the capture picture data by serial port TX in esp32-cam, also can I convert it to bmp directly before send it .
    I m trying convert it to serial data and send it to receiver and not save it in SD card
    so I use
    fb = esp_camera_fb_get();
    an replace
    file.write(fb->buf, fb->len); // payload (image), payload length
    by write.Serial(fb->buf, fb->len);

    the file.write will be on Arduino receiver.

    Thanks in advance.

    Reply
  41. Hi, you mentioned that esp32 cam doesn’t have many gpio pin.

    I’m just wondering what you think about using gpio extension?

    Would that be possible?

    Reply
  42. Can you please explain what is happening with this line of the program?

    camera_fb_t * fb = NULL;

    I can see it is a buffer in the psram. But I don’t understand more than that. Where is the size of the buffer determined? How is it setup?

    Reply
  43. Just a quick thing:
    The GPIO4 is used for the SD as well. On my board pushing reset somehow does not do a full power cycle and the pin is stuck low because of

    rtc_gpio_hold_en(GPIO_NUM_4)

    In any case I think it would be wise to add

    rtc_gpio_hold_dis(GPIO_NUM_4);

    at the top of the sketch. I guess quite a few people will modify this to wake up automatically from time to time to take a picture and in that case they will run into that issue as well.

    cheers

    Reply
  44. Hello Sara, very nice project. Is it also possible to use a normal push button instead of the reset button?
    What would I have to change about the sketch then?

    Many greetings Ulli

    Reply
  45. hello sara how are you ? can you help me please i have project like this project but i upload his code on esp32 cam and open serial have his message “rst:0x1 (POWERON_RESET),boot:0x2 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_FEO_V2))
    waiting for download
    ” please help me

    Reply
          • i do this ,I know you’re busy and you’re busy with me but you have any email or account in facebook to send photo of this message and connection of esp32 cam

          • After loading the program into your board, remove GPIO 0 from GND, open the Serial Monitor and press the RST button.
            That’s the solution for that issue.
            Regards,
            Sara

  46. I have been looking at using LoRa to transfer the pictures taken by an ESP32 CAM over long distances.

    As part of the testing I wanted a program so you could first see if the ESP32 CAM itself was long term reliable, could it repeatadly take pictures and save them to SD ?

    I modified the save to SD program so that the ESP32 CAM takes a picture, saves it to SD, and then goes into an xx seconds timed deep sleep. When it wakes it takes another picture and goes back to sleep again, etc.

    The code does work, but after its taken 206 pictures the microSD fails; ERROR – Failed to open file in writing mode.

    Now 206 is a wierd number really, so I restarted the ESP32 CAM and the next time it also failed after 206 pictures, and did the same a third time, always only 206 pictures.

    I editied the program to force it into no PSRAM mode;

    //if(psramFound()){
    //config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    //config.jpeg_quality = 10;
    //config.fb_count = 2;
    //} else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
    //}

    And again it takes 206 pictures and stops.

    Same on another ESP32 CAM module.

    Why only 206 pictures, any ideas ?

    (using the microSD in 1 bit mode)

    Reply
    • Hi.
      I’m not sure if it is related to the SD card or with the fact that we’re saving the picture number on the EEPROM in this particular example.
      Are you also using EEPROM in your example?
      As you’re using deep sleep, you can save the picture number using the RTC memory as mentioned in this tutorial: https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/
      Alternatively, you can save the picture number permanently in a file in SPIFFS or using the ESP32 Preferences library.
      Regards,
      Sara

      Reply
      • Picture number, and wake up number are going to RTC memory, that seems to be working OK.

        The sleep number increases, beyond 206, but the picture number does not since that only increases if a picture is taken and saved to SD.

        Reply
  47. Looks like a FAT16 issue on the SD card, thats the format the SD Association SD card utility (often recommended for Arduino use) uses.

    If the filenames are bigger than 8.3, such as ‘Picture200.jpg’, the number of files allowed in a directory is reduced, it seems in this case to 206.

    Just running it now on a FAT32 formatted SD, will report back.

    Reply
  48. Reporting back.

    Does look like issues with SD card format, with the card as FAT32, the picture count is now up to 816+.

    Now back to the picture transfer stuff ……………..

    Reply
  49. There ought to be a law against tutorials like this, how can an error like this occur:

    core\core.a(main.cpp.o):(.literal._Z8loopTaskPv+0x8): undefined reference to loop()'
    core\core.a(main.cpp.o): In function
    loopTask(void*)’:
    C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/main.cpp:21: undefined reference to `loop()’
    collect2.exe: error: ld returned 1 exit status

    How can an undefined reference not show up in the testing? Does your computer have something mine doesn’t and if so what is it?

    Reply
    • Hi.
      That error happens because you didn’t copy the last lines of the code that include the loop().
      Make sure you copy the whole code provided.
      Regards,
      Sara

      Reply
  50. Hello, excellent tutorial, it works perfectly. Now I want to send the photo saved in the SD and send it by TX to another device, is it possible to do it? Could you guide me how to do it? Thank you very much for your time.

    Hola, excelente tutorial, funciona perfectamente. Ahora quiero enviar la foto guardada en la SD y enviarla por TX a otro dispositivo, es posible hacerlo?,podrias orientarme como hacerlo?, desde ya muchas gracias por tu tiempo

    Reply
  51. Hello! Great job you are doing!
    When I verify the sketch it gives me this error: ImportError: No module named serial. I have selected the AI Thinker ESP32-CAM board. Help!!!
    Thank you.

    Reply
  52. Hi Sara, thank you for the great tutorial it worked perfectly. If you don’t mind, may I know how to transfer the image in SdCard to computer by using Bluetooth Module?

    Reply
  53. I am going to revisit the page and I love the tutorials you guys make. First of all I am suffering to get the solution to my Time-lapse setup. I didn’t want the Esp-32 module to connect to wifi and if the reset button is pressed means it will continuously take the time lapse photos as per we define it to do so. Like when I press the reset button it should start taking photos in some interval with the quality and other aspect settings.
    Please help me out! A simple sentence for the solution will do the work, or you can make a video for this if you feel good to.

    Thanks in advance,
    Kumar

    Reply
  54. Great Tutorials, slowly working my way through all of them.

    About to post a message saying the SD card failed to mount .

    Then I noticed the SD card had come out!

    Onto the next one.

    Reply
  55. Does anybody know of a programmer’s reference guide for this esp_camera library?

    These tutorials are fine for an overview, but without knowing all the functions which are available make it difficult to expand out on your own or come up with a better way to do things.

    I mean, I can pick apart the driver code, but would rather have something pre-written.

    Reply
  56. Although I did love this one, and it was one of my first programs on ESP32-CAM, I’ve found that you could do the pictures in darker areas as well. Although it takes a little bit of tweaking of camera settings themselves. I might to a follow up on it

    Reply
  57. Hello Sara, I built this project. I use the MB board with USB connection.
    Program loaded went without errors. I then started the Serial Monitor and I get the following error message:
    Initializing the camera module…Ok!
    Initializing the MicroSD card module… Booting the SD card
    Failed to mount SD card

    What am I doing wrong?
    Greetings Ulli

    Reply
    • Hello, I built this project. I use the MB board with USB connection.
      Program loaded went without errors. I then started the Serial Monitor and I get the following error message:
      rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
      configsip: 0, SPIWP:0xee
      clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
      mode:DIO, clock div:1
      load:0x3fff0018,len:4
      load:0x3fff001c,len:1216
      ho 0 tail 12 room 4
      load:0x40078000,len:9720
      ho 0 tail 12 room 4
      load:0x40080400,len:6352
      entry 0x400806b8
      [E][camera.c:1344] esp_camera_fb_get(): Failed to get the frame on time!
      Camera capture failed

      What am I doing wrong?
      Greetings Ulli

      Reply
  58. Hello,
    I’m running into a couple of curious issues. When I select AI Thinker ESP32-CAM board, the port speed selector disappears.

    I’m able to successfully upload the sketch, but I see this in the console output:

    esptool.py v3.1
    Serial port /dev/ttyUSB0
    Connecting…..
    Chip is ESP32-D0WDQ6 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    Crystal is 40MHz
    MAC: 0c:b8:15:f5:66:f0
    Uploading stub…
    Running stub…
    Stub running…
    Changing baud rate to 460800

    After the upload, the serial monitor displays: ……………………………..

    I believe the problem is that port speed 460800 is not available in board setup.

    Any suggestions?

    Thanks

    Reply
  59. Hey,

    I am working on same task but instead i am saving grayscale image ut it seems it is not working in case of grayscale image. it seems it is not saving the image in spiffs file system and then not showing it on weserver. can you please share your thought on that?

    greetings
    Mayur

    Reply
  60. Hi Sara,
    These tutorials are extremely useful and easy to follow.
    I am trying to design a device that uses the ESP-32 Camera to take a picture, but I want it to take a photo only when it receives a signal.

    I have tried modifying the code to use one of the GPIO input pins so that when it is turned high, it will take a photo and save to SD card, in the same way that happens now when the reset button is pressed, but I am having issues.

    Do you know any idea if this is possible? Which GPIO is available to use as an input if I am using the SD card at the same time?

    Reply
      • Hi Sara,

        Thank you for the fast reply. This was the modification of the code that I was using, but I wanted to use an impulse to drive the photo, instead of a push button. Do you have any idea why this might not work?

        I was using an Arduino 5v Output Pin to send a 5V signal to the GPIO 16, and when it receives that signal it should take a photo. However, it was not working as intended. I checked that the 5V from the Arduino was coming when I expected it to, but it doesnt take a photo for some reason.

        I tried programming it in the same way as the pushbutton works, since it receives a HIGH/LOW signal from the GPIO 16, though I was not having any success.

        Reply
  61. Great Tutorial🙂. Can I save esp32cam pic inside itself with no using external sd card. As the buffer in esp32cam is storing that image buffer right ?

    Reply
  62. Great Tutorial! I got some thing strange, my SD card works well and be able to save pictures, but can’t be read and need be formatted every time after pull out from ESP32CAM, what’s wrong?

    Reply
  63. Very good explanation!
    I have a problem. I can’t insert the mini connector into its housing.
    I don’t want to force the insertion and ruin it.
    Is there a system?
    Thanks

    Reply
    • Hi.
      What is the ESP32-CAM model you’re using?
      What connector are you referring to? The USB connector? Check that you’re using the right USB connector for the board you’re using.
      Regards,
      Sara

      Reply
  64. hey talk to me , I took an esp32s3 cam, and used a part of your code, you takes a lot of wave in yours projects, but I’m having a problem, when I activate the timelapse, it saves the photos but after a while it starts to give error in writing the card, I’m using the SD_MMC library, do you know some of a solution?

    Reply
  65. I’ve followed this project and installed everything as per the course here, at least as far as I can see and check. Unfortunately I’m constantly getting “Camera capture failed”. I’ve double checked everything also reformatted the SD card (I’m also not getting any error at boot) but no success. What I’m I doing wrong? I’ve tested to boot without SD card and I get the expected error and all that. Booting also says “Camera OK”, SD card mounted
 everything as expected. When pressing the reset button I get path and picture name on the serial monitor but then after a short moment the last line “Camera capture failed”. What am I missing?

    Thanks
    Hans

    Reply
    • Hi.
      Are you using an ESP32-CAM AI Thinker or another board?
      Double-check your power source.
      Is your camera properly connected to the board?
      The camera might not be properly connected or it might be broken.
      Regards,
      Sara

      Reply
  66. The output from the serial monitor:
    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    16:49:42.425 -> configsip: 0, SPIWP:0xee
    16:49:42.425 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    16:49:42.425 -> mode:DIO, clock div:1
    16:49:42.425 -> load:0x3fff0030,len:1344
    16:49:42.425 -> load:0x40078000,len:13924
    16:49:42.425 -> ho 0 tail 12 room 4
    16:49:42.425 -> load:0x40080400,len:3600
    16:49:42.425 -> entry 0x400805f0
    16:49:43.065 -> Initializing the camera module…Camera OK!
    16:49:43.315 -> Initializing the MicroSD card module… Mounting MicroSD Card
    16:49:43.559 -> Picture file name: /image42.jpg
    16:49:47.546 -> Camera capture failed
    16:49:47.546 -> Entering sleep mode

    Reply
    • I had a similar issue here. I don’t know why, but the ov2640 camera which came with my ESP32-CAMs stoped working. I tryed to downgrade the Arduino ESP32 board library and many other things. I just saw this issue solved when I bought a new OV2640 camera and attached it on my ESP32-CAM.

      Reply
  67. Hi,
    a very nice project – but I have a problem: After uploading your raw code on my AZ-Delivery AI-Thinker module (the FTDI adapter is still in place for 5V power supply/communication; GND_IO0 are disconnected) the Serial Monitor (SM) responds after the 1st RESET:

    ets Jul 29 2019 12:21:46

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1044
    load:0x40078000,len:10124
    load:0x40080400,len:5856
    entry 0x400806a8
    âžźPicture file name: /picture51.jpg
    Saved file to path: /picture51.jpg
    Going to sleep now

    (2nd RESET to take picture)

    ets Jul 29 2019 12:21:46

    rst:0x1 (POWERON_RESET),boot:0x3b (SPI_FAST_FLASH_BOOT)
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    ets Jul 29 2019 12:21:46 After the 2nd RESET this block is continuously repeated!
    .
    rst:0x10 (RTCWDT_RTC_RESET),boot:0x3b (SPI_FAST_FLASH_BOOT)
    invalid header: 0xffffffff
    invalid header: 0xffffffff
    invalid header: 0xffffffff Here I swiched power off/on (Picture 52)
    Picture file name: /picture53.jpg Power off/on: Picture 53
    Saved file to path: /picture53.jpg
    Going to sleep now Power off/on (Picture 54)
    Picture file name: /picture55.jpg Power off/on: Picture 55
    Saved file to path: /picture55.jpg
    Going to sleep now Power off/on (Picture 56)
    Picture file name: /picture57.jpg Power off/on: Picture 57
    Saved file to path: /picture57.jpg

    In summary, after the 2nd RESET (to take a picture) an “invalid header” block with a different boot address (0x3b compared with the 1st reset) is continuously repeated on SM, no picture is taken. But, switching the power off and on (by my hub, only FTDI and ESP32cam are connected), pictures are taken together with LED-flash. The SM documents only each second picture, but all pictures 53,54,55,56,57 are stored to SD.
    I use Arduino IDE 1.8.13 and for the board manager ESP32 by Espressive Sys. Vers. 1.0.6 (same problem occurs with Vers. 1.0.4).
    In addition, I noticed that the picture number is stored irrespective of a new upload (even of a different sketch). Is there a way to reset numbering? Please help me!
    Christian

    Reply
  68. Hello
    First of all thank you for guidance. But I am facing some issue when I capture the image the image captured comes with greenish tone
    I want to take proper pic so that I can read RGB value

    Reply
  69. Hello every one 😉

    Here after a simple exemple to show how to hold a GPIO on even during deep sleep !
    Here the output 4 (flash LED on the camera)

    #include “driver/rtc_io.h”

    unsigned long previousMillis = 0;
    const long INTERVAL = 5000; // 5s of LED blinking duration
    int LED = 4;

    void setup() {
    Serial.begin(115200);
    rtc_gpio_hold_dis(GPIO_NUM_4); // !!! important otherwise the LED will alway stay on after 1st deep sleep !!!
    pinMode(LED, OUTPUT); //Init flash LED connected to GPIO 4
    Serial.println(“Start to blink the flash LED for 5s”);
    }

    void loop(){
    digitalWrite(LED, HIGH); // turn the LED on
    delay(50); // 50ms ON
    digitalWrite(LED, LOW); // turn the LED off
    delay(450); // 450ms OFF
    if (millis() – previousMillis >= INTERVAL)
    {
    previousMillis = millis();
    digitalWrite(LED, HIGH); // turn the LED on during deep sleep
    Serial.println(“Going to deep sleep for 10s”);
    rtc_gpio_hold_en(GPIO_NUM_4); // LED will stay on also during deep sleep !!!
    ESP.deepSleep(10e6); // deep sleep for 10s
    Serial.println(“Going out of deep sleep”); // will be never printed !!
    }
    }

    Reply
  70. Dear !
    When compiling a sketch (I haven’t even connected the board yet), it gives this error –

    Backtracking (the most recent call):
    File “esptool.py “, line 31, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “esptool__init__.py “, line 41, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “esptool\cmds.py “, line 14, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “esptool\bin_image.py “, line 14, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “esptool\loader.py “, line 30, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “serial__init__.py “, line 29, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “serial\serialwin32.py “, line 15, in
    File “PyInstaller\loader\pyimod02_importers.py “, line 352, in exec_module
    File “ctypes__init__.py “, line 7, in
    ImportError: failed to load DLL when importing _ctypes: ???????? ????? ???????.
    [5088] The ‘esptool’ script could not be executed due to an unhandled exception!
    Pyserial is not set for C:\Users\Serj\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4 .5.1\esptool.exe . For installation instructions, see the README.
    exit status 1

    What is my mistake ?

    Reply
  71. Hallo Sara, nach lÀngerer Pause habe ich ein Projekt von Euch (Take Photo and save to SD Card with Pushbutton) gefunden und nachgebaut. GrundsÀtzlich lÀuft es. Ich habe nur das Problem, dass das erste Foto sehr schön wird und die folgenden Fotos immer nur teilweise abgespeichert wird.
    Ich habe schon eine andere SD-Card ausprobiert und auch neu formatiert. Ist aber immer wieder das gleiche Ergebnis. Ich habe auch nach jedem Foto eine lÀngere Pause gemacht.
    Woran könnte es liegen?
    Viele GrĂŒĂŸe ULLI

    Reply
  72. hello I have a problem like this:

    rst:0x1 (POWERON_RESET),boot:0x1a ets Jul 29 2ASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:1344
    load:0x40078000,len:13964
    load:0x40080400,len:3600
    entry 0x400805f0
    E (836) sdmmc_sd: sdmmc_init_sd_scr: send_scr (1) returned 0x107
    E (837) vfs_fat_sdmmc: sdmmc_card_init failed (0x107).
    SD Card Mount Failed

    maybe someone can help me on this

    Reply
  73. Hello, I am facing a problem while interfacing the camera with the custom board.
    I am using the ov5640.
    I am using the esp32-D0WD-V3 controller.
    These are the camera pins
    #define XCLK_GPIO_NUM 4
    #define SIOD_GPIO_NUM 18
    #define SIOC_GPIO_NUM 23
    #define Y9_GPIO_NUM 36
    #define Y8_GPIO_NUM 37
    #define Y7_GPIO_NUM 38
    #define Y6_GPIO_NUM 39
    #define Y5_GPIO_NUM 35
    #define Y4_GPIO_NUM 14
    #define Y3_GPIO_NUM 13
    #define Y2_GPIO_NUM 34
    #define VSYNC_GPIO_NUM 5
    #define HREF_GPIO_NUM 27
    #define PCLK_GPIO_NUM 25
    power down and the reset pin is connected to the io expander (uses I2C).

    I’d like to tell you that my task is to take a picture and store it in the SD card.

    is this camera compatible with this controller esp32-D0WD-V3?

    Can power down and reset the pins be implemented through the io expander?
    if this is possible to implement I cannot able to navigate the c file related to this.

    Reply
  74. This does not work with seeed esp32s3 sense.

    output is a loop printing this:

    20:44:18.637 -> ESP-ROM:esp32s3-20210327
    20:44:18.637 -> Build:Mar 27 2021
    20:44:18.637 -> rst:0x3 (RTC_SW_SYS_RST),boot:0x28 (SPI_FAST_FLASH_BOOT)
    20:44:18.637 -> Saved PC:0x40377234
    20:44:18.637 -> SPIWP:0xee
    20:44:18.637 -> mode:DIO, clock div:1
    20:44:18.637 -> load:0x3fce3818,len:0x109c
    20:44:18.637 -> load:0x403c9700,len:0x4
    20:44:18.637 -> load:0x403c9704,len:0xb50
    20:44:18.637 -> load:0x403cc700,len:0x2fe4
    20:44:18.637 -> entry 0x403c98ac

    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.