В предыдущих двух сообщениях этой серии мы использовали Java на мини-компьютере Raspberry Pi для отправки данных датчиков в облако HiveMQ и визуализации их на панели инструментов.

Теперь мы собираемся добавить еще немного данных в нашу систему обмена сообщениями с другим членом семейства Raspberry Pi: Pico.

О Raspberry Pi Pico

В январе 2021 года был представлен Raspberry Pi Pico. Это совершенно новый тип платы, так как это не полноценный Linux-ПК, а микроконтроллер (RP2040), разработанный самой Raspberry Pi, на небольшой и универсальной плате. Этот RP2040 оснащен двухъядерным процессором Arm Cortex-M0+ с 264 КБ внутренней оперативной памяти и поддержкой до 16 МБ внешней флэш-памяти в сочетании с широким спектром GPIO (с поддержкой I2C, SPI и программируемого ввода-вывода (PIO)). . Так что это сравнимо с Arduino или аналогичной платой микроконтроллера. Но самый большой сюрприз этого Пико: цена всего 4$!

Фонд Raspberry Pi позаботился о том, чтобы при запуске платы был доступен очень обширный сайт документации. Программирование можно выполнять с помощью C/C++ и MicroPython SDK.

Pico предоставляет множество GPIO, которые очень хорошо сгруппированы, разделив их заземлением. Эти основания даже имеют различную форму на доске (без закругленных углов), чтобы было легче найти правильный контакт, который вы хотите использовать.

Пико проект

В этом посте мы расширим Pico модулем WiFi и одним датчиком расстояния, в качестве примера того, как вы можете легко отправлять данные датчиков в облако HiveMQ с этой недорогой платы. Чтобы достичь этой очень низкой цены, Pico не содержит беспроводных функций.

К счастью, есть разные возможности добавить Wi-Fi в Pico, из которых Adafruit AirLift ESP32 WiFi Co-Processor Breakout Board, вероятно, является самой простой и дешевой за 9,95 $. Дополнительным преимуществом продуктов Adafruit является большое количество документации, которую они предоставляют на своем веб-сайте.

В большинстве этих примеров используется другая «разновидность» MicroPython, называемая CircuitPython, которая основана на той же реализации Python, но в большей степени ориентирована на новичков, обучение и вводные руководства.

Проект в этом посте представляет собой комбинацию различных примеров из Adafruit:

Подготовьте Pico для CircuitPython

Давайте начнем с подготовки нашего Пико для этого урока. Нам нужно соединить компоненты, прошить CircuitPython на Pico, добавить библиотеки и загрузить наш код.

Электропроводка

Возьмите макетную плату и несколько проводов, чтобы создать эту небольшую тестовую установку.

Adafruit AirLift Wi-Fi

AirLift — это модуль Wi-Fi, который будет обеспечивать связь между Pico и HiveMQ Cloud. Нам нужно 8 проводов макетной платы, чтобы соединить оба компонента. Используя контакты с 10 по 15, мы группируем все соединения GPIO на одной стороне.

Важное замечание на веб-сайте Adafruit: Вы ДОЛЖНЫ использовать вывод VSYS Pico для питания AirLift Breakout.

Pico — AirLift
VSYS — Vin
GND — GND
GP10 (SPI1 SCK) — SCK
GP11 (SPI1 TX) — MOSI
GP12 (SPI1 RX) — MISO
GP13 (SPI1 CSn) — CS
GP14 — BUSY
GP15 — !RST

Датчик расстояния

Третий компонент на макетной плате — датчик расстояния HC-SR04, аналогичный тому, что используется в CrowPi. Здесь нам нужно 4 провода, а для GPIO мы используем другую сторону Pico.

Pico — HC-SR04
VBUS — Vcc
GND —GND
GP16 — ECHO
GP17 — TRIGGER

CircuitPython на Pico

Чтобы наш Pico поддерживал этот пример проекта CircuitPython, нам нужно загрузить правильную прошивку и добавить некоторые библиотеки.

Прошивка

Загрузите прошивку, которую необходимо установить на Pico, чтобы использовать его в качестве устройства CircuitPython. Этот файл .uf2 для Raspberry Pi Pico можно загрузить с circuitpython.org/board/raspberry_pi_pico.

Используйте USB-кабель (который не предназначен только для зарядки), нажмите и удерживайте кнопку BOOTSEL на Pico и подключите кабель между Pico и компьютером. Подождите, пока на вашем ПК не появится новый USB-накопитель «RPI-RP2», чтобы отпустить кнопку BOOTSEL.

Перетащите или скопируйте загруженный файл .uf2 на диск «RPI-RP2». Когда это будет сделано, этот диск исчезнет при перезагрузке Pico и снова появится как диск с именем «CIRCUITPY». Теперь ваш Pico готов к программированию с помощью CircuitPython.

Библиотеки

Чтобы упростить использование компонентов, весь набор библиотек доступен для одной загрузки на circuitpython.org/libraries. Загрузите ZIP-файл, распакуйте его на свой компьютер и скопируйте каталоги или файлы из следующего списка в каталог libs на диске CIRCUITPY.

  • adafruit_bus_device
  • adafruit_esp32_spi
  • адафрукт_hcsr04
  • adafruit_io
  • adafruit_minimqtt
  • adafruit_requests

IDE

Файлы кода можно записать непосредственно в Pico с помощью любого текстового редактора или IDE. Adafruit рекомендует использовать редактор Mu, так как это позволяет писать код и просматривать вывод приложения в одном инструменте. Вы можете скачать этот инструмент с codewith.mu.

Установите приложение на свой ПК, запустите его и выберите Mode › CircuitPython.

Код

Исходники этого приложения доступны на GitHub в том же репозитории, где вы можете найти исходники двух предыдущих постов.

Секреты

Чтобы отделить общий код от конкретных учетных данных WiFi и HiveMQ Cloud, используется отдельный файл. Создайте файл secrets.py и сохраните его на Pico со следующим содержимым, используя свой логин, пароль и т. д.

secrets = {
   'ssid' : 'WIFI_NETWORK_NAME',
   'password' : 'WIFI_PASSWORD',
   'timezone' : 'Europe/Brussels',
   'mqtt_username' : 'HIVEMQ_USERNAME',
   'mqtt_key' : 'HIVEMQ_PASSWORD',
   'broker' : 'YOUR_INSTANCE.hivemq.cloud',
   'port' : 8883
}

Основной код

Ниже вы найдете полный код для этого проекта. Я пытался объяснить каждый шаг, добавляя комментарии и принты. Создайте новый файл в Mu, скопируйте этот код и сохраните его в Pico как code.py.

import time
import board
import busio
import adafruit_hcsr04
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import adafruit_minimqtt.adafruit_minimqtt as MQTT

from digitalio import DigitalInOut
from adafruit_esp32spi import adafruit_esp32spi

# Load the WiFi and HiveMQ Cloud credentials from secrets.py
try:
    from secrets import secrets
except ImportError:
    print("Error, secrets could not be read")
    raise

# MQTT Topic to publish data from Pico to HiveMQ Cloud
topic_name = "pico/distance"

# Initialize the Pico pins, WiFi module and distance sensor
esp32_cs = DigitalInOut(board.GP13)
esp32_ready = DigitalInOut(board.GP14)
esp32_reset = DigitalInOut(board.GP15)
spi = busio.SPI(board.GP10, board.GP11, board.GP12)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
hcsr04 = adafruit_hcsr04.HCSR04(trigger_pin=board.GP17, echo_pin=board.GP16)

# Handle HTTP requests
requests.set_socket(socket, esp)

# Check ESP32 status
print("Checking ESP32")
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("\tESP32 found and in idle mode")
print("\tFirmware version: ", esp.firmware_version)
print("\tMAC address: ", [hex(i) for i in esp.MAC_address])

# List the detected WiFi networks
print("Discovered WiFi networks:")
for ap in esp.scan_networks():
    print("\t", (str(ap["ssid"], "utf-8")), "\t\tRSSI: ", ap["rssi"])

# Connect to the configured WiFi network
print("Connecting to WiFi: ", secrets["ssid"])
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except RuntimeError as e:
        print("\tCould not connect to WiFi: ", e)
        continue
print("\tConnected to ", str(esp.ssid, "utf-8"), "\t\tRSSI:", esp.rssi)
print("\tIP address of this board: ", esp.pretty_ip(esp.ip_address))
print("\tPing google.com: " + str(esp.ping("google.com")) + "ms")

# Configure MQTT to use the ESP32 interface
MQTT.set_socket(socket, esp)

# Configure MQTT client (uses secure connection by default)
mqtt_client = MQTT.MQTT(
    broker=secrets["broker"],
    port=secrets["port"],
    username=secrets["mqtt_username"],
    password=secrets["mqtt_key"]
)

# Define callback methods and assign them to the MQTT events
def connected(client, userdata, flags, rc):
    print("\tConnected to MQTT broker: ", client.broker)

def disconnected(client, userdata, rc):
    print("\tDisconnected from MQTT broker!")

def publish(mqtt_client, userdata, topic, pid):
    print("\tPublished a message to: ", topic)

mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_publish = publish

# Connect to the MQTT broker
print("Connecting to MQTT broker...")
try:
    mqtt_client.connect()
    print("\tSucceeded")
except Exception as e:
    print("\tMQTT connect failed: ", e)

# Continuously measure the distance and send the value to HiveMQ
print("Starting the distance measurement")
killed = False
while not killed:
    # Measure distance
    distance = 0
    try:
        distance = hcsr04.distance
    except Exception as e:
        print("Distance measurement failure\n", e)

    # Send to HiveMQ Cloud
    try:
        json = "{\"value\": " + str(distance) + "}"
        print("\tMessage for queue: " + json)
        mqtt_client.publish(topic_name, json)
    except Exception as e:
        print("\tMQTT publish Failed, retrying\n", e)
        killed = True
        continue

    # Sleep a second
    time.sleep(1)

Поскольку code.py является именем файла по умолчанию для основного кода, этот файл будет выполняться напрямую, или вы можете выполнить программный сброс платы с помощью CTRL+D в терминале Mu.

Вывод программы

В терминале Mu отображается вывод на печать.

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Checking ESP32
	ESP32 found and in idle mode
	Firmware version:  bytearray(b'1.2.2\x00')
	MAC address:  ['0x50', '0x18', '0x49', '0x95', '0xab', '0x34']
Discovered WiFi networks:
	 *****1 		RSSI:  -73
	 *****2 		RSSI:  -79
Connecting to WiFi:  *****1
	Connected to  *****1 		RSSI: -71
	IP address of this board:  192.168.0.189
	Ping google.com: 20ms
Connecting to MQTT broker...
	Connected to MQTT broker:  ***.s1.eu.hivemq.cloud
	Succeeded
Starting the distance measurement
	Message for queue: {"value": 106.777}
	Published a message to:  pico/distance
	Message for queue: {"value": 106.352}
	Published a message to:  pico/distance
	Message for queue: {"value": 107.202}

Добавление данных на нашу панель инструментов JavaFX

С небольшими изменениями теперь мы можем добавить данные сообщений Pico в наше приложение JavaFX, которое мы создали в предыдущем посте. Единственный файл, который необходимо изменить, это DashboardView.java.

Изменения кода

Сначала мы добавляем новую переменную:

private final Tile gaucheDistancePico;

Внутри конструктора мы инициализируем тайл, аналогичный существующим, и определяем подписку на тему, в которой Pico публикует свои измерения расстояния.

gaucheDistancePico = TileBuilder.create()
    .skinType(Tile.SkinType.GAUGE)
    .prefSize(TILE_WIDTH, TILE_HEIGHT)
    .title("Distance Pico")
    .unit("cm")
    .maxValue(255)
    .build();

client.toAsync().subscribeWith()
    .topicFilter("pico/distance")
    .qos(MqttQos.AT_LEAST_ONCE)
    .callback(this::handlePicoData)
    .send();

Последний дополнительный метод необходим для разбора полученных данных и обновления тайла:

public void handlePicoData(Mqtt5Publish message) {
    var sensorData = new String(message.getPayloadAsBytes());
    logger.info("Pico distance data: {}", sensorData);
    try {
        var sensor = mapper.readValue(sensorData, 
           DoubleValue.class);
        gaucheDistancePico.setValue(sensor.getValue());
    } catch (JsonProcessingException ex) {
        logger.error("Could not parse the data to JSON: {}", 
           ex.getMessage());
    }
}

Расширенный макет

С этими небольшими изменениями мы теперь увидим данные как CrowPi, так и Pico на одной панели.

Заключение

Raspberry Pi Pico — очень универсальное устройство по очень низкой цене. С дополнительным WiFi-модулем Adafruit вы можете легко добавить беспроводную связь. Тем временем уже доступно много новых плат на базе того же микроконтроллера RP2040, и некоторые из них даже имеют встроенный WiFi. Хороший обзор можно найти на tomshardware.com/best-picks/best-rp2040-boards.

HiveMQ Cloud — отличный (и бесплатный до 100 устройств!) способ поэкспериментировать с обменом сообщениями. В сочетании с Java, Raspberry Pi и электронными компонентами обмен данными между различными приложениями и устройствами становится очень простым.

Я надеюсь, что эти три поста помогут вам приступить к созданию собственного проекта!

Это сообщение было написано по запросу HiveMQ и первоначально было опубликовано в Блоге HiveMQ.