Raspberry Pi

Raspberry Pi Sense HAT et MQTT : publier les données d'environnement et de l'IMU, afficher des messages sur la matrice LED

Transformez un Raspberry Pi Sense HAT en objet MQTT bidirectionnel : publiez les mesures d'environnement et d'orientation en JSON, et faites défiler sur la matrice LED 8x8 les messages envoyés depuis n'importe quel client MQTT.

Raspberry Pi équipé d'un Sense HAT faisant défiler un message sur sa matrice LED tout en envoyant des données de capteurs vers le cloud via MQTT
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Un projet Raspberry Pi Sense HAT MQTT est l'un des moyens les plus rapides de construire un véritable objet IoT bidirectionnel : la carte embarque déjà des capteurs de température, d'humidité et de pression, un accéléromètre, un gyroscope et un magnétomètre, un joystick et une matrice LED RVB 8x8. Dans ce tutoriel, vous allez publier les données d'environnement et de l'IMU en JSON vers un broker MQTT et faire défiler sur la matrice LED tout message envoyé au Pi, le tout dans un seul script Python.

Ce que vous apporte le Sense HAT

Capteur ou sortie Appel Python Unités
Température sense.get_temperature() degrés Celsius
Humidité relative sense.get_humidity() pourcentage
Pression sense.get_pressure() millibar (hPa)
Orientation sense.get_orientation() tangage, roulis, lacet en degrés
Accélération sense.get_accelerometer_raw() x, y, z en g
Joystick sense.stick.get_events() direction et action
Matrice LED sense.show_message(), sense.clear() RVB 8x8

Le HAT s'enfiche directement sur le connecteur 40 broches de tout Pi qui en est équipé, y compris les Pi 4 et Pi 5. Aucun câblage n'est nécessaire, ce qui le rend idéal pour les salles de classe, les démonstrations et les prototypes rapides. La documentation officielle du Sense HAT détaille le matériel.

Installer les logiciels

La bibliothèque du Sense HAT est fournie sous forme de paquet Debian. Installez-la au niveau du système, puis créez un environnement virtuel qui peut la voir :

sudo apt update
sudo apt install -y sense-hat python3-venv
mkdir -p ~/sensehat-mqtt && cd ~/sensehat-mqtt
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0"

Vérifiez que le HAT est détecté avant d'écrire le moindre code MQTT :

python -c "from sense_hat import SenseHat; s = SenseHat(); print(s.get_temperature(), s.get_humidity()); s.show_message('OK')"

Si deux nombres s'affichent et que « OK » défile sur la matrice, le matériel est prêt. Si vous obtenez une erreur concernant le framebuffer ou l'I2C, vérifiez que le HAT est bien enfoncé et que l'I2C est activé dans sudo raspi-config, sous Interface Options.

Organisation des topics

Regroupez les topics du Sense HAT sous un préfixe unique afin d'éviter toute collision avec les autres utilisateurs du serveur de test partagé :

Topic Sens Fréquence Retained
connectmq/demo/5d82be/sensehat/env Le Pi publie Toutes les 10 s Non
connectmq/demo/5d82be/sensehat/imu Le Pi publie Toutes les 1 s Non
connectmq/demo/5d82be/sensehat/joystick Le Pi publie Sur événement Non
connectmq/demo/5d82be/sensehat/display Le Pi s'abonne À la demande Non
connectmq/demo/5d82be/sensehat/status Le Pi publie, plus le last will À la connexion Oui

Remplacez 5d82be par votre propre chaîne aléatoire. Le serveur public autorise 10 messages par seconde et par client : un message IMU par seconde plus quelques événements d'environnement et de joystick restent largement sous cette limite.

Le script Raspberry Pi Sense HAT MQTT

Le point de conception important est que show_message() est bloquant pendant le défilement du texte. Si vous l'appelez depuis le callback MQTT, la boucle réseau se fige et le client peut manquer des keepalives. Le script ci-dessous place les messages entrants dans une file d'attente et laisse un thread d'affichage séparé les faire défiler, tandis que le thread principal lit les capteurs et publie. Enregistrez-le sous sensehat_mqtt.py :

#!/usr/bin/env python3
"""Publish Sense HAT data over MQTT and show incoming messages on the LED matrix."""
import json
import os
import queue
import threading
import time
import uuid

import paho.mqtt.client as mqtt
from sense_hat import SenseHat

BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"sensehat-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/5d82be/sensehat")
ENV_INTERVAL = 10
IMU_INTERVAL = 1
CPU_FACTOR = 2.0  # à calibrer avec un thermomètre de référence

sense = SenseHat()
sense.set_imu_config(True, True, True)  # boussole, gyroscope, accéléromètre
sense.low_light = True
messages = queue.Queue(maxsize=20)


def cpu_temperature():
    with open("/sys/class/thermal/thermal_zone0/temp") as f:
        return int(f.read()) / 1000.0


def corrected_temperature():
    raw = sense.get_temperature_from_humidity()
    cpu = cpu_temperature()
    # Le HAT est placé au-dessus du CPU, ses capteurs mesurent donc trop chaud. Cette
    # heuristique simple soustrait une partie de l'écart ; ajustez CPU_FACTOR selon votre cas.
    return raw - (cpu - raw) / CPU_FACTOR, raw


def display_worker():
    while True:
        text, colour = messages.get()
        try:
            sense.show_message(text, scroll_speed=0.06, text_colour=colour)
        finally:
            sense.clear()


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connection refused: {reason_code}")
        return
    print(f"Connected as {CLIENT_ID}")
    client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
    client.subscribe(f"{PREFIX}/display", qos=1)


def on_message(client, userdata, msg):
    raw = msg.payload.decode(errors="ignore").strip()
    colour = [255, 255, 255]
    text = raw
    if raw.startswith("{"):
        try:
            data = json.loads(raw)
            text = str(data.get("text", ""))
            colour = data.get("colour", colour)
        except json.JSONDecodeError:
            pass
    text = text[:80]
    if text:
        try:
            messages.put_nowait((text, colour))
        except queue.Full:
            print("Display queue full, dropping message")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
    client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
    client.tls_set()

threading.Thread(target=display_worker, daemon=True).start()
client.connect(BROKER, PORT, keepalive=30)
client.loop_start()

last_env = 0.0
last_imu = 0.0
try:
    while True:
        now = time.time()
        # Interroger souvent l'orientation pour que la fusion de capteurs reste précise.
        orientation = sense.get_orientation()

        if now - last_imu >= IMU_INTERVAL:
            accel = sense.get_accelerometer_raw()
            imu = {
                "pitch": round(orientation["pitch"], 1),
                "roll": round(orientation["roll"], 1),
                "yaw": round(orientation["yaw"], 1),
                "ax": round(accel["x"], 3),
                "ay": round(accel["y"], 3),
                "az": round(accel["z"], 3),
                "ts": int(now),
            }
            client.publish(f"{PREFIX}/imu", json.dumps(imu), qos=0)
            last_imu = now

        if now - last_env >= ENV_INTERVAL:
            temp, raw_temp = corrected_temperature()
            env = {
                "temperature": round(temp, 1),
                "temperature_raw": round(raw_temp, 1),
                "humidity": round(sense.get_humidity(), 1),
                "pressure": round(sense.get_pressure(), 1),
                "cpu_temp": round(cpu_temperature(), 1),
                "ts": int(now),
            }
            client.publish(f"{PREFIX}/env", json.dumps(env), qos=1)
            last_env = now

        for event in sense.stick.get_events():
            if event.action == "pressed":
                payload = {"direction": event.direction, "ts": int(event.timestamp)}
                client.publish(f"{PREFIX}/joystick", json.dumps(payload), qos=1)

        time.sleep(0.05)
except KeyboardInterrupt:
    pass
finally:
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
    client.loop_stop()
    client.disconnect()
    sense.clear()

Lancez-le avec python sensehat_mqtt.py. La boucle principale interroge l'orientation toutes les 50 ms, car la fusion de capteurs du Sense HAT a besoin de lectures fréquentes pour garder le tangage, le roulis et le lacet stables, mais elle ne publie qu'une fois par seconde.

Envoyer des messages à la matrice LED

Depuis n'importe quelle machine, abonnez-vous d'abord aux données :

mosquitto_sub -h broker.connectmq.com -p 1883 -i viewer-5d82be \
  -t 'connectmq/demo/5d82be/sensehat/#' -v

Envoyez ensuite du texte brut ou un message JSON avec une couleur :

mosquitto_pub -h broker.connectmq.com -p 1883 -i sender-5d82be \
  -t 'connectmq/demo/5d82be/sensehat/display' -m 'Hello from MQTT'

mosquitto_pub -h broker.connectmq.com -p 1883 -i sender-5d82be \
  -t 'connectmq/demo/5d82be/sensehat/display' \
  -m '{"text":"Door open","colour":[255,80,0]}'

Le message défile en blanc ou en orange pendant que la température et l'orientation continuent d'être transmises. Inclinez le Pi et observez le tangage et le roulis changer dans la fenêtre de l'abonné ; appuyez sur le joystick pour voir arriver les événements. Le topic d'affichage n'est volontairement pas retained : sinon, le dernier message serait rejoué à chaque reconnexion du Pi.

Obtenir des mesures de température fiables

Le Sense HAT est placé juste au-dessus du processeur : ses capteurs de température affichent donc plusieurs degrés de trop, davantage encore sur un Pi 4 ou un Pi 5 chargé. Le script publie à la fois la valeur brute et une estimation corrigée. Pour calibrer la correction :

  1. Placez un thermomètre fiable à côté du Pi et laissez les deux se stabiliser pendant 20 minutes.
  2. Comparez la référence avec temperature_raw et cpu_temp dans les messages MQTT.
  3. Ajustez CPU_FACTOR jusqu'à ce que temperature corresponde à la référence.
  4. Pour plus de précision, raccordez le HAT via une nappe d'extension 40 broches afin de l'éloigner du CPU.

Si vous avez besoin d'une température ambiante précise plutôt que d'une démo, une sonde dédiée est l'outil adapté. Nos guides sur le Raspberry Pi avec DHT22 et MQTT et la sonde 1-Wire DS18B20 montrent comment publier des capteurs externes avec le même style de topics.

Visualiser les données

Comme tout transite en JSON compact via MQTT, n'importe quel abonné peut l'exploiter. Node-RED peut tracer une jauge en direct, Telegraf peut écrire les données dans InfluxDB, et Grafana peut afficher des mois d'historique ; le guide Raspberry Pi avec Grafana et InfluxDB construit cette pile. Pour un coup d'œil rapide sans rien installer, le client MQTT intégré au navigateur et l'explorateur de topics en direct du portail ConnectMQ affichent chaque message env et imu dès son arrivée.

De la démo au broker privé

Le serveur MQTT public gratuit est lisible par tous, ce qui convient pour un message d'accueil qui défile, mais pas pour un capteur installé dans votre maison connectée ou votre salle de classe. ConnectMQ vous fournit un broker privé avec des identifiants générés et TLS. Définissez quelques variables d'environnement et le script se connecte de façon sécurisée :

export MQTT_HOST=broker.connectmq.com
export MQTT_PORT=8883
export MQTT_USERNAME=YOUR_USERNAME
export MQTT_PASSWORD=YOUR_PASSWORD
export MQTT_CLIENT_ID=YOUR_CLIENT_ID
export MQTT_PREFIX=classroom/lab1/sensehat
python sensehat_mqtt.py

Pour que le script continue de tourner après un redémarrage, encapsulez-le dans un service systemd comme le montre le tutoriel MQTT sur Raspberry Pi.

Idées pour aller plus loin

Une fois la boucle de base fonctionnelle, le Sense HAT devient un banc d'essai pratique pour des modèles MQTT que vous réutiliserez sur de vrais appareils :

  1. Alarme d'inclinaison : faites s'abonner un second script au topic imu pour publier un avertissement quand le tangage ou le roulis dépasse une limite, une façon simple de simuler la surveillance d'une machine qui ne doit pas bouger.
  2. Tableau de statut à distance : publiez de courts messages d'état depuis un pipeline CI, un scénario domotique ou un contrôle de santé de serveur vers le topic display, et utilisez la matrice comme notificateur de bureau.
  3. Joystick comme télécommande : abonnez-vous au topic joystick depuis Node-RED et associez chaque direction à une scène, un relais ou une page de tableau de bord.
  4. Alertes à seuil sans code : sur un broker ConnectMQ privé, définissez dans le portail une règle d'alerte sur la valeur d'humidité du topic env et consultez les alertes déclenchées dans le journal des alertes.
  5. Plusieurs salles de classe : attribuez à chaque Pi son propre niveau de préfixe, comme school/room12/sensehat, et abonnez-vous avec le joker + pour comparer les salles côte à côte.

Chaque idée ne demande qu'un nouvel abonné ou un nouveau topic. Le script du Pi reste identique : c'est précisément ce découplage qui rend MQTT si agréable à utiliser.

Dépannage

  • OSError: Cannot detect RPi-Sense FB device : le HAT n'est pas détecté ; réinstallez-le, Pi hors tension.
  • Le lacet dérive ou saute : calibrez le magnétomètre et éloignez le Pi des moteurs et des haut-parleurs ; l'orientation exige aussi une interrogation fréquente.
  • Les messages défilent mais les données des capteurs s'arrêtent : quelque chose bloque la boucle principale ; n'appelez jamais show_message() depuis un callback.
  • L'humidité affiche 0 : le capteur d'humidité a besoin d'un instant après le démarrage ; ignorez la première mesure.

Démarrer avec ConnectMQ

Faites passer votre Sense HAT du bac à sable public à un broker privé en quelques minutes. Créez un broker Serverless gratuit, sans carte bancaire, et connectez-vous en TLS avec les identifiants générés. Vous disposez d'un broker MQTT managé qui prend en charge MQTT 3.1.1 et 5.0, ainsi que d'un portail où vous pouvez envoyer des messages d'affichage et suivre chaque mesure en direct.

Questions fréquentes

Pourquoi la température du Sense HAT est-elle supérieure à celle de la pièce ?

La chaleur du processeur du Raspberry Pi réchauffe le HAT. Utilisez la correction basée sur le CPU de ce tutoriel, une nappe d'extension, ou un capteur externe pour des mesures précises.

Puis-je publier les données du Sense HAT plus d'une fois par seconde ?

Oui, mais restez dans les limites de débit de votre broker ; le serveur de test public autorise 10 messages par seconde et par client. Pour des données de mouvement à haute fréquence, regroupez plusieurs échantillons dans un seul message JSON.

Le Sense HAT fonctionne-t-il sur un Raspberry Pi 5 ?

Oui, il utilise le connecteur 40 broches standard et le paquet sense-hat de Raspberry Pi OS. Attendez-vous à des écarts de température plus importants, car le Pi 5 chauffe davantage.

Comment envoyer du texte en couleur à la matrice LED ?

Publiez un JSON comme {"text":"Hi","colour":[0,255,0]} sur le topic d'affichage. Le script lit la couleur sous forme de liste RVB et revient au blanc pour du texte brut.

Articles liés

Journal d'accès RFID MQTT sur Raspberry Pi avec le lecteur RC522

Câblez un lecteur RFID RC522 sur un Raspberry Pi, lisez les badges en Python, vérifiez-les dans une liste blanche locale et publiez chaque tentative d'accès sous forme d'événement MQTT exploitable par vos outils de journalisation, tableaux de bord et alertes.

8 min de lecture

Installer Mosquitto sur Raspberry Pi comme broker MQTT local sécurisé

Installez Mosquitto sur un Raspberry Pi, sécurisez-le avec des mots de passe et une configuration de listener raisonnable, testez-le avec mosquitto_pub et mosquitto_sub, et découvrez quand un broker local doit faire un pont vers un broker cloud.

9 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.