One of the alternative firmwares available for the ESP8266 is MicroPython Python interpreter. I’ve found by chance a great tutorial at Adafruit for building the Micropython firmware and I thought to give it a try.
Building the firmware:
The Adafruit tutorial uses a Vagrant based virtual machine to build the firmware, but since I’m already running Linux (Arch Linux to be more specific) and already have the Falcon open ESP8266 sdk installed (see here) and the esptool.py also available since I’m using the Sming firmware, I’ve just downloaded only the latest Micropython source code from the Github repository to a local directory.
cd ~ git clone https://github.com/micropython/micropython cd ~/micropython git submodule update --init cd ~/micropython/esp8266 export PATH=/opt/esp-open-sdk/xtensa-lx106-elf/bin:$PATH make axtls make
So far nothing different from the Adafruit tutorial except that I’m not using the vagrant VM. Also make sure that you first execute the command make axtls otherwise the main make command will compiling about not finding a version.h file. Also make sure that the export command that adds the path to the Xtensa compiler points to the right location.
After compiling, which was fast, I’ve just flashed the firmware on my Wemos mini D1 board. Again I had trouble flashing this board with other speeds than the default 115200 bps.
So:
cd ~/micropython/esp8266/build esptool.py -p /dev/ttyUSB0 --baud 115200 write_flash 0 firmware-combined.bin
And after flashing, we can connect through the serial terminal, and pressing CTRL-D we should be greeted with the following message:
PYB: soft reboot could not open file 'main.py' for reading MicroPython v1.8-157-g480159c on 2016-05-29; ESP module with ESP8266 Type "help()" for more information.
Some basic tests:
When doing some tests I’ve found out that most information is outdated regarding the version of Micropython that I’ve flashed. For example:
>>> import pyb Traceback (most recent call last): File "", line 1, in ImportError: no module named 'pyb' >>>
The common refered module pyb doesn’t exist, because it’s now machine:
>>> import machine >>> dir(machine) ['__name__', 'mem8', 'mem16', 'mem32', 'freq', 'reset', 'reset_cause', 'unique_id', 'deepsleep', 'disable_irq', 'enable_irq', 'RTC', 'Timer', 'Pin', 'PWM', 'ADC', 'UART', 'I2C', 'SPI', 'DEEPSLEEP', 'PWR_ON_RESET', 'HARD_RESET', 'DEEPSLEEP_RESET'] >>>
So the following code:
>>> import pyb >>> pin = pyb.Pin(14, pyb.Pin.OUT) # Set pin 14 as an output. >>> for i in range(10): ... pin.value(0) # Set pin low (or use pin.low()) ... pyb.delay(1000) # Delay for 1000ms (1 second) ... pin.value(1) # Set pin high (or use pin.high()) ... pyb.delay(1000)
should be now:
>>> import machine >>> pin = machine.Pin(14, machine.Pin.OUT) # Set pin 14 as an output. >>> for i in range(10): ... pin.value(0) # Set pin low (or use pin.low()) ... pyb.delay(1000) # Delay for 1000ms (1 second) ... pin.value(1) # Set pin high (or use pin.high()) ... pyb.delay(1000)
Other interesting stuff is for example, the esp module:
>>> import esp >>> dir(esp) ['__name__', 'osdebug', 'sleep_type', 'deepsleep', 'flash_id', 'flash_read', 'flash_write', 'flash_erase', 'flash_size', 'neopixel_write', 'apa102_write', 'dht_readinto', 'freemem', 'meminfo', 'info', 'malloc', 'free', 'esf_free_bufs', 'SLEEP_NONE', 'SLEEP_LIGHT', 'SLEEP_MODEM', 'STA_MODE', 'AP_MODE', 'STA_AP_MODE'] >>> esp.freemem() 17672 >>> esp.meminfo() data : 0x3ffe8000 ~ 0x3ffe8410, len: 1040 rodata: 0x3ffe8410 ~ 0x3ffe9038, len: 3112 bss : 0x3ffe9038 ~ 0x3fff6bd0, len: 56216 heap : 0x3fff6bd0 ~ 0x3fffc000, len: 21552
There are examples on GitHub to use the deepsleep functions:
Regarding the Wifi connectivity, by default when starting up the ESP8266 sets up a Wifi access point with the name Micropython-XXXXX where XXXX are some digits from the MAC address. Following the documentation the AP is protected with the password micropythoN, and sure enough the connection works. Still I haven’t tested it enough, for example, accessing the Python interpreter over Wifi, instead of through the serial port.
Anyway, one final test is to use Python to connect to make the ESP8266 to connect to my network. The instructions are simple, just write help(), and the micropython shows how to do it:
import network >>> help() Welcome to MicroPython! For online docs please visit http://docs.micropython.org/en/latest/esp8266/ . For diagnostic information to include in bug reports execute 'import port_diag'. Basic WiFi configuration: import network sta_if = network.WLAN(network.STA_IF) sta_if.active(True) sta_if.scan() # Scan for available access points sta_if.connect("", "") # Connect to an AP
and we can see if it connected successfully:
>>> sta_if.isconnected() True
and what IP configuration was set:
>>> sta_if.ifconfig() ('10.42.0.173', '255.255.255.0', '10.42.0.1', '10.42.0.1')
Also I was unable to access the Python interpreter through the access point connection. Supposedly there should be a listener running on port 8266 that allows access over WIFI, but I my tests found that the port 8266 was closed. Probably I need to initialize something first…
Anyway, there is a tool webrepl that allows to use the browser through websockets to connect to the ESP8266 and access the Python prompt and also to copy files to the ESP8266, namely the main.py startup file.
To finish. during my tests I had no crashes or surprise reboots. Using Python also has the advantage, in my opinion, that is more mainstream than Lua, since we leverage desktop programming with device programming. Also the useful tool ESPLorer already supports Micropython, it means that probably it is a better alternative for quick hacks using the ESP8266 instead of Nodemcu running LUA.