Flashing MicroPython Firmware for ESP8266 on Raspberry Pi 3B

I'm running CentOS on Raspberry Pi 3B. I'll flash the latest MicroPython firmware for ESP-01S (8mbit).

  • VCC - 3.3v
  • CH_PD - 3.3v
  • GND - GND
  • TX - RX
  • RX - TX
  • GPIO0 - GND (FLASH MODE)

Disable Serial Login

$ systemctl status serial-getty@*

$ vi /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait selinux=1 security=selinux enforcing=0

$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait selinux=1 security=selinux enforcing=0

$ reboot

Download Firmware

$ yum install -y wget unzip

$ wget http://micropython.org/resources/firmware/esp8266-20161017-v1.8.5.bin

$ wget --content-disposition http://bbs.espressif.com/download/file.php?id=1572

$ unzip ESP8266_NONOS_SDK_V1.5.4.1_patch_20160704.zip esp_init_data_default.bin

Flash Firmware

$ curl https://bootstrap.pypa.io/get-pip.py | python

$ pip install esptool

$ esptool.py -p /dev/ttyS0 write_flash -fm qio -fs 8m 0x00000 esp8266-20161017-v1.8.5.bin 0xfc000 esp_init_data_default.bin
esptool.py v1.1  
Connecting...  
Running Cesanta flasher stub...  
Flash params set to 0x0020  
Writing 565248 @ 0x0... 565248 (100 %)  
Wrote 565248 bytes at 0x0 in 49.8 seconds (90.8 kbit/s)...  
Leaving...  

After flashing, before rebooting ESP, I'm going to disconnect GPIO0 from GND.

Open Interactive Shell

$ yum install -y minicom

$ minicom -o -b 115200 -D /dev/ttyS0
ÇÏþ#5 ets_task(40100384, 3, 3fff6300, 4)
WebREPL daemon started on ws://192.168.4.1:8266  
WebREPL daemon started on ws://0.0.0.0:8266  
Started webrepl in normal mode  
could not open file 'main.py' for reading

MicroPython v1.8.5-10-g0e69e6b on 2016-10-17; ESP module with ESP8266  
Type "help()" for more information.  
>>>
>>> import network
>>>
>>> sta = network.WLAN(network.STA_IF)
>>> sta.active(True)
>>> sta.connect('MiWiFi', '********')
>>>
>>> sta.ifconfig()
('192.168.31.172', '255.255.255.0', '192.168.31.1', '192.168.31.1')
>>>

Open Web Console

There're only two GPIO pins (GPIO0 and GPIO2).
GPIO2 is connected to onboard LED.
We can make it blink.

Welcome to MicroPython!  
Password: ******  
WebREPL connected  
>>> import machine, time
>>> led = machine.PWM(machine.Pin(2), freq=50)
>>> while True:
...   for i in range(1024):
...     led.duty(i)
...     time.sleep(0.002)
...
^C
>>> led.deinit()

To make ESP useful, I'll connect a DHT11 sensor to GPIO0.

  • VCC - 5v (RPi)
  • GND - GND (RPi)
  • DATA - GPIO0 (ESP)
>>> import dht
>>> import machine
>>> d = dht.DHT11(machine.Pin(0))
>>> d.measure()
>>> d.temperature()
25  
>>> d.humidity()
78  

Publish data collected from sensor to MQTT broker.

Press Ctrl-E to paste code block:

>>> ^E
paste mode; Ctrl-C to cancel, Ctrl-D to finish  
=== ...PASTE...
=== ^D
from dht import DHT11  
from machine import Pin  
from umqtt.simple import MQTTClient  
import json, time

dht = DHT11(Pin(0))  
led = Pin(2, Pin.OUT)  
mqtt = MQTTClient('ESP8266', 'iot.eclipse.org')

def read_dht():  
  dht.measure()
  return {
    'humidity': dht.humidity(),
    'temperature': dht.temperature(),
  }

def main_loop(t=10):  
  while True:
    led.low()
    data = read_dht()
    print(data)
    if mqtt.connect() == 0:
      mqtt.publish('easypi/dht11', json.dumps(data))
    led.high()
    time.sleep(t)

main_loop()  

Run MQTT client on any computer:

$ mosquitto_sub -h iot.eclipse.org -t easypi/dht11
{"humidity": 71, "temperature": 21}
{"humidity": 72, "temperature": 21}
{"humidity": 72, "temperature": 21}

Upload main.py

We can create a file called main.py, then upload via WebREPL. ESP will load it at startup.

>>> import os
>>> os.listdir()
['boot.py', 'port_config.py', 'main.py']
>>>
>>> import machine
>>> machine.reset()

ESP only run one thread, we can interrupt main_loop() via send Ctrl-C.