Raspberry Pi

Raspberry Pi LoRa MQTT Alıcısı: SX127x Paketlerini Buluta İletin

RFM95 veya SX127x HAT ile Raspberry Pi üzerinde noktadan noktaya LoRa paketleri alın, radyo ayarlarını vericilerinizle eşleştirin ve her paketi JSON olarak bir MQTT broker'a yeniden yayınlayın.

Uzun menzilli paketleri alan LoRa radyo kartı ve antenli Raspberry Pi, raspberry pi lora mqtt kullanımını gösteriyor
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

Raspberry Pi LoRa MQTT alıcısı, Wi-Fi için fazla uzaktaki sensörlerden veri toplamanın en basit yoludur: bir tarla, bir çiftlik, bir otopark ya da büyük bir sahanın en uç noktası. Bu eğitimde SX127x tabanlı bir radyoyu (RFM95W, RFM96W veya bir LoRa bonnet) Pi'ye bağlayacak, kendi vericilerinizden noktadan noktaya paketler alacak ve her birini JSON olarak bir MQTT broker'a yeniden yayınlayacaksınız. broker.connectmq.com ile başlayıp üretime hazır bir kurulumla bitireceksiniz.

Noktadan Noktaya LoRa ve LoRaWAN

LoRa bir radyo modülasyonudur; LoRaWAN ise onun üzerine kurulmuş, cihaz kaydı, şifreleme anahtarları, bir ağ sunucusu ve çok kanallı gateway'ler içeren tam bir ağ protokolüdür. Zaten bir LoRaWAN ağı işletiyorsanız, ağ sunucunuz uplink'leri MQTT'ye yayınlar ve bunun yerine ChirpStack MQTT entegrasyonuna ihtiyacınız vardır.

Noktadan noktaya LoRa bunların hepsini atlar. Vericiniz (genellikle SX1276 modüllü bir ESP32 veya Arduino) sabit bir frekansta sabit ayarlarla küçük bir paket gönderir ve tek kanallı bir alıcı onu duyar. Anlaşılması kolaydır ve tamamen sizin kontrolünüzdedir; bu da onu her iki ucun da size ait olduğu hobi projeleri, prototipler ve özel sensör ağları için uygun kılar. Bunun bedeli; adreslemeyi, bütünlük kontrollerini ve görev döngüsü (duty cycle) sınırlarını kendinizin yönetmesidir.

Donanım

Parça Notlar
Raspberry Pi 40 pinli başlığa sahip herhangi bir model; bir Zero 2 W yeterlidir
SX127x radyo Adafruit LoRa Radio Bonnet, RFM95W breakout veya benzeri bir SPI modülü
Anten Bandınıza göre ayarlanmış; asla antensiz yayın yapmayın
Verici düğüm ESP32, Arduino veya eşleşen radyolu ikinci bir Pi
Frekans Avrupa'da 868 MHz, Kuzey Amerika'da 915 MHz, bazı bölgelerde 433 MHz; yerel kurallara uyun

Bir breakout kartın kablolaması SPI pinlerini izler: SCK'yi GPIO 11'e, MOSI'yi GPIO 10'a, MISO'yu GPIO 9'a, CS'yi CE1'e (GPIO 7), RESET'i GPIO 25'e, ayrıca 3,3 V ve toprağı bağlayın. Adafruit bonnet tam olarak bu pinleri kullanır; aşağıdaki kodun varsayılan olarak bunları kullanmasının nedeni budur.

Kütüphaneleri Kurun

sudo raspi-config ile SPI'ı etkinleştirin (Interface Options, SPI), ardından Linux üzerinde board ve busio modüllerini sağlayan Adafruit Blinka'yı ve RFM9x sürücüsünü içeren bir ortam oluşturun:

sudo raspi-config nonint do_spi 0
ls /dev/spidev*
python3 -m venv ~/lora/.venv
source ~/lora/.venv/bin/activate
pip install adafruit-blinka adafruit-circuitpython-rfm9x "paho-mqtt>=2.0"

Adafruit sitesindeki Blinka kurulum rehberi, bazı Pi modelleri için ek adımlar listeler; örneğin yeni sürümlerde lgpio kurulumu. import board başarısız olursa, devam etmeden önce o rehberi izleyin.

Radyo Ayarlarını Eşleştirin

Bir LoRa alıcısı yalnızca aynı frekans, yayılma faktörü (spreading factor), bant genişliği, kodlama oranı, senkronizasyon kelimesi ve önsözle (preamble) gönderilen paketleri duyar. Uyuşmazlık hata üretmez; sessizlik üretir. Ayarları bir kez yazın ve her iki tarafta da kullanın.

Ayar Örnek değer Notlar
Frekans 868,1 MHz Bölgenizde yasal olmalıdır
Yayılma faktörü 7 Yüksek değer daha uzun menzil, daha yavaş yayın süresi demektir
Bant genişliği 125 kHz Yaygın varsayılan
Kodlama oranı 4/5 Sürücüde 5 olarak ayarlanır
CRC Açık Verici ve alıcıda etkinleştirin
Başlık Vericiye bağlı Aşağıdaki RadioHead notuna bakın

RadioHead başlığı tuzağı. Adafruit RFM9x sürücüsü RadioHead kuralını izler ve varsayılan olarak alınan paketlerden 4 baytlık bir başlığı (to, from, id, flags) kırpar. Sandeep Mistry'nin Arduino LoRa kütüphanesini kullanan vericiler bu başlığı eklemez; bu yüzden payload'unuzun ilk dört baytı sessizce kaybolur. Vericiniz RadioHead kullanmıyorsa, aşağıdaki betikte olduğu gibi receive(with_header=True) çağırın.

Raspberry Pi LoRa MQTT Betiği

Bu örnekteki verici, n1,21.4,63,3.92 gibi kısa bir metin payload'u gönderir (düğüm kimliği, sıcaklık, nem, pil voltajı). Alıcı bunu doğrular, radyo meta verilerini ekler ve düğüm başına bir topic'e yayınlar. Bilinmeyen veya hatalı paketler sessizce atılmak yerine hata ayıklama için ayrı bir ham topic'e gider.

import json
import os
import time
import uuid

import adafruit_rfm9x
import board
import busio
import digitalio
import paho.mqtt.client as mqtt

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"lora-rx-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("TOPIC_PREFIX", "connectmq/demo/l9r3x5/lora")
FREQ_MHZ = float(os.getenv("LORA_FREQ", "868.1"))

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.CE1)
reset = digitalio.DigitalInOut(board.D25)
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, FREQ_MHZ)
rfm9x.spreading_factor = 7
rfm9x.signal_bandwidth = 125000
rfm9x.coding_rate = 5
rfm9x.enable_crc = True


def on_connect(client, userdata, flags, reason_code, properties):
    print("MQTT connected:", reason_code)
    client.publish(f"{PREFIX}/receiver/status", "online", qos=1, retain=True)


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


def parse(text):
    parts = text.split(",")
    if len(parts) != 4 or not parts[0].startswith("n"):
        return None
    node, temp, hum, vbat = parts
    return node, {"temperature": float(temp), "humidity": float(hum), "vbat": float(vbat)}


print(f"listening on {FREQ_MHZ} MHz")
try:
    while True:
        packet = rfm9x.receive(timeout=5.0, with_header=True)
        if packet is None:
            continue
        meta = {"rssi": rfm9x.last_rssi, "snr": rfm9x.last_snr, "ts": int(time.time())}
        try:
            parsed = parse(packet.decode("ascii").strip())
        except (UnicodeDecodeError, ValueError):
            parsed = None
        if parsed:
            node, values = parsed
            client.publish(f"{PREFIX}/{node}", json.dumps({**values, **meta}), qos=1, retain=True)
            print(node, values, meta)
        else:
            client.publish(f"{PREFIX}/raw", json.dumps({"hex": packet.hex(), **meta}), qos=0)
except KeyboardInterrupt:
    pass
finally:
    client.publish(f"{PREFIX}/receiver/status", "offline", qos=1, retain=True)
    client.loop_stop()
    client.disconnect()

Arduino LoRa kütüphanesini kullanan bir ESP32 vericide eşleşen yapılandırma LoRa.begin(868.1E6), LoRa.setSpreadingFactor(7), LoRa.setSignalBandwidth(125E3), LoRa.setCodingRate4(5) ve LoRa.enableCrc() şeklindedir. Ardından LoRa.beginPacket(); LoRa.print("n1,21.4,63,3.92"); LoRa.endPacket(); ile gönderin.

Sonuçları herhangi bir makineden izleyin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i lora-viewer-l9r3x5 -t "connectmq/demo/l9r3x5/lora/#" -v

Paketleri Sağlamlaştırmak

Düz metinde hata ayıklamak kolaydır ama yayın süresini (airtime) boşa harcar; LoRa'da kıt kaynak da yayın süresidir. Bağlantı çalıştığında şu iyileştirmeleri düşünün:

  1. İkili payload'lar. Değerleri sabit ölçeklemeyle paketleyin; örneğin sıcaklığı yüzde birlik hassasiyetle int16 olarak. 4 alanlı bir okuma yaklaşık 16 bayttan 7 bayta iner; bu da yayın süresini kısaltır ve pil ömrünü uzatır.
  2. Düğüm kimliği ve sıra numarası. Bir sıra sayacı, alıcının kaçırılan ve yinelenen paketleri tespit etmesini sağlar; ayrıca düğüm başına paket kaybını ayrı bir metrik olarak raporlamanıza olanak tanır.
  3. Bütünlük. Radyo CRC'si bozulmayı yakalar. Komşular aynı ayarlarla yayın yapabilecekse, size ait olmayan paketleri yok saymak için kısa bir tanımlayıcı veya bir HMAC ekleyin.
  4. Görev döngüsü. Birçok bölge, bir cihazın bir alt bantta saatte ne kadar süre yayın yapabileceğini kısıtlar. Uzun yayılma faktörleri ve sık gönderimler bu sınırı hızla aşabilir; bu yüzden payload'ları küçük, aralıkları makul tutun.
  5. Alıcı sağlığı. Alıcıdan bir heartbeat yayınlayın ve düğüm başına son görülme zamanını izleyin; böylece ölü bir verici ile ölü bir alıcı panelinizde farklı görünür.

Her paketle yayınlanan SNR ve RSSI değerleri, anten yerleşimi için en iyi aracınızdır. Pozitif SNR rahat bir bağlantı demektir; yayılma faktörünüzün hassasiyet sınırına yaklaşan değerler ise menzilin sınırında olduğunuzu gösterir.

Gözetimsiz Çalıştırma

Bir ahır duvarındaki veya direkteki alıcı, elektrik kesintilerini ve ağ kopmalarını atlatabilmelidir. Betiği otomatik olarak yeniden başlaması için bir systemd servisi olarak çalıştırın, uplink kesikken okumaları SQLite'ta çevrimdışı MQTT arabelleği ile yerel olarak saklayın ve SD kart yıpranması ile güç kaynakları için Raspberry Pi güvenilirlik ipuçlarını izleyin. Hücresel bağlantılı uzak sahalar için MQTT iyi bir seçimdir, çünkü bağlantı yalnızca dışa doğrudur ve protokol ek yükü küçüktür.

Test Broker'ından Ayrılmak

Genel MQTT test broker'ı radyo bağlantısını doğru kurmak için mükemmeldir, ancak orada yayınlanan her şey herkes tarafından görülebilir. Gerçek bir kurulum için ConnectMQ üzerinde bir broker oluşturun, portaldan oluşturulan kullanıcı adını, parolayı ve client ID'yi alın ve alıcıyı ortamda MQTT_PORT=8883 ve bu değerlerle başlatın. TLS bir Let's Encrypt sertifikası kullanır; bu yüzden tls_set() Pi'nin varsayılan CA deposuyla çalışır. Bir bulut MQTT broker, farklı sahalardaki birden fazla alıcının, panellerinizin ve uyarı kurallarınızın tek bir yerden okuyabileceği tek bir topic ağacına yayın yapmasını da sağlar.

Pi'de MQTT'ye yeni mi başlıyorsunuz? Raspberry Pi MQTT eğitimi burada kullanılan temelleri anlatır; Raspberry Pi IoT gateway rehberi ise bir LoRa alıcısının tek bir cihaz üzerinde BLE, Modbus ve diğer girişlerle nasıl birlikte çalışabileceğini gösterir.

LoRa Verilerinizi ConnectMQ'ya Gönderin

app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun; alıcınız için TLS kimlik bilgilerine dakikalar içinde sahip olursunuz. ConnectMQ'nun canlı topic gezgini her düğümü raporladığı anda gösterir; eşik tabanlı uyarı kuralları da bir sınırı aşan sıcaklık veya pil değerini işaretleyebilir.

Sık Sorulan Sorular

Tek bir SX127x alıcısı LoRaWAN gateway olarak çalışabilir mi?

Tam anlamıyla hayır. LoRaWAN gateway'leri, SX1302 gibi konsantratör yongaları kullanarak aynı anda birden fazla kanalı ve yayılma faktörünü dinler. Tek bir SX127x bir seferde tek bir yapılandırmayı duyar; bu da noktadan noktaya kullanıma uygundur.

Ne kadar menzil bekleyebilirim?

Menzil büyük ölçüde anten yüksekliğine, araziye ve yayılma faktörüne bağlıdır. Yükseltilmiş antenlerle görüş hattı, binaların içinden geçmeye göre çok daha uzağa ulaşır; bu yüzden RSSI ve SNR'yi sahada ölçün.

Alıcım neden eksik baytlı paketler alıyor?

Neredeyse her zaman RadioHead başlığı uyuşmazlığından. Verici 4 baytlık RadioHead başlığını eklemiyorsa receive(with_header=True) kullanın.

Pi düğümlere geri komut gönderebilir mi?

Evet, RFM9x sürücüsü yayın yapabilir. Bir komut topic'ine abone olun ve rfm9x.send() çağırın; ancak düğümlerin o anda dinliyor olması gerektiğini unutmayın; pille çalışan vericiler genellikle yalnızca yayın yaptıktan hemen sonra kısa bir süre dinler.

İ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.