Raspberry Pi

Raspberry Pi Sense HAT MQTT: Ortam ve IMU Verilerini Yayınlayın, LED Matriste Mesaj Gösterin

Bir Raspberry Pi Sense HAT'i çift yönlü bir MQTT cihazına dönüştürün: ortam ve yönelim okumalarını JSON olarak yayınlayın ve herhangi bir MQTT istemcisinden gönderilen mesajları 8x8 LED matris üzerinde kaydırın.

Bir raspberry pi sense hat mqtt projesinde buluta sensör verisi gönderirken LED matrisinde mesaj kaydıran Sense HAT'li Raspberry Pi
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Bir Raspberry Pi Sense HAT MQTT projesi, gerçek bir çift yönlü IoT cihazı yapmanın en hızlı yollarından biridir: kart zaten sıcaklık, nem ve basınç sensörleri, bir ivmeölçer, jiroskop ve manyetometre, bir joystick ve 8x8 RGB LED matris taşır. Bu eğitimde ortam ve IMU verilerini JSON olarak bir MQTT broker'a yayınlayacak ve Pi'ye gönderilen her mesajı LED matris üzerinde kaydıracaksınız; hepsi tek bir Python betiğinde.

Sense HAT Size Neler Sunar

Sensör veya çıkış Python çağrısı Birim
Sıcaklık sense.get_temperature() santigrat derece
Bağıl nem sense.get_humidity() yüzde
Basınç sense.get_pressure() milibar (hPa)
Yönelim sense.get_orientation() derece cinsinden pitch, roll, yaw
İvme sense.get_accelerometer_raw() g cinsinden x, y, z
Joystick sense.stick.get_events() yön ve eylem
LED matris sense.show_message(), sense.clear() 8x8 RGB

HAT, Pi 4 ve Pi 5 dahil 40 pinli başlığa sahip her Pi'nin başlığına doğrudan takılır. Kablolama gerekmez; bu da onu sınıflar, demolar ve hızlı prototipler için ideal kılar. Resmi Sense HAT dokümantasyonu donanımı derinlemesine ele alır.

Yazılımın Kurulumu

Sense HAT kütüphanesi bir Debian paketi olarak gelir. Onu sistem genelinde kurun, ardından onu görebilen bir sanal ortam oluşturun:

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"

Herhangi bir MQTT kodu yazmadan önce HAT'in algılandığını kontrol edin:

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

İki sayı görüyor ve matris üzerinde "OK" kaydığını izliyorsanız donanım hazırdır. Framebuffer veya I2C ile ilgili bir hata alırsanız, HAT'in tam oturduğunu ve sudo raspi-config içinde Interface Options altında I2C'nin etkin olduğunu doğrulayın.

Topic Düzeni

Paylaşımlı test broker'ındaki diğer kullanıcılarla hiçbir şeyin çakışmaması için Sense HAT topic'lerini benzersiz tek bir önek altında tutun:

Topic Yön Sıklık Retained
connectmq/demo/5d82be/sensehat/env Pi yayınlar Her 10 sn Hayır
connectmq/demo/5d82be/sensehat/imu Pi yayınlar Her 1 sn Hayır
connectmq/demo/5d82be/sensehat/joystick Pi yayınlar Olay anında Hayır
connectmq/demo/5d82be/sensehat/display Pi abone olur İsteğe bağlı Hayır
connectmq/demo/5d82be/sensehat/status Pi yayınlar ve last will Bağlanınca Evet

5d82be yerine kendi rastgele dizenizi yazın. Genel broker istemci başına saniyede 10 mesaja izin verir; bu yüzden saniyede bir IMU mesajı artı ara sıra ortam ve joystick olayları sınırın rahatça altında kalır.

Raspberry Pi Sense HAT MQTT Betiği

Önemli tasarım noktası, show_message() fonksiyonunun metin kayarken engelleme yapmasıdır. Onu MQTT geri çağırmasından çağırırsanız ağ döngüsü durur ve istemci keepalive'ları kaçırabilir. Aşağıdaki betik gelen mesajları bir kuyruğa koyar ve onları ayrı bir ekran iş parçacığının kaydırmasına izin verir; ana iş parçacığı ise sensörleri okur ve yayın yapar. sensehat_mqtt.py olarak kaydedin:

#!/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  # calibrate against a reference thermometer

sense = SenseHat()
sense.set_imu_config(True, True, True)  # compass, gyroscope, accelerometer
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()
    # The HAT sits above the CPU, so its sensors read warm. This simple
    # heuristic subtracts part of the difference; tune CPU_FACTOR for your case.
    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()
        # Poll orientation often so the sensor fusion stays accurate.
        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()

python sensehat_mqtt.py ile çalıştırın. Ana döngü yönelimi her 50 ms'de bir yoklar, çünkü Sense HAT'in sensör füzyonu pitch, roll ve yaw değerlerini kararlı tutmak için sık okumaya ihtiyaç duyar; ancak yalnızca saniyede bir yayın yapar.

LED Matrise Mesaj Gönderme

Herhangi bir makineden önce verilere abone olun:

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

Ardından düz metin veya renkli bir JSON mesajı gönderin:

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]}'

Sıcaklık ve yönelim akmaya devam ederken mesaj beyaz veya turuncu renkte kayar. Pi'yi eğin ve abone penceresinde pitch ile roll değerlerinin değiştiğini izleyin; olayların geldiğini görmek için joystick'e basın. Ekran topic'i bilerek retained yapılmamıştır; aksi halde son mesaj Pi her yeniden bağlandığında tekrar oynatılırdı.

Dürüst Sıcaklık Okumaları Almak

Sense HAT doğrudan işlemcinin üzerinde durur; bu yüzden sıcaklık sensörleri birkaç derece yüksek okur, yoğun çalışan bir Pi 4 veya Pi 5'te daha da fazla. Betik hem ham değeri hem de düzeltilmiş bir tahmini yayınlar. Düzeltmeyi kalibre etmek için:

  1. Pi'nin yanına güvenilir bir termometre yerleştirin ve ikisinin de 20 dakika boyunca dengelenmesini bekleyin.
  2. Referansı MQTT mesajlarındaki temperature_raw ve cpu_temp ile karşılaştırın.
  3. temperature referansla eşleşene kadar CPU_FACTOR değerini ayarlayın.
  4. Daha iyi doğruluk için HAT'i CPU'dan uzakta durması amacıyla 40 pinli bir şerit uzatma kablosuyla bağlayın.

Bir demo yerine hassas oda sıcaklığına ihtiyacınız varsa, özel bir prob daha iyi bir araçtır. MQTT ile Raspberry Pi DHT22 ve DS18B20 1-Wire prob rehberlerimiz harici sensörlerin aynı topic stiliyle nasıl yayınlanacağını gösterir.

Verileri Görselleştirmek

Her şey MQTT üzerinden kompakt JSON olarak taşındığından, her abone onu kullanabilir. Node-RED canlı bir gösterge çizebilir, Telegraf onu InfluxDB'ye yazabilir ve Grafana aylarca süren geçmişi grafiğe dökebilir; Raspberry Pi Grafana ve InfluxDB rehberi bu yığını kurar. Hiçbir şey kurmadan hızlıca bakmak için ConnectMQ portalındaki tarayıcı içi MQTT istemcisi ve canlı topic gezgini, her env ve imu mesajını geldiği anda gösterir.

Demodan Özel Broker'a

Genel MQTT test broker'ı herkes tarafından okunabilir; bu kayan bir selamlama için sorun değildir, ancak evinizdeki veya sınıfınızdaki bir sensör için uygun değildir. ConnectMQ size oluşturulmuş kimlik bilgileri ve TLS ile özel bir broker sunar. Dört ortam değişkenini ayarlayın; betik güvenli şekilde bağlanır:

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

Betiğin yeniden başlatmadan sonra da çalışmaya devam etmesi için onu Raspberry Pi MQTT eğitiminde gösterildiği gibi bir systemd servisine sarın.

Projeyi Genişletmek İçin Fikirler

Temel döngü çalıştığında Sense HAT, gerçek cihazlarda yeniden kullanacağınız MQTT desenleri için kullanışlı bir test tezgahına dönüşür:

  1. Eğim alarmı: ikinci bir betiğin imu topic'ine abone olmasını ve pitch veya roll bir sınırı aştığında bir uyarı yayınlamasını sağlayın; bu, hareket etmemesi gereken bir makineyi izlemenin basit bir karşılığıdır.
  2. Uzaktan durum panosu: bir CI hattından, bir ev otomasyonu akışından veya bir sunucu sağlık kontrolünden display topic'ine kısa durum dizeleri yayınlayın ve matrisi bir masa bildiricisi olarak kullanın.
  3. Uzaktan kumanda olarak joystick: Node-RED'den joystick topic'ine abone olun ve her yönü bir sahneye, bir röleye veya bir panel sayfasına eşleyin.
  4. Kod yazmadan eşik uyarıları: özel bir ConnectMQ broker'ında portalda env topic'inin nem değeri için bir uyarı kuralı ayarlayın ve tetiklenen uyarıları uyarı günlüğünde inceleyin.
  5. Birden fazla sınıf: her Pi'ye school/room12/sensehat gibi kendi önek seviyesini verin ve odaları yan yana karşılaştırmak için + joker karakteriyle abone olun.

Her fikir yalnızca yeni bir abone veya yeni bir topic gerektirir. Pi betiği aynı kalır; MQTT ile çalışmayı keyifli kılan da tam olarak bu ayrışmadır.

Sorun Giderme

  • OSError: Cannot detect RPi-Sense FB device: HAT algılanmıyor; Pi kapalıyken yeniden yerine oturtun.
  • Yaw kayıyor veya sıçrıyor: manyetometreyi kalibre edin ve Pi'yi motorlardan ve hoparlörlerden uzak tutun; yönelim ayrıca sık yoklama gerektirir.
  • Mesajlar kayıyor ama sensör verisi duruyor: bir şey ana döngüyü engelliyor; show_message() fonksiyonunu asla bir geri çağırmadan çağırmayın.
  • Nem 0 okunuyor: nem sensörü başlangıçtan sonra biraz zamana ihtiyaç duyar; ilk okumayı atın.

ConnectMQ ile Başlayın

Sense HAT'inizi birkaç dakika içinde genel test ortamından özel bir broker'a taşıyın. Kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun ve oluşturulan kimlik bilgileriyle TLS üzerinden bağlanın. MQTT 3.1.1 ve 5.0'ı destekleyen barındırılan bir MQTT broker ile birlikte ekran mesajları gönderebileceğiniz ve her okumayı canlı izleyebileceğiniz bir portal elde edersiniz.

Sık Sorulan Sorular

Sense HAT sıcaklığı neden oda sıcaklığından yüksek?

Raspberry Pi'nin işlemcisinden gelen ısı HAT'i ısıtır. Doğru okumalar için bu eğitimdeki CPU tabanlı düzeltmeyi, bir şerit uzatma kablosunu veya harici bir sensörü kullanın.

Sense HAT verilerini saniyede birden daha hızlı yayınlayabilir miyim?

Evet, ancak broker'ınızın hız sınırları içinde kalın; genel test broker'ı istemci başına saniyede 10 mesaja izin verir. Yüksek hızlı hareket verileri için birkaç örneği tek bir JSON mesajında toplayın.

Sense HAT, Raspberry Pi 5 üzerinde çalışır mı?

Evet, standart 40 pinli başlığı ve Raspberry Pi OS'taki sense-hat paketini kullanır. Pi 5 daha sıcak çalıştığından daha büyük sıcaklık sapmaları bekleyin.

LED matrise renkli metni nasıl gönderirim?

Ekran topic'ine {"text":"Hi","colour":[0,255,0]} gibi bir JSON yayınlayın. Betik rengi bir RGB listesi olarak okur ve düz metin için beyaza geri döner.

İlgili yazılar

RC522 Okuyucu ile Raspberry Pi RFID MQTT Erişim Kaydı

Bir RC522 RFID okuyucuyu Raspberry Pi'ye bağlayın, etiketleri Python ile okuyun, yerel bir izin listesiyle karşılaştırın ve her erişim denemesini kayıt araçlarının, panellerin ve uyarı araçlarının tüketebileceği bir MQTT olayı olarak yayınlayın.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.