Time-lapse Image Capture with ESP32 Cameras


Three ways to shoot time-lapse videos from an ESP32 based camera system such as the ESP32-Cam and the ESP-EYE

This tutorial will explain how to use JavaScript to capture images, how to capture and write images to an microSD card reader and also how to capture and send images to a server on the internet. Using one of these techniques you can make time-lapse videos such as these:

Before following this tutorial make sure your camera and Arduino IDE are set up correctly by following this tutorial Ai-Thinker ESP32-CAM in the Arduino IDE

Time-lapse Capture via JavaScript

This is the easiest way to capture time-lapse images from your camera. It works using JavaScript in a web page to request a new image from the camera at an interval you choose.

JavaScript Version Screenshot

Download JavaScript Time-lapse

Paste the script above into a new Sketch and upload it to your device. Reset the device, look for the IP address in the Serial Monitor and connect to that IP address with your browser.

You can speed up or slow down the speed of the capture using the slider during the process.  When the capture has completed use the ‘Save page as’ menu or Ctrl+s to save the images.

This method doesn’t work it you want to capture thousands of frames because the browser won’t save everything if there are too many images.


Capture to the SD Card

The Ai-Thinker has a built-in Micro-SD card reader. This Sketch captures an image at the interval set in the Sketch and saves it to the SD card. If there is an available internet connection the Sketch retrieves the time from the internet and uses this in the filename. If there is no connection, files are named numerically. Be aware that without internet, if the device restarts it will begin overwriting existing files.

Download MicroSD Card Time-lapse

The card must be formatted to FAT32 and be 4GB or less. For some reason the ‘flash’ LED on the front is connected to one of the SD card pins so it glows brightly every time a file is written. I ended up putting black tape over it.


Upload a Capture to a Server

This the most complicated approach but once working, it’s the easiest to manage and keep an eye on progress. Every time an image is captured it is sent to a server via http POST for saving. This would make an ideal solution for an online web cam.

Download Time-lapse to Server

Some simple PHP to name and copy the uploaded image to a folder:

$received = file_get_contents('php://input');
$fileToWrite = "timelapse/upload - ".time().".jpg";
file_put_contents($fileToWrite, $received);


Making the time-lapse video

This is the easiest to follow guide I found to make the time-lapse video from your images: https://www.youtube.com/watch?v=JwF6I0iLGS4


Time formatting: http://www.cplusplus.com/reference/ctime/strftime/
Code for SD card: https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card
Tips for making time-lapse videos: http://www.enriquepacheco.com/10-tips-for-shooting-time-lapse/

20 Replies to “Time-lapse Image Capture with ESP32 Cameras”

  1. Vicente says:


    Congratulations for your post, I’ve tried all the moldes and I have problems with the “Upload a Capture to a Server” model. I never get any picture in the server
    This is the message in the serial monitor.
    Can you please let me know what i’m doing wrong?
    Thank you for your help
    Taking picture…

    HTTP_EVENT_ON_HEADER, key=Date, value=Tue, 14 May 2019 20:11:51 GMT
    HTTP_EVENT_ON_HEADER, key=Server, value=Apache
    HTTP_EVENT_ON_HEADER, key=Vary, value=Accept-Encoding
    HTTP_EVENT_ON_HEADER, key=Content-Length, value=145
    HTTP_EVENT_ON_HEADER, key=Content-Type, value=text/html; charset=UTF-8
    HTTP_EVENT_ON_DATA, len=145
    esp_http_client_get_status_code: 200

    1. WordBot says:

      It looks like it’s working on the ESP32. Do you have an error log on the server?

  2. Mile says:

    Terrific programs!

    Question 1: Is there a mechanism to switch off the “flash” led?
    I’ve been scanning the ESP-CAM schematic and driver code. It seems to be driven by HS2_DATA1 GPIO4? but I cannot find who turns it on.
    Question 2: Do you know of a mp4 recorder onto sd card program? Or is that possible with this chip/cam combo?


    1. WordBot says:

      Thanks! DATA1 is one of the SD card data lines so whenever data is written the LED lights up. I don’t know how it still writes data when this is happening! I’ve looked into MP4 but not found anything yet.

  3. Mike says:

    Wow – that’s crazy. You are running a camera, and there is a giant white led flashing on and off as the “disk active” light — interfering with the camera if you take another picture before the write is done. It is marked “flash” on the schematic, but is does not turn on with the camera, but after the picture, during the write — so it is clearly not a flash to use in low light.

    There is a small led on the back that might be better used as “disk active” light.
    I see a small transistor marked J3Y just above the big led — i think there is room to de-solder that.

    I haven’t done it before, but I might try to grab some raspivid code, and write a video recorder.

    Thanks for the info.

  4. Najib says:


    Thank you for your script. I try upload a capture to the server with time lapse. In the serial monitor there are message:

    HTTP_EVENT_ON_HEADER, key=Date, value=Mon, 01 Jul 2019 13:34:27 GMT
    HTTP_EVENT_ON_HEADER, key=Server, value=Apache/2.4.25 (Raspbian)
    HTTP_EVENT_ON_HEADER, key=Content-Length, value=0
    HTTP_EVENT_ON_HEADER, key=Content-Type, value=text/html; charset=UTF-8
    esp_http_client_get_status_code: 200
    Taking picture…

    but it’s like vicente’s problem, i cant find the picture. Are you have php script completely? Where i put the folder name which is the picture placed?

    Thank you

    1. WordBot says:

      Hi, You might have to create a folder called timelapse in the same folder as the PHP script. Do you know PHP?

  5. Najib says:

    i got it, thank you so much.

  6. Roberto says:

    Thank for your code,I used the last example and it works perfectly!
    I would like to know if it possible to upload picture to server only when it detects some change on environment..is it possible to implement? thank you again!!

    1. WordBot says:

      Hi, I’m working on movement detection in the video field at the moment. It’s easy with a PIR sensor but you need a different board for this: https://robotzero.one/ttgo-security-camera-pir/

  7. Rizki Adi Saputra says:

    THANKS BRO!!!!
    CODE WORK 100% PERFECTLY ON MY ESP32 CAM! with esp to server method.
    searched this method for 3 days!

    1. WordBot says:

      No problem. I’m happy it worked for you. Feel free to mention the tutorial on Facebook etc so more people can find it.

  8. Roberto says:

    Hi again!
    I had an issue today without a clear explanation..the server code does not work anymore..inside the loop function it does not call take photo because the millis condition is never satisfied..so I used delay and it works but I don’t know why everything was working and suddenly not..probably is the millis?
    I do not understand!

    1. WordBot says:


      What value do have for capture_interval?

      The millis code below should be OK AFAIK. millis() is the time since the ESP32 was started so the first few loops you’ll get something like 10 – 0, 20 – 0, 30 – 0 for current_millis – last_capture_millis. If you have capture_interval at 20000 (20 secs) when the millis hit 20010 (for example) it should make last_captured_millis equal to 20010 and take a photo.

      current_millis = millis();
      if (current_millis – last_capture_millis > capture_interval) { // Take another picture
      last_capture_millis = millis();

      The problem with delay() is that it stops everything for that number of milliseconds so if your application takes 2 seconds to complete (in this case taking and sending a photo) you are actually taking a photo every 22 seconds. Things get really random timings if you have a short delay.

  9. Vicente Tomás says:

    Congratulations for your post. Is it possible to use the sd library (SD.h) instead the Sdmmc?
    Thank you.

    1. WordBot says:

      Thanks! I’m not sure.. I remember something about the Arduino library for SD cards using a different connection method (i2C or SPI) to the Espressif driver I used.

  10. Christoph says:

    Unfortunately I have no experience with PHP. Is this code

    $received = file_get_contents(‘php://input’);
    $fileToWrite = “timelapse/upload – “.time().”.jpg”;
    file_put_contents($fileToWrite, $received);

    the complete content of the yourscript.php file? Or is at the end missing?

    Thanks for your answer!

    1. WordBot says:

      Hi, Yes, you need to enclose the code in tags like this:


      The end one is optional

  11. Christoph says:

    Thought so. Thanks for the clarification!

    Another question: Is it possible to upload the images to a web server without using PHP? It is not necessary to number the images. It is sufficient to save an image and overwrite the last saved one.
    Like: const char *post_url = “http://your-webserver.net/img.jpg”; // Location where images are POSTED

    I try to build a camera (as a part of a doorbell) that takes a picture after pressing a button and uploads it to a webserver (without PHP). The previously captured image should be overwritten.

    1. WordBot says:

      I can’t think of any way of doing this from the ESP32. You have to send the data (image) somewhere that can process it (save it as a file in this case). Maybe you could email the image https://github.com/mobizt/ESP32-Mail-Client or https://github.com/gpepe/esp8266-sendemail (see issues for fixes) ?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top