CentraleSupélec LMF, UMR CNRS 9021
Département informatique Laboratoire Méthodes Formelles
Bât Breguet, 3 rue Joliot-Curie Bât 650 Ada Lovelace, Université Paris Sud
91190 Gif-sur-Yvette, France Rue Noetzlin, 91190 Gif-sur-Yvette, France
MicroPython on ESP32

The ESP32 is a microcontroller with support for WiFi and Bluetooth. MicroPython has a port for the ESP32, so it is also a great platform for MicroPython development. ESP32 development boards are much cheaper that pyboards, however, they lack the USB volume that may be a handy alternative for programming the pyboard. By contrast, they feature a WebREPL, which allows us to program an ESP32 under MicroPython just using a web browser!

To install Micropython on a ESP32, get a suitable version of Micropython, then, using the esptools (you can also install it with pip), install it on your ESP32:

esptool.py --port /dev/<the ESP32 device> erase_flash
esptool.py --chip esp32 --port /dev/<the ESP32 device> write_flash -z 0x1000 esp32-YYYYMMDD-vx.y.z.bin

For some boards, the firmware update mode is activated by rebooting (press the EN button) while holding the BOOT button pressed.

For developing on the ESP32, I find rshell vey handy.

The main issue with the ESP32 MicroPython port is that the documentation of the machine module is not complete. You have to look at the Quick Reference to get precise information.

Port of my pyboard modules to the ESP32

The Micropython libraries are not the same on the pyboard and on the ESP32. I have ported some of my pyboard modules to the ESP32 and made them available on GitHub.

Boot file with automatic connection to a WiFi network

I use this boot.py file for automatically connecting to a known WiFi network or creating a WiFi network is no known network is found.

# This file is executed on every boot (including wake-boot from deepsleep)
import esp
esp.osdebug(None)
import network
import usocket
import utime
import ujson
from ntptime import settime
from machine import Timer

# Get list of known WiFi networks
try :
  with open('/networks.json', 'r') as netfile :
    knownnets = ujson.load(netfile)
except exception :
  knownnets = {}

netprio = list(knownnets.keys())
netprio.sort()

if len(netprio) > 0 :
  # Firstly, try to connect to a known WiFi network
  wlan = network.WLAN(network.STA_IF)
  wlan.active(True)
  networks = wlan.scan()
  # Get the SSIDs of the networks
  netnames = [n[0].decode('utf-8') for n in networks]
  for net in netprio :
    if net < 0 :
      continue
    ssid = knownnets[net]['ssid']
    if ssid in netnames :
      print("Trying to connect to", ssid)
      wlan.connect(ssid, knownnets[net]['pword'])
      utime.sleep(5)  # Wait 5 seconds for the connection
      if wlan.isconnected() :
        print("Success!")
        break
      print("Failure.")

  # Secondly, if no network was found, create our own
  if not wlan.isconnected() :
    wlan.active(False)
    for net in netprio :
      if net >= 0 :
        continue
      wlan = network.WLAN(network.AP_IF)
      wlan.active(True)
      wlan.config(essid=knownnets[net]['ssid'], password=knownnets[net]['pword'])

# Print our IP address and the network we are on
print(wlan.ifconfig()[0], " on ", wlan.config('essid'))

# If we can reach an NTP server, setup a timer to fix the drift of the RTC every hour
if len(usocket.getaddrinfo('pool.ntp.org', 123)) > 0 :
  # Setup a timer to set the time from pool.ntp.org
  ntp_timer = Timer(-1)
  ntp_timer.init(period=3600000, mode=Timer.PERIODIC, callback=lambda t:settime())
  settime()

The list of known WiFi networks is stored in the networks.json file, which has the following structure:

{
  1: {"ssid":"Network1", "pword":"PasswordForNetwork1"},
  2: {"ssid":"Network2", "pword":"PasswordForNetwork2"},
 -1: {"ssid":"ESP32_WiFi", "pword":"ESP32WiFiNetworkPassword"},
}

The integer key gives the order in which the connection to the networks should be tried. A negative value corresponds to the network that will be created if no known network is found.

Port to the ESP32 of the practical sessions of the Computer Architecture course

With my colleagues from Supélec, we designed a course on computer architecture to demystify the operation of computers. This course is no longer given, however, the web site (in French) is still alive. I recently ported the practical sessions to the ESP32 so that this material can be reused on a cheaper platform than the pyboard (which is nevertheless a very good platform for educational purposes).

Practical session "BE 3" (subject in French) has been ported very easily, see buttons and LEDs.

Practical session "EL 2" (subject in French) was also quite easy to port, the main issue being to find the matching API in modules machine and time for the calls in the pyb module, see LED matrix.

Installing MicroPython on the ESP32

This is really easy thanks to the detailed instructions on the ESP32 tutorial at micropython.org and to the esptool module. However, I spent a large amount of time trying and trying again because I though that the installation failed. The real problem was with minicom that did not work fine with the ESP32 port of MicroPython. When I switched to picocom (or even to miniterm, which I do not recommend if you can find something better), everything worked fine. I therefore updated my pyterm script to use picocom.