Manage cookies

We use cookies to improve our services. Read more about how we use cookies and how you can refuse them.

The necessary cookies help to make the website work properly.

Anonymous statistical cookies help to understand how visitors use the website.

  • MicroPython
    6 min | 73803

    #MicroPython: Taking photos with an ESP32-CAM

    MicroPython | 6 min | 73803

    Last year, I bought an ESP32-CAM board from Banggood and I wanted to use it with MicroPython. The board has an OV2640 without any chip (buffer) between the ESP32 and the camera. There are many implementation for Arduino or directly using Espressif, but I wanted to use MicroPython. Thus, the only solution was to use the I2S interface, but I didn't have time to write the driver. Thus, I put the project on hold. However, last week I was searching between the ESP32 boards that I have, I found the board again, and I also found that tsaarni has written the driver for MicroPython.

    This tutorial is about compiling and deploying a version of MicroPython with support for I2S on the ESP32-CAM. Additionally, I included a project with a webserver to take and see the photo. Moreover, I uploaded the compiled firmware, so that you can directly deploy MicroPython with camara support on the board and take photos. The repository of tsaarni has a wiki with instructions, but some steps are not easily to understand and I had some issues with them. Thus, I write the steps again and added more information in this article.

    Fig. 1: Photo taken with the ESP32-CAM running MicroPython

    Hardware & Software

    In the following table, you find the hardware and software that you will use for this tutorial:

    There are two new articles about this topic:Check out those, before you keep reading this article and instructions.


    I uploaded the compiled firmware into the following repository: lemariva/uPyCam. You can deploy the firmware typing the following on a terminal: --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-cam-micropython.bin

    However, if you want to, you can compile MicroPython yourself. To start with this, you need the following dependencies on your development machine:

    # linux
    sudo apt-get install python3-pip
    pip3 install virtualenv

    On Windows, follow this article to install pip and install virtualenv with pip install virtualenv.

    Then, put everything you need inside a folder:

    mkdir micropython
    cd micropython

    and start a virtualenv inside that folder to install the dependencies:

    # linux
    . venv/bin/activate
    # windows
    pip3 install pyserial pyparsing
    If you want to, you can also install pyserial and pyparsing as an user or root package. Then, you don't need to install or activate any virtual environment. Just install python3-pip and then the packages using pip3 install pyserial pyparsing.

    Espressif IoT Development Framework (ESP-IDF)

    To compile MicroPython for the ESP32-CAM, you need to setup the Espressif IoT Development Framework (ESP-IDF). This can be done typing the following:

    git clone
    git checkout <current supported ESP-IDF commit hash> 
    git submodule update --init

    You need to look for the right commit hash that is compatible with the current MicroPython version. To do that, look for the Makefile in the MicroPython repository. This is now located here: micropython-with-esp32-cam/ports/esp32/Makefile. At the moment of writing this article, the supported hash is the following:

    # the git hash of the currently supported ESP IDF version
    ESPIDF_SUPHASH := 5c88c5996dbde6208e3bec05abc21ff6cd822d26

    Or go to the folder micropython-with-esp32-cam/ports/esp32 and type make without having a configured ESP-IDF, you'll get something like:

    Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
    ** WARNING **
    The git hash of ESP IDF does not match the supported version
    The build may complete and the firmware may work but it is not guaranteed
    ESP IDF path:       /home/riva/esp/esp-idf
    Current git hash:   3eecd43b31a765aae0231ff9a227786bac31b9a2
    Supported git hash: 5c88c5996dbde6208e3bec05abc21ff6cd822d26

    Thus, the above git checkout line changes to: git checkout 5c88c5996dbde6208e3bec05abc21ff6cd822d26.

    Some other requirements are needed depending on your OS. Check the prerequisites to install them.

    Then, type the following on a Terminal:

    export ESPIDF=$MICROPYTHON/esp-idf


    You can download the toolchain from here: Compiled Toolchain. They are legacy files but they still work. Or you can compile the toolchain with the following (Linux - requirements):

    git clone
    cd crosstool-NG
    git checkout esp32-2019r1
    ./bootstrap && ./configure --enable-local
    ./ct-ng xtensa-esp32-elf
    ./ct-ng build
    chmod -R u+w builds/xtensa-esp32-elf

    On Windows, you can download a precompiled toolchain here. MacOS has another requirements.

    Then, on Linux/MacOS add the toolchain bin files to the environmental PATH variable as:

    export PATH=$PATH:$MICROPYTHON/crosstool-NG/builds/xtensa-esp32-elf/bin
    If you've downloaded it, then extract the files and point the $PATH to the correct bin folder.

    OV2640 drivers

    You need to add the OV2640 camera drivers to the ESP-IDF. To do that, just type the following:

    cd $MICROPYTHON/esp-idf/components
    git clone esp32-camera

    MicroPython for ESP32-CAM

    After adding the OV2640 drivers to the ESP-IDF, clone the MicroPython version that supports the camera and compile it using the following lines:

    git clone micropython
    cd micropython/mpy-cross
    cd ../ports/esp32
    git submodule update --init
    make V=1 SDKCONFIG=boards/sdkconfig.esp32cam -j 

    Flash MicroPython on the board

    The ESP32-CAM does not have a CP2102 to connect it directly to an USB port. Thus, you need an USB to serial device to flash or program the chip.

    Connect the USB UART to the ESP32-CAM as described in the following table:


    If you don't have the DTR pin available (like my board), you need to connect the GPIO0 pin to GND in order to flash MicroPython firmware. For flashing MicroPython programs, you don't need to do this. Just leave the pin floating. Therefore, after flashing the firmware remove that cable!

    Then, connect the USB to a free USB port on your PC and type the following:

    cd $MICROPYTHON/micropython/ports/esp32
    make deploy

    This last command build the firmware under build/firmware.bin and upload it to the board. After getting these lines:

    Hash of data verified.
    Hard resetting via RTS pin...

    disconnect the IO0 pin from GND and reset the board using the button.

    Programming using MicroPython

    Read the following article to connect to the board using VSCode: #MicroPython: VSCode IntelliSense, Autocompletion & Linting capabilities.

    Use the following code to connect (replace the ssid_ wp2_pass with the right ones) the ESP-CAM to your Wi-Fi router:

    import network
    ssid_ = <wlan-ssid>
    wp2_pass = <wlan-password>
    sta_if = network.WLAN(network.STA_IF)
    sta_if.connect(ssid_, wp2_pass)

    Then, install the following MicroPython packages typing this lines on the terminal inside VSCode:

    import upip

    Then, clone the MicroPython project located in: uPyCam on your PC configure the file with the SSID and WPA2 password of the Wi-Fi and upload the files to your board. This project takes a photo with the camera and display it on your browser each time that you visit the webserver that is running on the board.


    This tutorial is about compiling a MicroPython version with support for the OV2640 camera. The firmware can be uploaded to the ESP32-CAM board to take photos. The resolution of the camera is not ideal, but the low power consumption of the ESP32 and the connectivity make the ESP32-CAM ideal for security and remote applications where the only source of energy is a battery. Furthermore, MicroPython, as usual, makes it easy to develop and update the application. Obviously, some ESP32 performance is lost, but the result is still acceptable.

    Thanks Matt for the mention, I really enjoy your recap: October 2019 Melbourne MicroPython Meetup - News Roundup

    Tip and Errors

    1. If you get the following error when building the toolchain (./ct-ng build): Build failed in step 'Extracting and patching toolchain components'. Scroll up and check, which file is giving you the error. In my case, I got the following:

      [EXTRA]    Extracting gcc-git-20df92b4
      [00:29] - 
      bzip2: Compressed file ends unexpectedly;

      Then, remove that file using the following:

      cd crosstool-NG/.build/tarballs
      rm gcc-git-20df92b4.tar.bz2

      and execute again the builder.

    2. The following error appears because the board is running the official firmware and the version of uasyncio on PyPi is not compatible.

      INFO:picoweb:30.000 <HTTPRequest object at 3ffc3590> <StreamWriter <socket>> "GET /"
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 903, in <module>
      File "/lib/picoweb/", line 298, in run
      File "/lib/uasyncio/", line 161, in run_forever
      File "/lib/uasyncio/", line 136, in run_forever
      File "/lib/uasyncio/", line 60, in remove_writer
      TypeError: function takes 2 positional arguments but 3 were given

      You need to replace and in the lib/uasyncio directory with those from the official micropython-lib. I included these files inside the repository. If you upload the complete repository, the files will be replace and you shouldn't get this error.