Examples 3: MQTT Communication
micro:bit
 

 

MQTT (Message Queuing Telemetry Transport) is a widely used communication protocol that provides data exchange over the Internet. MQTT is a useful alternative to HTTP communication, especially for communication with microcontrollers and mobile devices where resources are scarce. MQTT also communicates via TCP, but very economically. In contrast to HTTP requests, which require a lot of data for the protocol header, the MQTT overhead is only a few bytes. In addition, clients do not need a fixed IP address and can be both sender and receiver. An MQTT client can publish information on a freely chosen topic. Other clients can subscribe to these topics. The central component of MQTT is a so-called MQTT broker, which manages the communication. The publisher sends his information to the broker, who forwards it to all subscribers. There is no automatic feedback to the publisher as to whether and who has actually read the information. The data is sent to the broker in real time and the broker forwards it immediately to the subscribers. This means that the data is not stored by the broker, as is the case with most cloud application.

Typically, the publisher is a microcontroller that collects measurement data, such as air temperature or other parameters of a system. It publishes the data periodically or triggered by specific event and the information can be retrieved by any number of subscribers. MQTT brokers can be found on the Internet, providing their services free of charge. For example, you can use the following hosts:

test.mosquitto.orgm2m.eclipse.org, broker.hivemq.com

The connection to one of these servers is established via a WLAN access point (SSID/password required)).

ex3_1

In this first example the micro:bit publishes sensor data from an environment sensor (temperature/humidity). Here one of the the precise Sensirion sensors SHT31, SHT35 or SHT85 is used, but any other sensor data (luminosity, vibration, PIR motion detection, etc.) could be published. The information is retrieved from the MQTT broker with a smartphone or a PC.

ex3_3

PublishEnviro.py creates the connection to the broker "broker.hivemq.com" via an access point and publishes the measured temperature and humidity under the topic /hb9abh/home/temp and /hb9abh/home/humi about every 10 seconds. The values are also shown as scroll text on micro:bit's LED matrix display.

# PublishEnviro.py

import mqtt
import sht
from microbit import *

host = "broker.hivemq.com"

while True:
    try:
        if mqtt.connectAP("raspilink", "aabbaabbaabb"):
            mqtt.broker(host)
            if mqtt.connect():
                while True:
                    temp, humi = sht.getValues() 
                    s = " : : %.1f - %.1f" % (temp, humi)
                    if not (mqtt.publish("/hb9abh/home/temp", "%.1f" % temp) and 
                            mqtt.publish("/hb9abh/home/humi", "%.1f%%" % humi)):
                        break
                    display.scroll(s)
                    sleep(10000)    
    except:
        sleep(5000)

As you see, the program is robust, e.g. runtime errors are detected by the return values of the mqtt functions and the connection is restarted at the top level

You can use an MQTT client application as a subscriber, which is installed on a PC or smartphone, e.g.
  ex3_4

To retrieve the data with a smartphone or PC, select the same broker and subscribe to the /hb9abh/home/temp and /hb9abh/home/temp topics with Add Subscriber.

ex3_5 ex3_6
Subscription with MQTTBox
with MQTTDash

In the next example MQTT is used to create a remote control system where the micro:bit receives commands to turn on a device. This can be a 12V LED lamp switched on by a relay such as the Grove device that uses very little actuating current and can be driven directly from a GPIO port. The micro:bit also publishes its state in regular intervals. As good side effect this keeps the connection to the broker open without the need to send "PING" requests.

wy3_7

The program sets P0 to 0 or 1 and shows a cross or a tick on the LED display.The micro:bit subscribes to the topic /hb9abh/lamp and listens for the payload "on" or "off" sent by any publisher (PC, tablet, smartphone, etc.). You can run it, even if you do not have P0 connected to a device. Instead of a relay you can also connect a small LED (with a serial resistor of about 470 Ohm).

The micro:bit periodically calls the function mqtt.receive() in a loop (here about every second), which returns the MQTT message as a tuple (topic, payload). Both are None if no message has arrived. (If several messages have arrived since the last call, they are stored in a receive buffer and the "oldest" message is returned for each call.). If mqtt.receive() returns None, the connection to the broker is lost.

# SubscribeSwitch.py

from microbit import *
import mqtt, sys

host = "broker.hivemq.com" 
topic_switch = "/hb9abh/lamp"
topic_state = "/hb9abh/lamp/state"
pin0.write_digital(0)
display.show(Image.NO)
while True:
    try:
        print("Connecting to AP...")      
        if mqtt.connectAP("raspilink", "aabbaabbaabb"):
            print("OK. Connecting to broker...")      
            mqtt.broker(host)
            if mqtt.connect():
                print("OK. Connection to broker established")      
                mqtt.subscribe(topic_switch)
                count = 0
                state = "OFF"
                while True:
                    count += 1
                    if count % 10 == 0:
                        print("Publishing topic:", topic_state, "payload:", state)
                        if not mqtt.publish(topic_state, state):
                            print("Error. Publish failed")
                            break
                    data = mqtt.receive()
                    if data == None:
                        print("Error. Connection to broker lost")
                        break    
                    topic, payload = data
                    if topic != None:
                        print("Got topic:", topic, "payload:", payload)
                        if payload == "on":
                            pin0.write_digital(1)
                            display.show(Image.YES)
                            state = "ON"
                        elif payload == "off":
                            pin0.write_digital(0)
                            display.show(Image.NO)
                            state = "OFF"
                    sleep(1000)
            else:
                print("Error. Broker unreachable")      
        else:
            print("Error. Can't connect to AP")      
    except Exception as e:
        sys.print_exception(e)


The program is quite long because it also writes state information to the console. It is robustly written, i.e. if an error occurs somewhere, the connection is restarted. If you use MQTTTDash on your smartphone, you can switch your device from anywhere in the world. The system has been successfully used to water the home garden during stays abroad. For such applications it is safer to use a non-public broker such as cloudmqtt.com.

ex3_8

To demonstrate the program logic, the error handling can be removed. The result is a highly simplified program.

# SubscribeSwitchSimple.py

from microbit import *
import mqtt

display.show(Image.NO)
mqtt.connectAP("myssid", "mypassword")
mqtt.broker("broker.hivemq.com")
mqtt.connect()
mqtt.subscribe("/hb9abh/lamp")
count = 0
state = "OFF"
while True:
    count += 1
    if count % 10 == 0:
        mqtt.publish("/hb9abh/lamp/state", state)
    data = mqtt.receive()
    topic, payload = data
    if topic != None:
        if payload == "on":
            pin0.write_digital(1)
            display.show(Image.YES)
            state = "ON"
        elif payload == "off":
            pin0.write_digital(0)
            display.show(Image.NO)
            state = "OFF"
    sleep(1000)