khalido.org

every blog needs subheader text

starting out with micropython on a esp8266

I’ve been wanting to try out a IOT board to do something for a while, and somebody lent me a mystery ESP8266 based board.

So, this is a log of my journey from never using an IOT device to making it blink lights or something.

Note: most of the below is unneeded with Mu 1.1, it autofinds the board, flashes it and makes it easy to run code on the board itself.

Initial steps

First up, I plugged in the board to the pc… and nothing happened, besides the a blue led coming on.

lsusb listed a bunch of devices, out of which my IOT board seems to be: Bus 001 Device 012: ID 1a86:7523 QinHeng Electronics CH340 serial converter. I figured this out by running lsusb with it plugged and unplugged. All this tells me is that my board is using the CH340 chip to provide usb connectivity.

First up, I need to know what port the device is, so running sudo dmesg has this at the end: usb 1-1: ch341-uart converter now attached to ttyUSB0.

Another useful tool is using usb-devices | less to list all the usb devices, and using vim commands to search.

Ok so far I can see that there is a board connected.

So I need esptool:

conda create -n iot # using a new environment
conda install -c conda-forge esptool # esptool for flashing esp boards

My user couldn’t access the usb port to actually use esptool, so I had to give my user these permissions:

sudo usermod -a -G tty ko
sudo usermod -a -G dialout ko

, then logout and log back in.

Running esptool.py --port /dev/ttyUSB0 chip_id tells me:

esptool.py v3.0
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
...

Micropython or Circuitpython?

Micropython came first, and at some point adafruit forked it to make circuitpython. The three main chipsets micropython seems to be using is esp8266 and its succesor esp32, and whatever pyboard itself uses. Circuitpython seems to support a lot more boards, but they all seem to be a lot more expensive than the esp ones.

One big different is that circuitpython supports fstrings! I like fstrings! But overall the choice comes down to what board - the esp ones are cheap and support micropython, the adafruit and competition are expensive and support both.

Installing micropython

So this has a ESP8266EX chip. So I headed over to the micropython esp8266 page and grabed the latest stable firmware, 2M of more of flash build, which seems to be the only one. As of 1.13, micropython only supports boards with 2M of flash.

First up, I erased the flash: esptool.py --port /dev/ttyUSB0 erase_flash, cause why not.

then installed micropython by:

esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-20200911-v1.13.bin

Eureka! It detected 4MB of flash and succesfully installed. Now to test if it works by logging into the board: picocom /dev/ttyUSB0 -b115200. This gives a simple REPL interface. I tested if the board works by:

import machine as m
pin = m.Pin(2, m.Pin.OUT) # I read somewhere that pin 2 is an output led
pin.on()
pin.off()

On and off are reversed, but this works to turn on and off the led. When I changed the pin number to 3 to see what happens, the repl froze and I had to power cycle the board and reconnect.

Setting up a dev env

vs code (failed)

Now using a cli REPL is a but too old school, so of course there is a plugin for VS Code. This needs nodejs (why!) so first install node using nvm, then the extension:

Ctrl-P and ext install pycom.Pymakr to install pymakr.

Note: Investigate https://github.com/BradenM/micropy-cli

So pymakr refuses to connect to the board even though it should, since the board itself is connecting and working just fine. Instead of wasting time with the pymakr extension which seems to have a lot of pending issues I switched to mu-editor.

Mu-editor

Only mu 1.1 which is still in alpha release supports esp boards so installed that in a new env by:

conda create -n mu python=3.7 pip # mu refuses to install on 3.8 or above
conda activate mu
conda install -c conda-forge esptool
# installing mu
git clone https://github.com/mu-editor/mu.git
cd mu
pip install -e ".[dev]"

Note: I installed mu in its own env as it uses a bunch of old packages.

Running mu-editor launches, it found the esp board right away with no config needed and it just works! with autocompleting ide and the repl at the bottom. So I dropped VS Code as its way overkill for the simple code needed for these devices and went with mu.

Testing it blinks:

import machine as m
import time

# set up output led
pin = m.Pin(2, m.Pin.OUT)

for _ in range(5):
    time.sleep(0.1)
    pin.on()
    time.sleep(0.2)
    pin.off()

print("The light should have blinked a few times!")

Mu soft-reboots the board, then executes the file on it. The repl has autocomplete, which is handy, but no syntax highlighting.

Copying files to the board

Micropython executes boot.py on startup, then runs main.py if found. So my code should go inside a main.py file.

Mu-editor has a built in file manager but it wasn’t working on my board, so I went with ampy.

Install that by: pip install adafruit-ampy then find the port the board is using.

On a mac this lists all the serial ports in use: ls -l /dev/tty.*

On my machine I got /dev/tty.usbserial-1420, so ampy basics is:

  • list files: ampy --port /dev/cu.usbserial-1420 ls
  • put a file on the board: ampy --port /dev/cu.usbserial-1420 put config.py
  • get a file: ampy --port /dev/cu.usbserial-1420 get config.py
  • delete: ampy --port /dev/cu.usbserial-1420 rm config.py

Board setup

Wifi

To connect to wifi:

def do_connect(ssid="****", password="***", wait=5):
    "connects to the network and returns sta_if"
    import network
    sta_if = network.WLAN(network.STA_IF)

    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect(ssid, password)

        # while loop to wait until it connects with a timeout
        timeout = time.time() + wait   # wait seconds from now
        while not sta_if.isconnected():
            if time.time() < timeout:
                pass
            else:
                print("Timed out...")
                break

    print('network config:', sta_if.ifconfig())
    return sta_if

wifi = do_connect() # use wifi.isconnected() as needed

Running this is hit and miss, sometimes it connects, other times it doesn’t. I’m returning the sta_if object so I can check later on if the board is connected when doing internet things.

Do something

The board by itself is pretty useless. I can make it blink a light, but it has no built in sensors or outputs (besides one led). So first up I need to get some things to connect it to.

Project ideas:

  • funky clock - needs display and some time transitions
  • door bell - needs camera and a button.
    • should be cheaper than buying a ring, and as a bonus can use wifi to send a pic on button press.
    • could also parse video feed and save pics of movements
  • weather display - with wind speed, water temp, tide etc
  • robot - a few sensors, motors
    • (is an esp board powerful enough to parse simple video or do i need a pi)
  • pixel art, needs some kind of funky led lights to put somewhere
  • music player

Resources

posted
tagged: iot