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.

  • M5Stack, MicroPython
    6 min | 35715

    #Tutorial: Getting Started with MicroPython on ESP32, M5Stack, and ESP8266

    M5Stack, MicroPython | 6 min | 35715


    MicroPython has almost all the features of Python, and allows you to easily interact with microcontrollers and sensors, making them accessible to both beginners and experienced Python programmers.

    If you are new to MicroPython, I quote the official MicroPython page for you:

    MicroPython is a lean and efficient implementation of the Python 3 programming language that includes a small subset of the Python standard library and is optimized to run on microcontrollers and in "constrained environments".

    If you have one of the boards listed in the hardware section below or another one with an ESP32, you can flash the MicroPython firmware on that chip. Then, you have two options: you can compile it yourself, or you can download a pre-compiled firmware and flash it.

    If you are still not sure about MicroPython, check out the section: MicroPython. There are many interesting articles and projects to read! Otherwise, you can start reading the following sections to flash micropython and upload your code on the board!

    Hardware

    This is just a selection of boards that support MicroPython.

    If you've bought a Pycom WiPy3.0, you don't need to flash the MicroPython firmware. That board comes with a version of MicroPython pre-flashed and you can update it using the Pycom's update tool.

    Flashing a pre-compiled Firmware

    This is the easiest way to get the MicroPython running on an ESP32. However, you get only what you download. So you cannot extend the version or freeze any new module.

    If you are not familiar with Linux, this is your best option:

    1. Install Python >=3.6 on your PC (Guide)
      • On Windows install it with PIP support
      • On Linux install pip too: sudo apt-get install python3-pip
    2. Go to the MicroPython download website
    3. Download the firmware:

      • if you have a board with pSRAM, download a GENERIC-SPIRAM firmware;
      • if you need BLE, download the firmware built with ESP-IDF v4.x

      There are many versions: stable ones, and a nightly release. You can choose one of them. I prefer the last stable release.

    4. Install the esptool.py tool following these instructions:
      # on Linux
      pip install esptool
      # or usually on Windows
      python -m pip install esptool 

      (source)

    5. Using the esptool.py tool and type the following lines:
      # On Linux:
      esptool.py --chip esp32 --port /dev/ttyUSBx erase_flash
      esptool.py --chip esp32 --port /dev/ttyUSBx --baud 460800 write_flash -z 0x1000 <file_name>.bin
      # On Windows:
      python -m esptool --chip esp32 --port COMx erase_flash
      python -m esptool --chip esp32 --port COMx --baud 460800 write_flash -z 0x1000 <file_name>.bin

      The first line erases the entire flash, you need this if you are flashing MicroPython for the first time on the board.

    Compiling MicroPython

    If you want to compile your MicroPython version from scratch, follow these instructions:

    1. Install the pre-requirements (< Ubuntu 19.10):
      sudo apt-get install git wget libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-click python-cryptography python-future python-pyparsing python-pyelftools cmake ninja-build ccache libffi-dev libssl-dev

      Note: if your are using Ubuntu 20.04 LTS, you need the following pre-requirements.

      sudo apt-get install git wget libncurses-dev flex bison gperf python3 python3-pip python3-setuptools python3-serial python3-click python3-cryptography python3-future python3-pyparsing python3-pyelftools cmake ninja-build ccache libffi-dev libssl-dev python-is-python3

      Otherwise, you will get the error /usr/bin/env: ‘python’: No such file or directory.

    2. Download the ESP-IDF framework (I'm using here the new version V4.x):

      mkdir ~/esp/
      cd ~/esp/
      git clone https://github.com/espressif/esp-idf.git
      cd esp-idf
      git checkout 310beae373446ceb9a4ad9b36b5428d7fdf2705f 
      
      ## the above hash is defined by the variable ESPIDF_SUPHASH_V4 in the file:
      # https://github.com/micropython/micropython/blob/master/ports/esp32/Makefile
      # you can use:
      # make ESPIDF=  # This will print the supported hashes, copy the one you want.
      
      git submodule update --init --recursive
      ## if you don't clone the submodules (recursive)
      # you'll get the following error while compiling MicroPython: 
      # xtensa-esp32-elf/bin/ld: cannot find -lrtc
      # and others...
    3. Download and install the toolchain:

      ## this downloads the v.5.2.0 release, you can use it, but esp-idf v4.0 should use v.8.2.0
      cd ~/esp/
      wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
      tar -xzf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
      
      ## recommended: this downloads the v8.2.0 r2 release compatible with esp-idf v4.0
      cd ~/esp/
      wget https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp-2019r2-linux-amd64.tar.gz
      tar -xzf xtensa-esp32-elf-gcc8_2_0-esp-2019r2-linux-amd64.tar.gz
      
      # set the path to the crosscompiler
      export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
      export IDF_PATH="$HOME/esp/esp-idf"   # old micropython versions
      export ESPIDF="$HOME/esp/esp-idf"     # new micropython versions
      ## Don't use the install.sh option, it didn't work for me and
      # I got a lot of errors while compiling MicroPython
    4. Clone MicroPython and compile the cross-compiler:
      git clone --recursive https://github.com/micropython/micropython.git
      cd micropython/mpy-cross
      make
      ## go to the esp32 porting files
      cd ../ports/esp32
    5. (Optional) Modify the setup to include support for BLE. If you have a board with pSRAM, change GENERIC to GENERIC_SPIRAM:

      nano boards/GENERIC/mpconfigboard.mk
      
      ##  boards/GENERIC/mpconfigboard.mk 
      # add the following line at the end
      SDKCONFIG += boards/sdkconfig.ble
    6. Select the board version (change this to GENERIC_SPIRAM if your board has pSRAM):
      export BOARD=GENERIC
    7. Compile the submodules and MicroPython:
      make -jN submodules
      make -jN

      where N is the number of CPU of your computer. If you are on Ubuntu 20.04 LTS, you need to type:

      make -jN PYTHON=python3
    8. Flash the MicroPython firmware on the ESP32, which should be already connected to a USB port:
      make deploy 
      # on 20.04 LTS
      make -jn deploy PYTHON=python3

      If you get the error A fatal error occurred: Timed out waiting for packet header, the firmware is usually located inside the build-GENERIC(...)/firmware.bin, you can flash it typing:

      esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x1000 build-GENERIC(...)/firmware.bin

    Freeze modules on MicroPython

    As I mentioned, you can freeze modules and include them into the firmware. This reduces the memory use on MicroPython and makes your code faster. To do that, copy the module files that you want to freeze into micropython/ports/esp32/modules. Then, repeat step 7 and 8. You should see something like this:

    Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
    Building with ESP IDF v4
    MPY sx127x.py
    GEN build-GENERIC/frozen_content.c
    CC build-GENERIC/frozen_content.c
    LINK build-GENERIC/application.elf
       text    data     bss     dec     hex filename
    1151395  269960   46244 1467599  1664cf build-GENERIC/application.elf
    Create build-GENERIC/application.bin
    esptool.py v2.8-dev
    Create build-GENERICM/firmware.bin
    bootloader     22528
    partitions      3072
    application  1421488
    total        1487024

    In this case, the SX127x driver (sx127x.py) was included. The module is compiled (MPY) and added to the MicroPython firmware as a frozen module. Then, you don't need to upload it using the PyMakr extension and you can import/use it as usual. In the example case:

    from sx127x import TTN, SX127x

    Fonts files and drivers are good candidates for this procedure.

    Uploading code to the board

    I recommend using VSCode and the Pymakr extension to program and upload code to the ESP32 boards running MicroPython firmware. A tutorial is available on this link: MicroPython: Visual Studio Code (VSCode) as IDE.

    Furthermore, you can get IntelliSense, autocompletion, dependency management, and linting capabilities on VSCode installing the micropy-cli. A tutorial about the extension is available on this link: MicroPython: VSCode IntelliSense, Autocompletion & Linting capabilities.

    Extra Tips

    1. If you get these errors, while trying to flash or erase the flash of the ESP32/ESP8266/M5Stack:
      • Permission denied /dev/ttyUSB0:
        serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyUSB0: [Errno 13] Permission denied: '/dev/ttyUSB0'

        you can use sudo to execute the command. However, you will also have the same problem, while using VSCode to flash upload the code to your board. Therefore, you can use the following:

        sudo usermod -a -G dialout [your_username]
      • A fatal error occurred: Timed out waiting for packet header.
        Serial port /dev/ttyUSB0
        Connecting......
        Chip is ESP32-PICO-D4 (revision 1)
        Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
        Crystal is 40MHz
        MAC: d8:a0:1d:5c:07:cc
        Uploading stub...
        Running stub...
        Stub running...
        Changing baud rate to 460800
        Changed.
        Configuring flash size...
        A fatal error occurred: Timed out waiting for packet header

        Try to reduce the the transmission speed, while flashing the board e.g.:

        esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x1000 <<filename>>
    2. If you get a long list of error that includes one of these:
      ../../extmod/modbtree.c:362:5: error: unknown type name 'DB'
      ../../py/obj.h:282:39: note: in definition of macro 'MP_OBJ_FROM_PTR'

      add the following flag MICROPY_PY_BTREE=0, while compiling/deploying MicroPython, e.g.:

      make -jN PYTHON=python3 MICROPY_PY_BTREE=0
      make -jN deploy PYTHON=python3 MICROPY_PY_BTREE=0 

      where N is the number of CPU of your computer. I got this error on Ubuntu 20.04 LTS.


    Comments

    alex 05.14.2020

    Can Thonny do the same steps?

    funny_hat 10.14.2020

    THANKS A LOT!!!!

    Marc Hauer 12.29.2020

    Thanks a lot for sharing your work.

    I was having a hard time following your tutorial. I was able to flash the esp32cam, but never managed to talk to it in pymakr or putty.
    Until I removed the GPIO 0 from GND.

    Rusty Shackleford 04.07.2021

    Great tutorial! But I don't get Compiling MicroPython, step 2 (I'm a noob): Could you clarify how to access ESPIDF_SUPHASH_V4 to list supported hashes?

    nitin sharma 05.26.2021

    hi, we are getting this error in linux idf.py -D MICROPY_BOARD=GENERIC -B build-GENERIC build make: idf.py: Command not found Makefile:34: recipe for target 'all' failed make: *** [all] Error 127 thank you