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 :
- Placez un thermomètre fiable à côté du Pi et laissez les deux se stabiliser pendant 20 minutes.
- Comparez la référence avec
temperature_rawetcpu_tempdans les messages MQTT. - Ajustez
CPU_FACTORjusqu'à ce quetemperaturecorresponde à la référence. - 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 :
- Alarme d'inclinaison : faites s'abonner un second script au topic
imupour 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. - 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. - Joystick comme télécommande : abonnez-vous au topic
joystickdepuis Node-RED et associez chaque direction à une scène, un relais ou une page de tableau de bord. - 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
envet consultez les alertes déclenchées dans le journal des alertes. - 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.



