Table of Contents

MicroPython Asynchronous MQTT

MQTT library for MicroPython on the ESP8266 and ESP32

Files

ESP32

boot.py is the MicroPython startup. The others are the MQTT demo.

boot.py
config.py
mqtt_as.py
test.py
Shell

These scripts to interact with the mosquitto MQTT broker.

pubtest
subtest

boot.py

The ESP32 startup file which run our test after a short boot delay.

# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
#import webrepl
#webrepl.start()
import utime
utime.sleep(4)
import test

test.py

Main executable called from startup. This demo is pulled from the README documentation with local changes.

Configure SERVER here.

from mqtt_as import MQTTClient
from config import config
import uasyncio as asyncio

SERVER = '192.168.0.13'  # Change to suit e.g. 'iot.eclipse.org'

def callback(topic, msg, retained):
    print((topic, msg, retained))

async def conn_han(client):
    await client.subscribe('foo_topic', 1)

async def main(client):
    await client.connect()
    n = 0
    while True:
        await asyncio.sleep(5)
        print('publish', n)
        # If WiFi is down the following will pause for the duration.
        await client.publish('result', '{}'.format(n), qos = 1)
        n += 1

config['subs_cb'] = callback
config['connect_coro'] = conn_han
config['server'] = SERVER

MQTTClient.DEBUG = True  # Optional: print diagnostic messages
client = MQTTClient(config)
loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(main(client))
finally:
    client.close()  # Prevent LmacRxBlk:1 errors

config.py

mqtt_as configuration as found in distribution directory with mosquitto MQTT broker and wifi changes.

Configure MQTT broker, ssid and password.

# config.py Local configuration for mqtt_as demo programs.
from sys import platform
from mqtt_as import config

config['server'] = '192.168.0.13' # Change to suit
# config['server'] = 'iot.eclipse.org'

# Not needed if you're only using ESP8266
config['ssid'] = 'kewl-v8'
config['wifi_pw'] = 'PASSWORD'

# For demos ensure the same calling convention for LED's on all platforms.
# ESP8266 Feather Huzzah reference board has active low LED's on pins 0 and 2.
# ESP32 is assumed to have user supplied active low LED's on same pins.
# Call with blue_led(True) to light

if platform == 'esp8266' or platform == 'esp32' or platform == 'esp32_LoBo':
    from machine import Pin
    def ledfunc(pin):
        pin = pin
        def func(v):
            pin(not v)  # Active low on ESP8266
        return func
    wifi_led = ledfunc(Pin(0, Pin.OUT, value = 0))  # Red LED for WiFi fail/not ready yet
    blue_led = ledfunc(Pin(2, Pin.OUT, value = 1))  # Message received
elif platform == 'pyboard':
    from pyb import LED
    def ledfunc(led, init):
        led = led
        led.on() if init else led.off()
        def func(v):
            led.on() if v else led.off()
        return func
    wifi_led = ledfunc(LED(1), 1)
    blue_led = ledfunc(LED(3), 0)

mqtt_as.py

mqtt_as excecutable. This is the main logic which maintains a Wifi connection and publishes and subscribes to topics.

wget https://raw.githubusercontent.com/peterhinch/micropython-mqtt/master/mqtt_as/mqtt_as.py

Run

ESP32
>>> import machine
>>> machine.reset()
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5008
ho 0 tail 12 room 4
load:0x40078000,len:10600
ho 0 tail 12 room 4
load:0x40080400,len:5684
entry 0x400806bc
I (548) cpu_start: Pro cpu up.
I (548) cpu_start: Application information:
I (548) cpu_start: Compile time:     Aug 16 2020 00:54:20
I (551) cpu_start: ELF file SHA256:  0000000000000000...
I (557) cpu_start: ESP-IDF:          v3.3.2
I (562) cpu_start: Starting app cpu, entry point is 0x40082f30
I (552) cpu_start: App cpu up.
I (573) heap_init: Initializing. RAM available for dynamic allocation:
I (579) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (585) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (591) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (598) heap_init: At 3FFBDB5C len 00000004 (0 KiB): DRAM
I (604) heap_init: At 3FFCA9E8 len 00015618 (85 KiB): DRAM
I (610) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (616) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (623) heap_init: At 4009DE28 len 000021D8 (8 KiB): IRAM
I (629) cpu_start: Pro cpu start user code
I (312) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (4890) modsocket: Initializing
I (5020) wifi:wifi driver task: 3ffd1120, prio:23, stack:3584, core=0
I (10354) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (10354) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (10404) wifi:wifi firmware version: 44aa95c
I (10404) wifi:config NVS flash: enabled
I (10404) wifi:config nano formating: disabled
I (10404) wifi:Init dynamic tx buffer num: 32
I (10404) wifi:Init data frame dynamic rx buffer num: 32
I (10414) wifi:Init management frame dynamic rx buffer num: 32
I (10414) wifi:Init management short buffer num: 32
I (10424) wifi:Init static rx buffer size: 1600
I (10424) wifi:Init static rx buffer num: 10
I (10424) wifi:Init dynamic rx buffer num: 32
I (10534) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
I (10534) wifi:mode : sta (30:ae:a4:fe:03:80)
I (10534) wifi: STA_START
I (10914) wifi:new:<3,0>, old:<1,0>, ap:<255,255>, sta:<3,0>, prof:1
I (11764) wifi:state: init -> auth (b0)
I (11764) wifi:state: auth -> assoc (0)
I (11774) wifi:state: assoc -> run (10)
I (11784) wifi:connected with kewl-v8, aid = 10, channel 3, BW20, bssid = c2:4a:00:be:c7:a6
I (11794) wifi:security type: 3, phy: bgn, rssi: -57
I (11794) wifi:pm start, type: 1

I (11794) network: CONNECTED
I (11844) wifi:AP's beacon interval = 102400 us, DTIM period = 2
I (19724) event: sta ip: 192.168.0.237, mask: 255.255.255.0, gw: 192.168.0.1
I (19724) network: GOT_IP
Checking WiFi integrity.
Got reliable connection
Connecting to broker.
Connected to broker.
publish 0
publish 1

subtest

script

Subscribe to the topic named 'result' published by the ESP32 module and display it.

#! /bin/bash
mosquitto_sub -h 192.168.0.13 -t result
Shell output

Running status for the result topic.

0
1

pubtest

script

Publish two messages to the topic named 'foo_topic' which the ESP32 device is subscribed to,

#! /bin/bash
# mosquitto_sub -h 192.168.0.10 -t result
while :
do
    mosquitto_pub -h 192.168.0.13 -t foo_topic -m "gordon bennett" -q 1
    sleep 5
    mosquitto_pub -h 192.168.0.13 -t foo_topic -m "pete was here" -q 1
    sleep 5
done
ESP32 output

Show running status on the ESP32 and incoming subscription topics.

publish 103
(b'foo_topic', b'gordon bennett', False)
RAM free 94032 alloc 17136
publish 104
(b'foo_topic', b'pete was here', False)
publish 105

Resources

Project page

Documentation