ESP32 CAM example expanded

A nicer example of a ESP32 CAM webserver, based on the Espressif example, but more user-friendly.

Similar projects worth following
This sketch is a extension/expansion/rework of the ‘official’ ESP32 Camera example sketch from Espressif:

The example they have is nice, but a bit incomprehensible and hard to modify as supplied. It is very focused on showing off the face recognition capabilities, and forgets the ‘webcam’ part. There are many other variants of a webcam server for these modules online, but most are created for a specific scenario and not good for general, casual, webcam use.

Hopefully this expanded example is more useful for those users who wish to set up a simple ESP32 based webcam using the cheap(ish) modules freely available online. Especially the AI-THINKER board:

AI-THINKER ESP32-CAM and Other Modules:

I have four AI-THINKER ESP32-CAM boards, so the descriptions below are for that board. But I took care to leave the default definitions and controls for other boards in the example intact. You may need to adjust the programming method to suit the your board, look for examples online.

My Modifications:

The basic example is extended to allow control of a high power LED FlashLamps, which are present on my modules. It can also blink a status LED to show when it connects to WiFi.

The WiFi details can be stored in an (optional) header file to allow easier code development, and a camera name for the UI title can be configured. The lamp and status LED's are optional, and the lamp uses a exponential scale for brightness so that the control has some finess.

The compressed and binary encoded HTML used in the example has been unpacked to raw text, this makes it much easier to access and modify the Javascript and UI elements. Given the relatively small size of the index page there is very little benefit from compressing it.

I have left all the Face Recognition code untouched, it works, and with good lighting and camera position it can work quite well. But you can only use it in low-resolution modes, and it is not something I will be using.

The web UI has had minor changes to add the lamp control (only when enabled), I also made the 'Start Stream' and 'Snapshot' controls more prominent, and added feedback of the camera name + firmware.


  • I only have AI-THINKER modules with OV2640 camera installed; so I have only been able to test with this combination. I have attempted to preserve all the code for other boards and the OV3660 module, and I have merged all changes for the WebUI etc, but I cannot guarantee operation for these.
  • I created a small board with a handy switch for power, a pushbutton for the GPIO0 programming switch, and a socket for the AI-THINKER board. This proved very useful for development work and programming multiple devices.
  • I found some excellent cases on Thingieverse.


  • Improve Wifi, add a captive portal for setup and fallback, better disconnect/reconnect behaviour.
  • The module has a SD/TF card slot; this is currently unused, but I would like to add the ability to store snapshots; recording Video at low resolution may be possible, but the card interface is too slow for HD video as far as I know.
  • Remove face rcognition to save a Mb+ of code space and then implement over the air updates.
  • Combine current split html pages (one per camera type) into one which adapts as needed.

Zipfile for the Win

Zip Archive - 1.28 MB - 04/07/2020 at 22:15



Gzip for the Geeks

gzip - 1.27 MB - 04/07/2020 at 22:15


  • 1 × ESP32 CAM Lots of models available...

  • Remote Access

    Owen11/20/2019 at 14:33 0 comments

    There is something weird happening when I try and proxy through Apache to the cameras (or remote (*) access  I get:

    Header fields are too long for server to interpret

     This is coming from the ESP itself; needs more debug.

    (*) A simple http proxy with basic authentication enabled, it works for some other tools including a ESP32 based CNC controller, but not for this. Strange.

View project log

  • 1
    Setup, gather components

    For programming you will need a suitable development environment, I use the Arduino IDE, but this code should work in the Espressif development environment too.

    Follow This Guide to set up the Espressif Arduino core in the IDE.

    The AI-THINKER board requires use of an external 3.3v serial adapter to program; I use a FTDI Friend adapter, for more about this read AdaFruits excellent FTDI Friend guide.

    Be careful not to use a 5v serial adapter since this will damage the ESP32.

  • 2

    Hooking this up is pretty simple, see the diagram below. 


    Connect the RX line from the serial adapter to the TX pin on ESP32

    The adapters TX line goes to the ESP32 RX pin

    The GPIO0 pin of the ESP32 must be held LOW (to ground) when the unit is powered up to allow it to enter it's programming mode. This can be done with simple jumper cable connected at poweron, fitting a switch for this is useful if you will be reprogramming a lot.

    You must supply 5v to the ESP32 in order to power it during programming, the FTDI board can supply this.

  • 3

    Download the code from the Files section here, or clone the GitHub repo.

    You need to set the Board you are using in the main esp32-cam-webserver.ino sketch file, it defaults to the AI-THINKER, but the WRover Kit, ESP Eye and M5Stack are also availiable.

    You can also set the camera name plus SSID and password for your WiFi network in that file, or follow the notes about using a separate file for your settings.

View all 5 instructions

Enjoy this project?



Jassim Ali wrote 04/18/2020 at 02:37 point

first I would thank u for this amazing alternative, and I was looking for something like this urgently, I think the face recognition is useless on this cam, and I was looking to make an FPV robot that is connected to the WIFI and be able to access the stream remotely. it will be nice to make a (bare bone) version, that is light and require less computation, since the camera gets rely hot using the standard sketch. BTW, How can I change the defult server port (80) ? I tried so many lines but with no avail. all what I could do is change the lines in app_httpd file to this 

    config.server_port =***;
    config.ctrl_port = ***;

*** = my new port

this changed the streaming server but not the web server.

and If I entered the web server, I can take still pictures but not live stream. 

any suggestions ?


I added lines in the main code before the setup function to creat a static IP as :

IPAddress local_IP(192, 168, 8, 203);
IPAddress gateway(192, 168, 8, 1);

IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 8, 1); 
IPAddress secondaryDNS(192, 168, 8, 1); 

  Are you sure? yes | no

bentech4you wrote 04/04/2020 at 22:16 point


i would like to add overlay text(live temperate and humidity) to the video, is that possible?

  Are you sure? yes | no

Owen wrote 04/07/2020 at 21:37 point

Unfortunately this cannot be done directly in the stream output (for the same 'not enough cpu/ram' reasons that stops rotation etc).

But, as with the rotation setting, this could be applied in the browser window via an overlay pretty easily.  I have no plans to do anything about this myself, but if anybody wants to give it a go and submit a PR on GitHub I'd be interested.

  Are you sure? yes | no

al wrote 01/21/2020 at 19:30 point


I tried your sketch on an ESP32-CAM from a Cinese vendor "DIY MORE" which looks identical to the AI-THINKER. I can see the camera dashboard in my browser but the serial monitor shows the following error...

"[E][camera.c:1344] esp_camera_fb_get(): Failed to get the frame on time! Camera capture failed"

Any idea as to what is causing the failure?


  Are you sure? yes | no

Owen wrote 04/07/2020 at 21:33 point

Sorry for slow reply, that error comes from the Expresssif libraries; Google is your friend:

See the comment here:

And the page here repeats that; and has a load more advice too!

  Are you sure? yes | no

Owen wrote 04/07/2020 at 22:13 point

I have now added a pins definition to the code (in pins.h) for non-psram modules that get this error when run with the standard examples.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates