MicroPython — OTA Updates and GitHub, a match made in heaven

Ronald Dehuysser
3 min readJul 20, 2018

--

MicroPython is a lean and efficient software implementation of the Python 3 programming language, written in C, that is optimized to run on a microcontrollers (like the pyBoard or an ESP8266, ESP32, …). MicroPython is a full Python compiler and runtime that runs on the micro-controller itself. As a user you are presented with an interactive prompt (the REPL) to execute supported commands immediately. Included are a selection of core Python libraries and some extra libraries like machine which allows you to easily access low-level hardware.

As a developer, I am much more productive with MicroPython than plain old Arduino C++. Proper support for classes, easy access to the low level hardware results in readable and maintainable code which I find really important. But that’s enough of smalltalk about MicroPython.

For the moment, I’m working on a complex micro-controller project where I just feel that I will need updates to all the micro-controllers running in the wild. I do not want to bother people with asking them to flash their micro-controller again and again, each time I do an update/bugfix to the code. Since in my day-to-day workflow I already use github as a source control repository, I was thinking about using it to manage updates to all the devices.

So, I created a new MicroPython library (https://github.com/rdehuyss/micropython-ota-updater) which allows you to automatically update your MicroPython project using github releases. The workflow is as follows:

  • You have a github repo where you host your micropython project
  • In this project, you include all your source code in a folder called ‘main’
  • You also include the ota_updater.py (https://github.com/rdehuyss/micropython-ota-updater)
  • whenever you feel fit, you ask the OTAUpdater (on my project this is after a hardware interrupt which starts up the WLAN for MQTT messaging) to check for a new version using ota_updater.check_for_update_to_install_during_next_reboot()
  • if a new version is present, the OTAUpdater will download the new version on the next reboot (use machine.reset() to reboot your micro-controller) and use it
  • Use the following code in your `main.py`:
  • Eh voila!

The important part to note is that o.download_and_install_update_if_available(‘wifi-ssid’, ‘wifi-password’) will only start the WLAN if a new version is available (see below for more info). If not, it will just start your main code as usual.

What happens behind the scene? Once you finish a new feature/bug fix, you create a new release in GitHub (thus tagging it). The ota_updater queries GitHub for the latest release/tag (you should use semantic versioning). If a new version is available, it creates a .version_on_reboot file which contains the new version number and puts it in a sibling folder of your main module, called next. Once you reset your microcontroller and ask the OTAUpdater to download_and_install_update_if_available() the pending version, it will:

  • see which version it must download from the .version_on_reboot file in the next folder
  • download all the new .py files in the next folder
  • delete the main folder
  • rename the next folder to main
  • rename the .version_on_reboot to .version
  • and do a machine.reset(). In your main.py file you then continue as normal, importing and bootstrapping your code from your main module.

The .version file is used to compare it against the latest release on your GitHub account. If a new version is found, the cycle starts over and that’s it!

You may ask yourself: why this workflow? Well, my project is quite complex and large and I was hitting memory issues. By having the download and update part in a separate boot cycle, I’m sure that everything is garbage collected.

For the moment, the ota_updater works with for sure with an ESP32 micro-controller running MicroPython 1.9.4.

--

--

Ronald Dehuysser

All-round software gardener (Java, .NET core, Javascript, TypeScript, Python) and visual facilitator. You can reach me via linkedin.