Raspberry Pi Pico W + MQTT + HC SR04
Finalmente sono arrivati i Raspberry Pi Pico W. La "W" sta per Wi-Fi o forse Wireless.
Ho iniziato a fare le prime prove scaricando gli esempi e compilandoli.
Se anche tu stai pensando di "giocare" con i Raspberry Pi Pico W sappi che non troverai molta documentazione!
Ne esiste un po per Phyton, ma davvero pochissima per C/C++.
Il repository ufficiale per l'sdk e gli esempi sono:
I primi esperimenti che ho fatto sono stati compilare gli esempi in C/C++ e farli girare sul "Pico W". Non ho avuto particolari problemi se non quelli relativi alla configurazione di Visual Studio Code e tool vari.
Subito dopo ho provato a fare una semplicissima richiesta HTTP. Non esiste un esempio e/o una libreria pronta all'uso e quindi bisogna costruire la richiesta HTTP e inviarla tramite TCP.
La questione si complica nel momento in cui ho voluto provare a fare una richiesta HTTPS. Immagino che l'unica soluzione sarebbe partire da un libreria di Arduino o ESP8266 (o altro) e riadattarla per il Raspberry Pi Pico W.
Per ora non avendo ne tempo e ne voglia, ho provato a fare lo stesso esperimento con Python. Non conosco Python e non è mai troppo tardi per imparare. Ho utilizzato Thonny per iniziare a prendere la mano con Python, dal semplice Blink sono passato a esempi più complessi.
Mi sono posto un obbiettivo. Interfacciare il Raspberry Pi Pico con un sensore ad ultrasuoni HC SR-04, visualizzare la distanza su un piccolo display ST7789 e inviare la distanza dell'oggetto rilevato tramite MQTT ad un'applicazione desktop fatta in C#.
In realtà avrei potuto utilizzare MQTT anche su HTTP e non su HTTPS, ma va davvero contro i miei principi :P
Le librerie che ho utilizzato sono:
import uos
import machine
from machine import Pin
import st7789py as st7789
import vga2_8x8 as font1
import vga1_16x32 as font2
import random
import network
import time
import urequests
from umqtt.simple import MQTTClient
Determinazione della distanza con Raspberry PI Pico W e HC SR04
trig = Pin(14, Pin.OUT)
echo = Pin(15, Pin.IN, Pin.PULL_DOWN)
Print su display ST7789
Il display che ho utilizzato è un ST7789 240x240 acquistato su AliExpress per qualche euro.

Per gestire il display ho utilizzato https://github.com/devbis/st7789py_mpy che contiene:
- st7789py
- vga2_8x8
- vga1_16x32
Il codice è il seguente:
spi1_sck=10
spi1_mosi=11
spi1_miso=8
st7789_res = 12
st7789_dc = 13
disp_width = 240
disp_height = 240
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)
display = st7789.ST7789(spi1, disp_width, disp_width,
reset=machine.Pin(st7789_res, machine.Pin.OUT),
dc=machine.Pin(st7789_dc, machine.Pin.OUT),
rotation=0)
display.fill(st7789.BLACK)
display.text(font2, "TEST!", 10, 10)
Invio pacchetto MQTT tramite Raspberry Pi Pico W
Prima di tutto devi registrarti su HiveMQ - Enterprise ready MQTT to move your IoT data
Dopo la registrazione è necessario creare un cluster:

Al cluster va aggiunta una utenza che poi sarà utilizzata per inviare e ricevere i pacchetti:

Adesso passiamo al codice.
La libreria che ho utilizzato umqtt.simple, può essere installata da Thonny (Strumenti -> Gestion Pacchetti).
mqttssl_params= {"server_hostname": "17XXXXXXXXXXXXXX85.s2.eu.hivemq.cloud" }
broker = '17XXXXXXXXXXXXXX85.s2.eu.hivemq.cloud'
mqttport=8883
mqttuser='gimqtttest1'
mqttpassword='LA_PASSWORD'
client_id = 'unclientidacaso'
sub_topic = 'subtopic/1'
pub_topic = 'testtopic/distance'
def sub_cb(topic, msg):
print((topic, msg))
def connect_and_subscribe():
global client_id, mqtt_server, topic_sub
client = MQTTClient(client_id, broker, port=mqttport, user=mqttuser , password=mqttpassword,keepalive=0,ssl=True,ssl_params=mqttssl_params)
client.set_callback(sub_cb)
client.connect()
client.subscribe(sub_topic)
print('Connected to %s MQTT broker as client ID: %s, subscribed to %s topic' % (broker, client_id, sub_topic))
return client
def restart_and_reconnect():
print('Failed to connect to MQTT broker. Reconnecting...')
time.sleep 10)
machine.reset()
try:
client = connect_and_subscribe()
except OSError as e:
restart_and_reconnect()
pub_msg = 'Hello! Sono il rasberry1!'
client.publish(pub_topic, pub_msg)
Applicazione desktop (C#) per la ricezione del pacchetto MQTT
Per riceve e visualizzare la distanza che il Raspberry Pico W invia ho creato una applicazione WPF in C#.
Prima di tutto è nesessario importare i 2 pacchetti nuget relativi alla libreria MQTTnet:

Il codice C# è il seguente:
private async void BtnTest_Click(object sender, RoutedEventArgs e)
{
try
{
await Handle_Received_Application_Message();
}
catch (Exception ex)
{
LogError(ex.ToString());
}
}
public async Task Handle_Received_Application_Message()
{
var mqttFactory = new MqttFactory();
var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(Constants.MqttUrl, Constants.MqttPort)
.WithCredentials(Constants.MqttUsername, Constants.MqttPassword)
.WithTls(
o =>
{
o.CertificateValidationHandler = eventArgs =>
{
return true;
};
})
.Build();
mqttClient.ApplicationMessageReceivedAsync += e =>
{
Log("Received application message.");
Log("Topic: " + e.ApplicationMessage.Topic);
var payload = System.Text.ASCIIEncoding.ASCII.GetString(e.ApplicationMessage.Payload);
Log("Payload: " + payload);
SetDistance(payload);
return Task.CompletedTask;
};
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(f => { f.WithTopic("testtopic/distance"); })
//.WithTopicFilter(f => { f.WithTopic("mqttnet/samples/topic/2"); })
//.WithTopicFilter(f => { f.WithTopic("mqttnet/samples/topic/2"); })
.Build();
await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Log("MQTT client subscribed to topic.");
}
Ecco la breadbord:

Buon divertimento!
Se hai voglia di lasciarmi un commento mi trovi su Linkedin.