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 | 34984

    #Tutorial: MicroPython and Bluetooth (BLE) on M5Stack

    M5Stack, MicroPython | 6 min | 34984


    The M5Stack is a modular open-source toolkit for developing IoT applications. It is based on an ESP32, which is the core module and there are a lot of stackable modules that you can use for different projects. This enables to do rapid and high-quality prototyping!

    You can program the core device using the ESP-IDF framework, the Arduino-IDE, Blockly or MicroPython. Unfortunately, the BLE is still not available using the official M5Stack MicroPython firmware (forked from LoBo). However, flashing the ESP32 with the official MicroPython version built with the ESP-IDF v4.x enables the BLE module and it is possible to send and receive data to/from the M5Stack.

    This article is a quick tutorial for flashing the MicroPython official version on the M5Stack. Additionally, I've included a project example that uses the BLE module to send the data of the IMU and the buttons' states and to receive a variable value in order to switch on/off the display.

    This tutorial focuses on the M5Stack-Fire. However, it can be used with every ESP32 boards that are available on the market. With some modification (sensors' or buttons' pins), the example application can run on different ESP32 boards. However, you should use boards that have pSRAM. Otherwise, the boards only have 512kB RAM, which will be a problem for the BLE Stack and you'll get an "out of memory" error. Some boards are listed here.

    Hardware and Software

    In this article, the following hardware and software are used or recommended:


    Note (*): You need the M5Stack Fire! There are cheaper versions (for example, Basic, Gray, M5Stick), but the RAM is only 512kB on those models, and therefore they will not work well with MicroPython. The following figure shows a summary of the differences between the M5Stack CORE models:

    M5Stack

    MicroPython Firmware

    As I mentioned, you need to download the official version of MicroPython. You can compile it yourself, or you can download a pre-compiled firmware and flash it on your M5Stack-Fire.

    Flashing a pre-compiled Firmware

    This is the easy way to get the official version of MicroPython on the M5Stack. 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. Go to the MicroPython download website
    2. Download the firmware built with ESP-IDF v4.x (GENERIC-SPIRAM for the M5Stack Fire). There are two versions: a stable one, and a nightly release. You can choose one of them.
    3. Flash the M5Stack-Fire using the esptool.py tool and the following lines:
      esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash
      esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32spiram-idf4-20191220-v1.12.bin

      If you are flashing this version of MicroPython on the M5Stack for the first time then you should first erase the entire flash. In that case, you need the first line of the code above.

    4. Use VSCode and the PyMakr extension to upload and run code on the M5Stack.

    Compiling MicroPython

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

    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:

      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. Modify the setup to include support for BLE on the SPIRAM board version (with pSRAM):

      nano boards/GENERIC_SPIRAM/mpconfigboard.mk
      
      ##  boards/GENERIC_SPIRAM/mpconfigboard.mk 
      # add the following line at the end
      SDKCONFIG += boards/sdkconfig.ble
    6. Select the board version with SPIRAM:
      export BOARD=GENERIC_SPIRAM
    7. Compile the submodules and MicroPython:
      make submodules
      make
    8. Flash MicroPython on the M5Stack, which should be already connected to a USB port:
      make deploy

    Freeze modules on MicroPython

    As I mentioned, you can freeze modules and include them in 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 ili934xnew.py
    GEN build-GENERIC_SPIRAM/frozen_content.c
    CC build-GENERIC_SPIRAM/frozen_content.c
    LINK build-GENERIC_SPIRAM/application.elf
       text    data     bss     dec     hex filename
    1151395  269960   46244 1467599  1664cf build-GENERIC_SPIRAM/application.elf
    Create build-GENERIC_SPIRAM/application.bin
    esptool.py v2.8-dev
    Create build-GENERIC_SPIRAM/firmware.bin
    bootloader     22528
    partitions      3072
    application  1421488
    total        1487024

    In this case, the display driver (ili934xnew.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 ili934xnew import ILI9341, color565

    Fonts files and drivers are good candidates for this procedure.

    Code Example

    I've published an application example on GitHub, clone it using the following:

    git clone --recursive https://github.com/lemariva/uPyM5BLE.git

    Then, use VSCode and the PyMakr extension to upload the project to the M5Stack-Fire. If you need some help, a tutorial is available here.

    The uPyM5BLE application reads the data from the IMU (accelerometer, gyrometer, magnetometer, and temperature sensors) and the buttons' states. The application then publishes them as different BLE characteristics (GATT) (see Fig. 1). Additionally, it offers a writeable variable to switch on/off the M5Stack display (see Fig. 2). Thus, to summarize, the following data is available:

    • 3-axis accelerometer - 3 shorts & accuracy 0.01g,
    • 3-axis magnetometer - 3 ints & accuracy 0.01uT,
    • 3-axis gyroscope - 3 ints & accuracy 0.01°/s,
    • Temperature sensor - 1 short & accuracy 0.01°C,
    • Button A, B and C states.

    To see the BLE device, read and write data, you can use the BLE Scanner application.

    ble_scanner_read.png
    Fig. 1: BLE Scanner Application - Reading data from the M5Stack
    ble_scanner_write.png
    Fig. 2: BLE Scanner Application - Writing a variable value

    Additional information about the ubluetooth module can be found here. And, as it is mentioned in the documentation, on the ESP32, the MAC address is random and will be generated when the BLE interface is activated. So you can use the BLE Scanner application to find the device MAC address as shown in Fig. 3.

    ble_scanner_mac.png
    Fig. 3: BLE Scanner Application - Getting Device MAC address

    Conclusions

    This tutorial helps you enable the Bluetooth module on an M5Stack-FIRE running MicroPython. The M5Stack official version still doesn't include that option. If you want to send data over Bluetooth, you need to flash the MicroPython official version built with ESP-IDF v4.x. The article explains two ways to achieve this and includes an explanation to freeze modules in order to reduce RAM use on ESP32. Furthermore, an example is included, in which readable and writeable variables are listed. The IMU data and the buttons' states are sent over BLE and the display can be controlled writing a variable. The BLE Scanner application is used to see the device and interact with the data.


    Comments

    Empty