Slide 1

Slide 1 text

Enter MicroPython Python meets the metal Alejandro Guirao @lekum github.com/lekum

Slide 2

Slide 2 text

What is MicroPython MicroPython is a lean and efficient implementation of the Python 3 programming language that includes a small subset of the Python standard library and is optimised to run on microcontrollers and in constrained environments Just 256k of code space and 16k of RAM!

Slide 3

Slide 3 text

Features of Micropython ● Python compiler + runtime that runs on bare-metal ● REPL + ability to run and import scripts from the filesystem ● Arbitrary precision integers, closures, list comprehension, generators, exception handling...

Slide 4

Slide 4 text

Supported boards Pyboard ESP8266 WiPy BBC Micro:bit https://github.com/micropython/micropython/wiki/Boards-Summary

Slide 5

Slide 5 text

ESP8266

Slide 6

Slide 6 text

The ESP8266 The ESP8266 is a low-cost Wi-Fi chip with full TCP/IP stack and MCU (Micro Controller Unit) capability produced by Espressif Systems Microcontroller ESP-8266EX Operating Voltage 3.3V Digital I/O Pins 11 Analog Input Pins 1(Max input: 3.2V) Clock Speed 80MHz/160MHz Flash 16M bytes Length 34.2mm Width 25.6mm Weight 2.5g

Slide 7

Slide 7 text

MicroPython installation ● Download a firmware for the ESP8266 (http://micropython.org/download#esp8266) ● Install esptool.py ○ pip install esptool ● Connect the board and take note of the port (e.g. /dev/ttyUSB0) that shows up in the output of dmesg command ● Erase the flash memory of the board: ○ esptool.py --port /dev/ttyUSB0 erase_flash ● Flash with the firmware: ○ esptool.py --port /dev/ttyUSB0 write_flash -fm dio -fs 32m 0 esp8266-20170108-v1.8.7.bin

Slide 8

Slide 8 text

Using the REPL Install picocom and connect to the serial interface: picocom -b 115200 /dev/ttyUSB0 You should see the MicroPython REPL: MicroPython v1.8.7-7-gb5a1a20a3 on 2017-01-09; ESP module with ESP8266 Type "help()" for more information. >>>

Slide 9

Slide 9 text

Blinking the built-in LED >>> from machine import Pin >>> led = Pin(2, Pin.OUT) >>> for i in range(10): ... led.high() ... led.low() ... ... >>>

Slide 10

Slide 10 text

Code upload and execution ● We will use adafruit-ampy ● Installation: ○ pip install adafruit-ampy ● Set up the port connection: ○ export AMPY_PORT=/dev/ttyUSB0 ● Test it: ○ ampy ls

Slide 11

Slide 11 text

Workflow ● Edit your script main.py ● Perform one-shot run and get console output: ○ ampy run main.py ● Upload the file to the board: ○ ampy put main.py ● Restart the board!

Slide 12

Slide 12 text

Project A: Slack button

Slide 13

Slide 13 text

Schematics from machine import Pin button = Pin(0) if button.value(): print("The button is not pressed.") else: print("The button is pressed.")

Slide 14

Slide 14 text

Connect to a WiFi import network def wifi_connect(ssid, pwd): """ Connect to a wifi 'ssid' with password 'pwd' """ sta_if = network.WLAN(network.STA_IF) ap_if = network.WLAN(network.AP_IF) if ap_if.active(): ap_if.active(False) if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(ssid, pwd) while not sta_if.isconnected(): pass return 'IP address: %s' % sta_if.ifconfig()[0]

Slide 15

Slide 15 text

Post to Slack import urequests def to_slack(slack_hook_url, slack_icon_url, slack_message, slack_username): """ Send the 'slack_message' using an incoming webhook """ data = { "link_names": 1, "icon_url": slack_icon_url, "username": slack_username, "text": slack_message } res = urequests.post(slack_hook_url, json=data) return res.status_code == 200

Slide 16

Slide 16 text

Main loop (I) import time from machine import Pin if __name__ == "__main__": [...] led_pin = 0 # D3 button_pin = 12 #D6 wifi_connect(SSID, pwd) led = Pin(led_pin, Pin.OUT) button = Pin(button_pin, Pin.IN, Pin.PULL_UP)

Slide 17

Slide 17 text

Main loop (II) while True: # Button pressed if not button.value(): print("The button has been pressed") ok = to_slack(slack_hook_url, slack_icon_url, slack_message, slack_username) # If succeed, light the LED during 1s if ok: print("Succeeded posting to Slack") led.high() time.sleep(1) else: print("Failed trying to post to Slack") led.low() time.sleep_ms(10)

Slide 18

Slide 18 text

Project B: Temperature and humidity probe

Slide 19

Slide 19 text

Main loop from machine import unique_id from ubinascii import hexlify from sht30 import SHT30 from umqtt.simple import MQTTClient [...] mqtt_server = "" mqtt_client_id = "micropython-{}".format(hexlify(unique_id()).decode()) print("mqtt_client_id:", mqtt_client_id) wifi_connect(SSID, pwd) client = MQTTClient(mqtt_client_id, mqtt_server) client.connect() sensor = SHT30() while True: time.sleep(1) temperature, humidity = sensor.measure() client.publish("{}/temperature".format(mqtt_client_id).encode(), "{:.2f}".format(float(str(temperature))).encode()) client.publish("{}/humidity".format(mqtt_client_id).encode(), "{:.2f}".format(float(str(humidity))).encode())

Slide 20

Slide 20 text

Notes ● Get the driver dht.py from https://github.com/rsc1975/micropython-sht30 ● Upload it to the board: ○ ampy put sht30.py ● Send the metrics to any MQTT broker ○ iot.eclipse.org ● Search for these topics: ○ /temperature ○ /humidity

Slide 21

Slide 21 text

Visualization https://github.com/lekum/node-red-with-dashboards

Slide 22

Slide 22 text

Visualization Android MQTT Dash app

Slide 23

Slide 23 text

Further resources http://micropython-on-wemos-d1-mini.readthedocs.io/en/latest/ https://docs.micropython.org/en/latest/esp8266/ https://learn.adafruit.com/search?q=micropython& https://github.com/lekum/esp8266sketches

Slide 24

Slide 24 text

BBC Micro:bit

Slide 25

Slide 25 text

The BBC Micro:bit It is an ARM-based embedded system designed by the BBC for use in computer education in the UK. ● Size: approx. 5cm x 4cm ● Weight: 8g ● Processor: 32-bit ARM Cortex M0 CPU ● Bluetooth Low Energy ● Digital Compass ● Accelerometer ● Micro-USB controller ● 5x5 LED matrix with 25 red LEDs ● 2 programmable buttons ● Powered by 2x AAA batteries

Slide 26

Slide 26 text

Using the REPL Install picocom and connect to the serial interface: picocom -b 115200 /dev/ttyACM0 You should see the MicroPython REPL: MicroPython v1.7-9-gbe020eb on 2016-04-18; micro:bit with nRF51822 Type "help()" for more information. >>>

Slide 27

Slide 27 text

Code upload and workflow ● We will use uFlash ● Installation: ○ pip install uflash ● Upload a script ○ uflash main.py ● Auto-upload when changes ○ uflash --watch main.py

Slide 28

Slide 28 text

LED “Hello, World!” from microbit import display display.scroll("Hello, World!")

Slide 29

Slide 29 text

Built-in images from microbit import Image, display display.show(Image.HAPPY) HEART_SMALL HAPPY SMILE SAD CONFUSED ANGRY ASLEEP SURPRISED SILLY FABULOUS MEH YES NO TRIANGLE TRIANGLE_LEFT CHESSBOARD DIAMOND DIAMOND_SMALL SQUARE SQUARE_SMALL RABBIT COW MUSIC_CROTCHET MUSIC_QUAVER MUSIC_QUAVERS PITCHFORK XMAS PACMAN TARGET TSHIRT ROLLERSKATE DUCK HOUSE TORTOISE BUTTERFLY STICKFIGURE GHOST SWORD GIRAFFE SKULL UMBRELLA SNAKE...

Slide 30

Slide 30 text

Pinout

Slide 31

Slide 31 text

GPIO from microbit import * while True: pin0.write_digital(1) sleep(20) pin0.write_digital(0) sleep(480) print(pin0.read_analog()) sleep(480)

Slide 32

Slide 32 text

Music import music music.play(music.NYAN) music.play([‘c4’, ‘f#’, ‘g’]) DADADADUM ENTERTAINER PRELUDE ODE NYAN RINGTONE FUNK BLUES BIRTHDAY WEDDING FUNERAL PUNCHLINE PYTHON BADDY CHASE BA_DING WAWAWAWAA JUMP_UP JUMP_DOWN POWER_UP POWER_DOWN...

Slide 33

Slide 33 text

Project C: Remote compass

Slide 34

Slide 34 text

Compass import radio from microbit import display, Image, compass, button_a, button_b, sleep def menu_mode(): """ Principal menu mode """ while True: display.show(Image.HAPPY) radio.send("ready") if button_a.is_pressed(): send_direction() if __name__ == "__main__": radio.on() compass.calibrate() menu_mode()

Slide 35

Slide 35 text

Compass (II) def send_direction(): """ Send the direction which the probe is pointing to: direction_N, direction_NE, direction_E... """ display.show(Image.ARROW_N) while True: sleep(100) if button_b.is_pressed(): break # Back to the menu mode heading = compass.heading() if (heading > 337) or (heading <= 22): needle = "N" elif 22 < heading <= 67: needle = "NE" elif 67 < heading <= 112: needle = "E" [...] radio.send("dir_{}".format(needle))

Slide 36

Slide 36 text

Station import radio from microbit import display, Image def decode_direction(dirstring): """ Decode the dir_X and show the arrow """ needle = dirstring.split("dir_")[1] img = getattr(Image, "ARROW_{}".format(needle)) display.show(img) if __name__ == "__main__": radio.on() while True: incoming = radio.receive() if incoming is None: continue elif incoming.startswith("dir_"): decode_direction(incoming) elif incoming == "ready": display.show(Image.HAPPY)

Slide 37

Slide 37 text

Further resources https://microbit-micropython.readthedocs.io/en/latest/ http://microbit.org/ideas/ https://github.com/lekum/microbit-sketches/tree/master/micropython/remote_ compass

Slide 38

Slide 38 text

Happy hacking! Alejandro Guirao @lekum lekum.org github.com/lekum