• MicroPython
    4 min | 1615

    #MicroPython: a three-color E-INK display controlled using an ESP32

    MicroPython | 4 min | 1615


    diy projects
    e-ink display
    e-paper
    getting started
    micropython
    micropython extensions
    tutorial

    This is a tutorial to control and display widgets on an E-INK display using an ESP32. Three widgets are available:

    • Weather: weather forecast obtained using the OpenWeatherMap API.
    • News: news highlights obtained using the NewsApi API.
    • Notes: notes that can be added using a web-server that runs on the ESP32.

    The result can be seen in this video:

    Thus, in this tutorial, I will try to achieve the following:

    • A guide to compile MicroPython to freeze modules;
    • A setup guide for the code (Wi-Fi, APIs);
    • Steps to upload the code to the ESP32 board.

    Hardware & Software

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

    Freeze MicroPython Modules

    The RAM of the ESP32-WROOM (512kb) running MicroPython is very limited. Therefore, it is not possible to load the un-compiled modules and run the code. You will get the annoying error:

    MemoryError: memory allocation failed, allocating xxxx bytes

    To avoid that, you should include the modules under the folder frozen_modules as "frozen" modules on your MicroPython firmware. To freeze MicroPython modules, you need to compile MicroPython from scratch. To do that, follow these instructions:

    1. Install pre-requirements:
      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
    2. Download the ESP-IDF framework (I use here the new version V4):

      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
      
      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
      
    3. Download and install the toolchain:
      wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
      cd ~/esp/
      tar -xzf ~/Downloads/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
      export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
      export IDF_PATH="$HOME/esp/esp-idf"
      ## 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 https://github.com/micropython/micropython.git
      cd micropython/mpy-cross
      make
      
      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 submodules
      make

    Freezing modules on MicroPython 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:

    1. Flash MicroPython on the ESP32, which should be already connected to a USB port:
      make deploy

    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 v3
    MPY e7in5.py
    [...]
    MPY fonts/monaco16.py
    [...]
    MPY widgets/forecast.py
    [...]
    GEN build-GENERIC/frozen_content.c
    [...]
    Writing build-GENERIC/firmware.bin to the board
    esptool.py v2.8-dev
    Serial port /dev/ttyUSB0
    Connecting.....
    Chip is ESP32D0WDQ6 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    Crystal is 40MHz
    MAC: cc:50:e3:a8:80:cc
    Uploading stub...
    Running stub...
    Stub running...
    Changing baud rate to 460800
    Changed.
    Configuring flash size...
    Auto-detected Flash size: 4MB
    Compressed 1336896 bytes to 816859...
    Wrote 1336896 bytes (816859 compressed) at 0x00001000 in 20.9 seconds (effective 510.7 kbit/s)...
    Hash of data verified.
    
    Leaving...
    Hard resetting via RTS pin...

    For this project, copy the complete frozen_module folder content into micropython/ports/esp32/modules. Then, the modules are compiled (MPY) and added to the MicroPython firmware as frozen modules.

    Upload the uPyEINK project

    Follow these steps to run the project on the ESP32 board:

    1. Clone the project typing the following:
      git clone https://github.com/lemariva/uPyEINK.git
    2. Rename the files:
      • boot.py.sample to boot.py and include your Wi-Fi credentials:
        ssid_ = ''
        wpa2_pass = ''

        It is important that your ESP32 is connected to Wi-Fi to update the widgets.

      • settings.py.sample to settings.py and set up the following variables:
        news_api_key (info here)
        weather_api_key (info here)
    3. Upload the code to the ESP32, using e.g. VSCode and PyMakr extension and have fun! If you need help, check this tutorial: MicroPython: Visual Studio Code (VSCode) as IDE.

    The web-server is available under http:// and you can add and remove notes that will be displayed on the E-INK display.

    The E-INK update frequency is set to 2 hours (settings.update_interval in milliseconds) and after 5 updates (settings.calibration_interval) the ESP32 cleans the display to avoid ghosting and reset the board to update the clock using a NTP server. If you want to, you can activate the deep sleep functionality (settings.deep_sleep) but you lose the web-server and you can only update the notes only when the ESP32 is updating the display.

    Acknowledgement

    I took code and ideas from following repositories and wikis:

    Conclusions

    This tutorial helps you deploy a project to control an E-INK display using an ESP32. The screen is divided into different widgets that can be activated to gather information. Three widgets are included: Weather forecast, news, and notes. The weather forecast and news are obtained from the Internet using APIs and for the notes, the code starts a web server, in which the notes can be managed (written and deleted). The ESP32 wrover has limited RAM, then the steps to freeze modules on MicroPython are also described.


    Comments

    Empty