Python
На плате Графит-S3 предустановлен интерпретатор CircuitPython, который позволяет писать программы на упрощённом python.
Для работы с MQTT используем библиотеку adafruit_minimqtt. Всё, что нам нужно сделать для её установки — это скопировать файл adafruit_minimqtt.mpy в папку lib на накопителе CIRCUITPY.
Более подробно о работе с библиотеками CircuitPython мы писали в одном из ранних наших уроков: Библиотеки для CircuitPython
Программа
Для составления программы используем среду разработки Mu.
Пусть, тестовая программа будет каждые пять секунд отправлять MQTT брокеру значение обычного счётчика. Начнём с подключения всех необходимых библиотек. Помним, что в python это делается с помощью команды import.
Кроме adafruit_minimqtt нам будут нужны еще три библиотеки:
- time — предоставляет функцию sleep для организации паузы;
- wifi — нужен для работы с wifi;
- socketpool — нужен для работы с сетью, в принципе.
Итак, минимальная программа для отправки сообщений.
import time
import wifi
import socketpool
import adafruit_minimqtt.adafruit_minimqtt as MQTT
ssid = 'X-COM-CITADEL' # имя точки доступа WiFi
password = 'id7dq8d-' # пароль к точке доступа WiFi
mqtt_username = 'user_3ad51bab' # имя пользователя MQTT
mqtt_password = '************' # пароль пользователя MQTT
broker = 'mqtt.robotclass.ru' # адрес MQTT брокера
sensor_feed = 'user_3ad51bab/data'
print(f"Подключаемся к {ssid}...")
wifi.radio.connect(ssid, password)
print("успешно")
pool = socketpool.SocketPool(wifi.radio)
mqtt_client = MQTT.MQTT(
broker=broker,
username=mqtt_username,
password=mqtt_password,
client_id='user_3ad51bab_env',
socket_pool=pool
)
print(f"Подключаемся к MQTT брокеру {broker}...")
mqtt_client.connect()
print("успешно")
val = 0
while True:
print(f"Отправляем значение: {val}...")
mqtt_client.publish(sensor_feed, val)
print("успешно")
val += 1
time.sleep(5)
Загружаем программу на Графит-S3 и смотрим панель управления на смартфоне. Число в блоке data должно увеличиваться на единицу каждые 5 секунд.
А в мониторе последовательного порта среды Mu появится такой вывод:
Подключаемся к X-COM-CITADEL...
успешно
Подключаемся к MQTT брокеру mqtt.robotclass.ru...
успешно
Отправляем значение: 0...
успешно
Отправляем значение: 1...
успешно
Отправляем значение: 2...
Такой вывод означает, что сообщения были успешно отправлены брокеру MQTT.
Приём сообщений
Теперь изменим программу так, чтобы наше устройство смогло ещё и получать сообщения от MQTT брокера.
Пусть при нажатии кнопки в панели управления на плате Графит-S3 включается или выключается штатный светодиод.
Для начала напишем обработчики событий MQTT: подключение, отключение, получение сообщения. Эти функции-обработчики будут вызывать каждый раз, когда происходит соответствующее событие.
def connected(client, userdata, flags, rc):
# эта функция будет вызвана, когда клиент успешно подключится к брокеру
print(f"успешно подключен к брокеру")
# подписываемся на сообщения с указанной темой
client.subscribe(switch_feed)
def disconnected(client, userdata, rc):
# эта функция будет вызвана, когда клиент отключится от брокера
print("успешно отключен от брокера")
def message(client, topic, message):
# эта функция будет вызвана, когда клиент получит новое сообщение
print(f"пришло сообщение с темой {topic}: {message}")
Затем укажем их в настройках объекта mqtt_client.
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message
В суперцикл программы добавим вызов обработчика событий:
while True:
mqtt_client.loop(timeout=1)
Чтобы не пропустить события избавимся от явной паузы в суперцикле: time.sleep(5). Организуем отправку сообщений с помощью таймаута.
Итак, полный код программы:
import time
import board
from digitalio import DigitalInOut, Direction
import wifi
import socketpool
import adafruit_minimqtt.adafruit_minimqtt as MQTT
ssid = 'X-COM-CITADEL' # имя точки доступа WiFi
password = 'id7dq8d-' # пароль к точке доступа WiFi
mqtt_username = 'user_3ad51bab' # имя пользователя MQTT
mqtt_password = '************' # пароль пользователя MQTT
broker = 'mqtt.robotclass.ru' # адрес MQTT брокера
sensor_feed = 'user_3ad51bab/data'
switch_feed = 'user_3ad51bab/switch'
sensor_timeout = 5
sensor_next = 0
def connected(client, userdata, flags, rc):
# эта функция будет вызвана, когда клиент успешно подключится к брокеру
print(f"успешно подключен к брокеру")
# подписываемся на сообщения с указанной темой
client.subscribe(switch_feed)
def disconnected(client, userdata, rc):
# эта функция будет вызвана, когда клиент отключится от брокера
print("успешно отключен от брокера")
def message(client, topic, message):
# эта функция будет вызвана, когда клиент получит новое сообщение
print(f"пришло сообщение с темой {topic}: {message}")
led.value = message=="1" and 1 or 0
# настраиваем светодиод
led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
print(f"Подключаемся к {ssid}...")
wifi.radio.connect(ssid, password)
print("успешно")
pool = socketpool.SocketPool(wifi.radio)
mqtt_client = MQTT.MQTT(
broker=broker,
username=mqtt_username,
password=mqtt_password,
client_id='user_3ad51bab_env',
socket_pool=pool
)
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message
print(f"Подключаемся к MQTT брокеру {broker}...")
mqtt_client.connect()
val = 0
while True:
mqtt_client.loop(timeout=1)
t = time.monotonic()
if( t > sensor_next ):
sensor_next = t + sensor_timeout
print(f"Отправляем значение: {val}...")
mqtt_client.publish(sensor_feed, val)
print(f"успешно")
val += 1
Загружаем программу на Графит-S3 и открываем консоль интерпретатора.
Теперь при нажатии на кнопку на панели управления сработает функция-обработчик message и штатный светодиод зажжётся, а в консоли появится соответствующий текст:
Подключаемся к X-COM-CITADEL...
успешно
Подключаемся к MQTT брокеру mqtt.robotclass.ru...
успешно подключен к брокеру
Отправляем значение: 0...
успешно
Отправляем значение: 1...
успешно
Отправляем значение: 2...
успешно
пришло сообщение с темой user_3ad51bab/switch: 1
Отправляем значение: 3...
успешно
led.value = message==»1″ and 1 or 0
