Easy IoT
with MicroPython
on ESP SoCs

Nick Moore
@mnemote
nick@mnemote.com

ESP8266 / ESP32 SoCs

What is a SoC

System on a Chip, or System on a Module

Microcontroller

Atmel ATMega
PIC16
Cortex M0


No OS
SoC / SoM

Cortex M4+
PIC32
ESP32


FreeRTOS
Embedded

x86
x86-64
ARM-v8


Linux

ESP8266 / ESP32

ESP8266 CPU

ArduinoESP8266
AVR
ATMega328P
Tensilica
Xtensa LX106
8 bit32 bit
1 core1 core
20 MHz80/160 MHz
2 KB RAM160 KB RAM
32 KB Flash4 MB Flash

ESP32 CPU

ArduinoESP8266ESP32
AVR
ATMega328P
Tensilica
Xtensa LX106
Tensilica
Xtensa LX6
8 bit32 bit32 bit
1 core1 core2 core *
20 MHz80/160 MHz160/240 MHz
2 KB RAM160 KB RAM520 KB RAM
32 KB Flash1 - 4 MB Flash4 - 16 MB Flash

original image: zeptobars.com

original image: zeptobars.com

original image: zeptobars.com

ESP32 Modules

WROOM-32 or ESP-32S

original image: espressif.com

ESP32 Boards

ESP32-DevKitC / Sparkfun ESP32 Thing / AdaFruit HUZZAH32

original images: espressif.com and sparkfun.com and adafruit.com

ESP32 Networking

ESP32 I/O

ESP IDF

IoT Development Framework

C SDK for building programs to run on ESP32

Contains LWIP, examples, instructions for building toolchain

The Internet of Toys — 1

The Internet of Toys — 2

https://buzzconf.io/sessions/airborne-iot-build-a-rocket/

MicroPython

micropython.org

MicroPython

MicroPython Platforms

For more background, see
Damien's talk about the Kickstarter campaign
from PyConAU 2016

MicroPython for ESP32

github: micropython/micropython-esp32

$ git clone --recursive https://github.com/micropython/micropython-esp32.git
$ more micropython-esp32/ports/esp32/README.md

OR

http://micropython.org/downloads#esp32

$ pip install esptool
$ esptool.py write_flash --flash_mode dio 0x1000 esp32-20170919-v1.9.2-272-g0d183d7f.bin

Running MicroPython — 1

$ miniterm.py /dev/ttyUSB0 115200 --raw
MicroPython v1.9.2-272-g0d183d7f on 2017-09-19;
ESP32 module with ESP32
Type "help()" for more information.
>>>

Running MicroPython — 2

$ miniterm.py /dev/ttyUSB0 115200 --raw
MicroPython v1.9.2-272-g0d183d7f on 2017-09-19;
ESP32 module with ESP32
Type "help()" for more information.
>>> help()
Welcome to MicroPython on the ESP32!

(... etc ...)

Running MicroPython — 3

>>> help('modules')
__main__          flashbdev         random            uos
_boot             framebuf          re                upip
_onewire          gc                select            upip_utarfile
_thread           hashlib           socket            urandom
apa106            heapq             ssl               ure
array             inisetup          struct            uselect
binascii          io                sys               usocket
btree             json              time              ussl
builtins          machine           ubinascii         ustruct
cmath             math              ucollections      utime
collections       micropython       uctypes           utimeq
dht               neopixel          uerrno            uzlib
ds18x20           network           uheapq            zlib
errno             onewire           uio
esp               os                ujson

Running MicroPython — 4

$ miniterm.py /dev/ttyUSB0 115200 --raw
MicroPython v1.9.2-272-g0d183d7f on 2017-09-19;
ESP32 module with ESP32
Type "help()" for more information.
>>> import machine
>>> pin = machine.Pin(5, machine.Pin.OUT)
>>> pin.value(True)

Running MicroPython — 5

>>> import machine
>>> import time
>>> pin = machine.Pin(5, machine.Pin.OUT)
>>> while True:
...     pin.value(True)
...     time.sleep(1)
...     pin.value(False)
...     time.sleep(1)

Running MicroPython — 6

>>> import machine
>>> import time
>>> pin = machine.Pin(5, machine.Pin.OUT)
>>> while True:
...     pin.value(True)
...     time.sleep(1)
...     pin.value(False)
...     time.sleep(1)

Running MicroPython — 7

With thanks to apple //jse

Programming MicroPython — mpy-utils

github: nickzoic/mpy-utils

Using REPL as a file transfer protocol: slow and very alpha

Programming MicroPython — modules/ and scripts/

Also upip, a micropython package manager

Programming MicroPython — Filesystem

>>> import os
>>> os.listdir()
['boot.py']
>>> f = open('hello.world', "w")
>>> f.write("Hello, World!")
13
>>> f.close()
>>> os.listdir()
['boot.py', 'hello.world']

Programming MicroPython — Networking — 1

>>> import network
>>> w = network.WLAN(network.STA_IF)
>>> w.active(True)
>>> w.connect("SSID","PASSWORD")
>>> w.ifconfig()
('192.168.1.101', '255.255.255.0', '192.168.1.1',
'192.168.1.1')

Programming MicroPython — Networking — 2

>>> import socket
>>> s = socket.socket()
>>> s.connect(('example.com', 80))
>>> s.write('GET / HTTP/1.0\r\n')
16
>>> s.write('Host: example.com\r\n\r\n')
21
>>> s.readline()
b'HTTP/1.0 200 OK\r\n'
>>> s.close()
    

Programming MicroPython — I2C — 1

Programming MicroPython — I2C — 2

>>> import machine
>>> i2c = machine.I2C(
...   freq=400000,
...   scl=machine.Pin(22),
...   sda=machine.Pin(21)
... )
>>> i2c.scan()
[104]

Programming MicroPython — I2C — 3

>>> import machine
>>> i2c = machine.I2C(
...   freq=400000,
...   scl=machine.Pin(22),
...   sda=machine.Pin(21)
... )
>>> i2c.readfrom_mem(104, 59, 14)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Programming MicroPython — I2C — 4

>>> i2c.writeto_mem(104, 107, bytes([0]))
>>> i2c.readfrom_mem(104, 59, 14)
b'\xf3\x90\x00\x0cB\xa0\xf6\x10\xfd\x1d\x00\xa4\xff\x9d'

Programming MicroPython — I2C — 5

>>> import struct
>>> struct.unpack(
...   ">7h",
...   i2c.readfrom_mem(104, 59, 14)
... )
(-3016, 32, 17024, -2768, -758, 224, -133)

Programming MicroPython — I2C — 6

class Accelerometer:
    def __init__(self, i2c=None, address=104):
	self.i2c = i2c or machine.I2C(freq=400000,
                scl=machine.Pin(22), sda=machine.Pin(21))
        self.address = address
	self.i2c.writeto_mem(self.address, 107, bytes([0])

    def read_xyz(self):
	return struct.unpack(
            ">3h", self.i2c.readfrom_mem(104, 59, 6)
        )

Developing MicroPython

original image: iconsplace.com

How do C modules work? — 1

>>> import esp
>>> dir(esp)
['__name__', 'flash_read', 'flash_write', 'flash_erase',
'flash_size', 'flash_user_start', 'gpio_matrix_in',
'gpio_matrix_out', 'neopixel_write', 'dht_readinto']
>>> esp.flash_size()
4194304

How do C modules work? — 2

esp-idf/components/spi_flash/include/esp_spi_flash.h

/**
 * @brief  Get flash chip size, as set in binary image header
 *
 * @note This value does not necessarily match real flash size.
 *
 * @return size of flash chip, in bytes
 */
size_t spi_flash_get_chip_size();

How do C modules work? — 3

ports/esp32/modesp.c

#include "esp_spi_flash.h"

STATIC mp_obj_t esp_flash_size(void) {
    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
}

How do C modules work? — 4

ports/esp32/modesp.c

#include "esp_spi_flash.h"

STATIC mp_obj_t esp_flash_size(void) {
    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
}

How do C modules work? — 5

ports/esp32/modesp.c

#include "esp_spi_flash.h"

STATIC mp_obj_t esp_flash_size(void) {
    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);

How do C modules work? — 6

ports/esp32/modesp.c

#include "esp_spi_flash.h"

STATIC mp_obj_t esp_flash_size(void) {
    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);

STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) },
    { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&esp_flash_size_obj) },
};
    

How do C modules work? — 7

ports/esp32/modesp.c

#include "esp_spi_flash.h"

STATIC mp_obj_t esp_flash_size(void) {
    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);

STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) },
    { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&esp_flash_size_obj) },
};
STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table);

const mp_obj_module_t esp_module = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t*)&esp_module_globals,
};

How do C modules work? — 8

ports/esp32/mpconfigport.h

extern const struct _mp_obj_module_t esp_module;

#define MICROPY_PORT_BUILTIN_MODULES \
    { MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \

esp32/Makefile

SRC_C = \
        modesp.c \

How do C modules work? — 9

>>> import esp
>>> dir(esp)
['__name__', 'flash_read', 'flash_write', 'flash_erase',
'flash_size', 'flash_user_start', 'gpio_matrix_in',
'gpio_matrix_out', 'neopixel_write', 'dht_readinto']
>>> esp.flash_size()
4194304

The State of the IoT

The State of the IoT

... a bit like mobile phones in the 1990s

... or motorcars in the 1920s

On the one hand
information wants to be expensive,
because it's so valuable.

The right information in the right place
just changes your life.


On the other hand,
information wants to be free,
because the cost of getting it out
is getting lower and lower all the time.


Stewart Brand, 1st Hackers Conference 1984

Panacea or Panopticon?

images: revistamundonatural.com / focault.info

The State of the IoT

 

1. If you're not the customer, you're the product.

2. End Of Life

arlogilbert.com

3. Internet Not Found

telegraph.co.uk

4. Cryptography


image: xkcd 221

5. Awful Software

6. Update Cycle

Complaints → Requirements

  1. Internet Mediation Internet Independence
  2. Vendor Lockin Generic Interfaces
  3. SSL Simplified Cryptography
  4. C / Linux Easier development

Requirements → Potential Solutions

MicroPython Meetup

 

Wednesday, September 27

Connected Community HackerSpace (CCHS)

 

https://www.meetup.com/MicroPython-Meetup/

http://hackmelbourne.org

BuzzConf Nights

 

Thursday, September 28

Loop Bar

 

https://www.meetup.com/BuzzConf/

LinuxConf 2018

 

Tutorial:

"Getting Started with MicroPython"

 

https://linux.conf.au/

Questions / Comments

Nick Moore
Mnemote Pty Ltd

Slides:

Content © Mnemote Pty Ltd except where otherwise noted