embedded-deck
LoRaWAN — Uzun Menzilli IoT Ağı · embedded-deck embedded-deck
GÖMÜLÜ NETWORK LORAWAN IoT 2026

LoRaWAN
uzun menzilli IoT ağı.

Chirp Spread Spectrum radyo teknolojisinden MAC katmanı protokolüne. Semtech SX1276 sürücüsünden TTN ve ChirpStack entegrasyonuna. Uçtan uca LoRaWAN sistemi kurun.

00 LoRa ve LoRaWAN farkı

LoRa ve LoRaWAN sıkça birbirinin yerine kullanılır, ancak farklı katmanlara aittir. LoRa fiziksel katman (PHY) radyo teknolojisiyken, LoRaWAN bu radyo üzerine inşa edilmiş MAC protokolü ve ağ mimarisidir.

LoRa — fiziksel katman

LoRa, Semtech Corporation tarafından geliştirilen ve patentlenmiş bir radyo modülasyon tekniğidir. Chirp Spread Spectrum (CSS) modülasyonu kullanır. Bir "chirp", belirli bir bant genişliği boyunca frekansın yukarı veya aşağı süpürüldüğü bir sinyaldir.

CSS'nin temel avantajı gürültüye dayanıklılığıdır. Sinyal gürültü oranı (SNR) -20 dB'nin altına düşse bile alıcı paketi başarıyla çözebilir. Bu özellik, birkaç km'lik kentsel veya onlarca km'lik açık alan mesafelerine olanak tanır.

LoRa lisanssız ISM bantlarında çalışır: Avrupa'da 863–870 MHz, Kuzey Amerika'da 902–928 MHz, Asya'da 915–928 MHz veya 470–510 MHz.

LoRaWAN — MAC protokolü

LoRaWAN, LoRa radyo üzerine inşa edilen Katman 2 protokolüdür. LoRa Alliance tarafından standartlaştırılmaktadır. MAC katmanı şunları tanımlar: adres yönetimi, şifreleme (AES-128), oturum anahtarı türetme, frekans planları, çalışma modları (Class A/B/C) ve ağ bileşenleri arasındaki mesaj formatları.

  OSI Katmanları — LoRaWAN
  ┌──────────────────────────────────┐
  │  Uygulama Katmanı (App Server)   │  ← sensör verisi
  ├──────────────────────────────────┤
  │  LoRaWAN MAC (Network Server)    │  ← ADR, join, downlink
  ├──────────────────────────────────┤
  │  LoRa PHY (Chirp SS modülasyon) │  ← SF, BW, CR, frekans
  ├──────────────────────────────────┤
  │  RF (ISM bandı, lisanssız)       │  ← 868/915 MHz
  └──────────────────────────────────┘
    
ÖZET

LoRa = Semtech'in radyo çipi ve modülasyon tekniği. LoRaWAN = bu radyo üzerine LoRa Alliance'ın tanımladığı açık standart MAC protokolü ve ağ mimarisi. Bir analogya: LoRa = Ethernet PHY, LoRaWAN = Ethernet MAC + IP.

01 LoRa RF temelleri

LoRa bağlantısının performansını belirleyen üç temel parametre vardır: Spreading Factor (SF), bant genişliği (BW) ve kodlama oranı (CR). Bu parametreler birbirine bağlı tradeoff'lar içerir.

Spreading Factor (SF) — yayma faktörü

SF7 ile SF12 arasında değer alır. Yüksek SF değeri daha fazla işleme kazancı sağlar; daha uzun menzil ve gürültüye daha fazla direnç. Ancak sembol süresi ve dolayısıyla hava üzerinde geçen süre (Time on Air, ToA) üssel olarak artar. SF12, SF7'ye göre yaklaşık 64 kat daha uzun ToA'ya sahiptir.

SFBit hızı (BW 125 kHz)Alıcı HassasiyetiMenzil (kentsel)ToA (50B paket)
SF75470 bps-123 dBm~2 km~56 ms
SF83125 bps-126 dBm~3 km~103 ms
SF91757 bps-129 dBm~5 km~185 ms
SF10977 bps-132 dBm~8 km~370 ms
SF11537 bps-134.5 dBm~12 km~741 ms
SF12293 bps-137 dBm~15–20 km~1482 ms

Bant genişliği (BW)

Standart değerler 125 kHz, 250 kHz ve 500 kHz'dir. Daha geniş BW daha hızlı bit oranı sağlar ancak alıcı hassasiyetini düşürür. Avrupa frekans planında çoğunlukla 125 kHz kullanılır.

Kodlama oranı (CR)

CR 4/5, 4/6, 4/7 veya 4/8 değerlerini alır. CR 4/8 en güçlü hata düzeltmeyi sağlar, ancak veri oranını düşürür. LoRaWAN genellikle CR 4/5 kullanır.

Link budget hesabı

link budget formülü
Link Budget (dB) = TX Güç - Kablo Kayıpları + TX Anten Kazancı
                 + RX Anten Kazancı - Alıcı Hassasiyeti

Örnek (SX1276, SF12, 125 kHz):
  TX Güç           = +20 dBm  (SX1276 max)
  TX Anten         = +2 dBi   (dipole)
  Kablo kayıpları  = -1 dB
  RX Hassasiyet    = -137 dBm (SF12)
  RX Anten         = +2 dBi

  Link Budget = 20 - 1 + 2 + 2 - (-137) = 160 dB

Serbest alan yol kaybı (FSPL) formülü:
  FSPL(dB) = 20*log10(d) + 20*log10(f) + 92.45
  (d=km, f=GHz)

  868 MHz, 10 km: FSPL = 20*log10(10) + 20*log10(0.868) + 92.45
                       = 20 + (-1.23) + 92.45 = 111.2 dB

  Link margin = 160 - 111.2 = 48.8 dB  → güçlü bağlantı

ADR — Adaptive Data Rate

LoRaWAN Network Server, her cihazın sinyal kalitesini izler ve bağlantı koşullarına göre SF ve TX gücünü otomatik ayarlar. Yakın cihazlara SF7 verilerek kanal kapasitesi artırılır, uzak cihazlar SF12 kullanmaya devam eder. Bu özellik ağ kapasitesini önemli ölçüde artırır.

02 LoRaWAN mimarisi

LoRaWAN, yıldız topolojisine dayalı dört bileşenli bir mimariye sahiptir. End device'lar gateway'e, gateway'ler ağ sunucusuna, ağ sunucusu ise uygulama sunucusuna bağlanır.

  ┌────────────┐   LoRa RF    ┌──────────────┐   TCP/IP    ┌───────────────┐
  │ End Device │─────────────▶│   Gateway    │────────────▶│ Network Server│
  │ (Sensor)  │              │  (Concentr.) │  (UDP/TLS)  │ (TTN/ChirpSt.)│
  └────────────┘              └──────────────┘             └───────┬───────┘
                                                                   │ MQTT/HTTP
  ┌─────────────────────────────────────────────────────────────── │ ──────┐
  │                    End Device                                   │       │
  │  Sensör → LoRa modem → RF →                                    ▼       │
  │  AES-128 şifreli payload                          ┌────────────────┐   │
  │  DevAddr + MIC                                    │ App Server     │   │
  │                                                   │ (decode/store) │   │
  └───────────────────────────────────────────────────└────────────────┘───┘

  Gateway'ler "şeffaf" aktarıcıdır — içeriği çözemez, sadece iletir.
  Şifre çözme Network Server'da yapılır (AppSKey ile payload şifresi).
    

End Device (son cihaz)

Sensör veya aktüatör içeren, pil ile çalışan IoT cihazı. LoRa modem (SX1276/SX1278 veya entegre çip) içerir. Uygulama verisi AES-128 ile şifrelenir. LoRaWAN MAC çerçevesi oluşturulur ve RF üzerinden gönderilir.

Gateway (ağ geçidi)

LoRa RF sinyallerini alır ve IP paketlerine dönüştürür. Genellikle SX1301/SX1302 multichannel concentrator chip kullanır; 8 kanalı aynı anda dinleyebilir. İçeriği şifreyi çözemez, sadece iletir. Ethernet veya LTE üzerinden Network Server'a bağlanır.

Network Server

LoRaWAN protokolünün beynidir. Görevleri: duplicate paket eleme (birden fazla gateway aynı paketi alabilir), ADR yönetimi, join prosedürü, downlink zamanlama ve güvenlik anahtarı yönetimi. TTN (The Things Network) ve ChirpStack en popüler açık kaynak çözümlerdir.

Application Server

Şifresi çözülmüş payload'u alır, decode eder (CayenneLPP, özel format) ve uygulamaya iletir. MQTT, HTTP webhook veya doğrudan veritabanı yazma yöntemleri kullanılır.

Paket yönlendirme
Gateway, Semtech UDP Packet Forwarder veya Gateway Bridge (MQTT) protokolünü kullanır.
Güvenlik katmanları
Ağ güvenliği (NwkSKey) ve uygulama güvenliği (AppSKey) birbirinden bağımsızdır. Gateway içeriği göremez.
Multi-gateway
Birden fazla gateway aynı cihazı duyabilir. NS en iyi RSSI/SNR'ye sahip gateway'i seçer.

03 Device sınıfları

LoRaWAN üç farklı cihaz sınıfı tanımlar. Her sınıf farklı enerji tüketimi ve downlink alım kapasitesi dengesi sunar.

SınıfDownlink alımıGüç tüketimiGecikmeTipik kullanım
Class AHer uplink sonrası 2 RX penceresiEn düşükYüksek (bir sonraki uplink'e kadar)Sensörler, pil cihazları
Class BBeacon ile senkronize periyodik RXOrtaOrta (beacon dönemi)Aktüatörler, kısmen pil
Class CSürekli RX (sadece TX sırasında kapalı)En yüksekÇok düşükŞebeke bağlı aktüatörler

Class A — Tüm cihazların uyması zorunlu temel sınıf

Her cihaz Class A'yı desteklemek zorundadır. Cihaz uplink gönderdiğinde iki alım penceresi açılır:

  Uplink gönder
  ──────────────────────────────▶ RF TX
                                  │
                      RX1 Delay   │  (1 saniye sonra)
                                  ├──────────────────▶ RX Pencere 1
                                  │                    (aynı frekans, farklı SF)
                      RX2 Delay   │  (2 saniye sonra)
                                  └──────────────────▶ RX Pencere 2
                                                       (869.525 MHz, SF12 — Avrupa)

  Network Server RX1'de yanıt verirse RX2 açılmaz.
  Her iki pencerede de yanıt gelmezse cihaz uyku moduna geçer.
    

Class B — Beacon senkronizasyonu

Gateway, belirli aralıklarla (128 saniye) beacon sinyali yayınlar. Cihaz beacon'a senkronize olur ve öngörülebilir ping slot'larında alıcısını açar. Network Server hangi slot'ta paket göndereceğini bilir; bu nedenle gecikme Class A'ya göre düşüktür.

Class C — Sürekli alıcı

Cihaz sadece uplink gönderirken alıcıyı kapatır, diğer tüm zamanlarda RX2 penceresini dinler. Şebeke beslemeli sensörler ve hızlı komut yanıtı gerektiren aktüatörler (kapı kilitleri, aydınlatma kontrol) için uygundur.

04 Aktivasyon — OTAA ve ABP

Bir LoRaWAN cihazı ağa iki yöntemle katılabilir: Over-The-Air Activation (OTAA) ve Activation By Personalization (ABP). Güvenlik açısından OTAA tercih edilir.

OTAA — Over-The-Air Activation

  Cihaz                    Network Server
    │                           │
    │── JoinRequest ───────────▶│
    │   DevEUI + AppEUI         │
    │   + AppKey ile MIC        │
    │                           │  AppKey ile doğrula
    │                           │  NwkSKey + AppSKey türet
    │◀─ JoinAccept ─────────────│
    │   DevAddr + NetID         │
    │   + AppKey ile şifreli    │
    │                           │
    │  NwkSKey ve AppSKey       │
    │  her session'da farklı    │
    │  (forward secrecy!)       │
    
DevEUI
64-bit benzersiz cihaz tanımlayıcısı. MAC adresi benzeri, üretici tarafından atanır.
AppEUI / JoinEUI
64-bit uygulama tanımlayıcısı. TTN/ChirpStack konsolundan alınır.
AppKey
128-bit kök anahtar. Cihazda güvenli depolanmalı (güvenli eleman önerilir). Ağda asla açık gitmez.
NwkSKey
Join'dan türetilen ağ oturum anahtarı. MIC hesaplama için kullanılır.
AppSKey
Join'dan türetilen uygulama oturum anahtarı. Payload şifrelemesi için kullanılır.

ABP — Activation By Personalization

DevAddr, NwkSKey ve AppSKey üretim sırasında cihaza yazılır. Join prosedürü yoktur; cihaz hemen iletişime başlar. Dezavantajı: anahtarlar sabittir, ele geçirilirse tüm geçmiş ve gelecek trafik deşifre edilebilir. Güvenli başlatma ortamı olmayan basit projeler için sınırlı kullanım önerilir.

ABP konfigürasyonu örneği
/* ABP parametreleri — üretimde güvenli depolama kullanın! */
#define DEVADDR   0x26011234   /* 32-bit, NS tarafından atanır */
#define NWKSKEY   { 0x2B,0x7E,0x15,0x16,0x28,0xAE,0xD2,0xA6, \
                    0xAB,0xF7,0x15,0x88,0x09,0xCF,0x4F,0x3C }
#define APPSKEY   { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, \
                    0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }

OTAA vs ABP karşılaştırması

ÖzellikOTAAABP
GüvenlikYüksek (her session farklı anahtar)Düşük (sabit anahtarlar)
Kurulum kolaylığıOrta (join prosedürü)Kolay
Güç kesintisi sonrasıYeniden join gerekebilirHemen çalışır
Frame sayacıJoin'da sıfırlanırGüç kesintisinde sorun
Üretim tavsiyesiÖnerilenYalnızca basit projeler

05 Semtech SX1276 Linux sürücüsü

SX1276, LoRa modülasyonunu destekleyen en yaygın Semtech çipidir. Linux'ta SPI üzerinden iletişim kurulur. Resmi kernel sürücüsü yoktur; userspace SPI-dev veya topluluk kütüphaneleri kullanılır.

SX1276 SPI bağlantısı — Raspberry Pi

  Raspberry Pi        SX1276 / LoRa Modül (RFM95)
  ┌───────────┐       ┌────────────────────────┐
  │ 3.3V      │──────▶│ VCC                    │
  │ GND       │──────▶│ GND                    │
  │ GPIO 11   │──────▶│ SCK  (SPI Clock)       │
  │ GPIO 10   │──────▶│ MOSI (SPI Master Out)  │
  │ GPIO 9    │◀──────│ MISO (SPI Master In)   │
  │ GPIO 8    │──────▶│ NSS  (Chip Select)     │
  │ GPIO 22   │──────▶│ RESET                  │
  │ GPIO 4    │◀──────│ DIO0 (TX/RX Done IRQ)  │
  │ GPIO 17   │◀──────│ DIO1 (RX Timeout IRQ)  │
  └───────────┘       └────────────────────────┘
    

SPI etkinleştirme

SPI etkinleştirme adımları
## /boot/config.txt veya raspi-config ile SPI aç
echo "dtparam=spi=on" >> /boot/config.txt
reboot

## SPI aygıtını doğrula
ls /dev/spidev*
# /dev/spidev0.0  /dev/spidev0.1

## SPI hızını test et
spi-config -d /dev/spidev0.0 -s 1000000 -q

pySX127x ile Python örneği

lora_rx.py — LoRa alıcı
#!/usr/bin/env python3
"""
pip install RPi.GPIO spidev pySX127x
"""
from SX127x.LoRa import *
from SX127x.board_config import BOARD

BOARD.setup()

class LoRaReceiver(LoRa):
    def __init__(self, verbose=False):
        super().__init__(verbose)
        self.set_mode(MODE.SLEEP)
        self.set_dio_mapping([0] * 6)

    def start(self):
        self.reset_ptr_rx()
        self.set_mode(MODE.RXCONT)    # sürekli alım

        print("Dinleniyor... (Ctrl+C ile dur)")
        while True:
            pass   # IRQ callback beklenir

    def on_rx_done(self):
        print("\n--- Paket alındı ---")
        payload = self.read_payload(nocheck=True)
        print(f"Payload : {bytes(payload).hex()}")
        print(f"RSSI    : {self.get_pkt_rssi_value()} dBm")
        print(f"SNR     : {self.get_pkt_snr_value()} dB")
        self.set_mode(MODE.SLEEP)
        self.reset_ptr_rx()
        self.set_mode(MODE.RXCONT)

lora = LoRaReceiver(verbose=False)

# SF9, BW 125 kHz, CR 4/5
lora.set_freq(868.1)            # MHz
lora.set_spreading_factor(9)
lora.set_bw(BW.BW125)
lora.set_coding_rate(CODING_RATE.CR4_5)
lora.set_preamble(8)
lora.set_rx_crc(True)

try:
    lora.start()
except KeyboardInterrupt:
    lora.set_mode(MODE.SLEEP)
    BOARD.teardown()
    print("\nDurduruldu.")

SX1302 — yeni nesil concentrator

Gateway'ler için SX1301 yerine SX1302 kullanılmaktadır. Raspberry Pi HAT'larında (RAK2287, WM1302) yaygındır. Linux sürücüsü sx1302_hal kütüphanesi üzerinden kullanılır.

sx1302_hal kurulumu
git clone https://github.com/Lora-net/sx1302_hal.git
cd sx1302_hal
make

## Örnek packet forwarder yapılandırması
cp tools/reset_lgw.sh .
cp packet_forwarder/global_conf.json.sx1250.EU868 \
   packet_forwarder/global_conf.json

## Gateway EUI al
./packet_forwarder/lora_pkt_fwd -c packet_forwarder/global_conf.json

06 The Things Network v3

The Things Stack (TTN v3) en yaygın kullanılan ücretsiz LoRaWAN ağ sunucusudur. Bulut tabanlı çalışır; kendi sunucunuza da kurabilirsiniz.

Uygulama ve cihaz kaydı

TTN CLI ile cihaz kaydı
## ttn-lw-cli kurulumu ve giriş
brew install ttn-lw-cli   # macOS
ttn-lw-cli login

## Uygulama oluştur
ttn-lw-cli applications create \
    --application-id my-sensor-app \
    --name "Sensör Uygulaması"

## OTAA cihazı kaydet
ttn-lw-cli end-devices create \
    --application-id my-sensor-app \
    --device-id sensor-01 \
    --dev-eui 0011223344556677 \
    --app-eui 70B3D57ED0000000 \
    --app-key AABBCCDDEEFF00112233445566778899 \
    --lorawan-version MAC_V1_0_2 \
    --frequency-plan-id EU_863_870_TTN

MQTT Data API

mqtt_subscribe.py — TTN MQTT
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import json, base64

APP_ID    = "my-sensor-app"
API_KEY   = "NNSXS.xxx..."   # TTN konsolundan al
TTN_HOST  = "eu1.cloud.thethings.network"

def on_connect(client, userdata, flags, rc):
    print(f"Bağlandı: {rc}")
    client.subscribe(f"v3/{APP_ID}@ttn/devices/+/up")

def on_message(client, userdata, msg):
    data = json.loads(msg.payload)
    dev_id  = data["end_device_ids"]["device_id"]
    raw_b64 = data["uplink_message"]["frm_payload"]
    payload = base64.b64decode(raw_b64)
    rssi    = data["uplink_message"]["rx_metadata"][0]["rssi"]
    snr     = data["uplink_message"]["rx_metadata"][0]["snr"]

    print(f"[{dev_id}] payload={payload.hex()}  RSSI={rssi}  SNR={snr}")

client = mqtt.Client()
client.username_pw_set(f"{APP_ID}@ttn", API_KEY)
client.tls_set()
client.on_connect = on_connect
client.on_message = on_message
client.connect(TTN_HOST, 8883, 60)
client.loop_forever()

Payload decoder — JavaScript / CayenneLPP

payload_decoder.js — TTN formatter
// TTN Console → Application → Payload Formatters → Uplink
function decodeUplink(input) {
    var bytes = input.bytes;
    var decoded = {};

    // Özel format: [2B sıcaklık x10, 2B nem x10, 2B basınç x10]
    if (bytes.length >= 6) {
        decoded.temperature = ((bytes[0] << 8) | bytes[1]) / 10.0;
        decoded.humidity    = ((bytes[2] << 8) | bytes[3]) / 10.0;
        decoded.pressure    = ((bytes[4] << 8) | bytes[5]) / 10.0;
    }

    return {
        data: decoded,
        warnings: [],
        errors: []
    };
}

// CayenneLPP için hazır çözüm:
// npm install cayennelpp
// TTN konsolunda "CayenneLPP" seçeneği doğrudan kullanılabilir.
TTN FREQUENCİ PLANLARI

Türkiye Avrupa frekans planını (EU868) kullanır. TTN Avrupa kümesi eu1.cloud.thethings.network adresindedir. Her gün 30 saniye uplink ve 10 downlink süresiyle "fair use policy" uygulanır. Yoğun ticari kullanım için kendi TTN Stack'inizi kurun.

07 ChirpStack

ChirpStack, açık kaynak bir LoRaWAN network server stack'idir. Kendi altyapınızda çalıştırabilirsiniz. TTN'ye alternatif olarak tam kontrol sağlar.

Docker ile hızlı kurulum

docker-compose.yml — ChirpStack stack
version: "3"

services:
  chirpstack:
    image: chirpstack/chirpstack:4
    environment:
      - POSTGRESQL__DSN=postgres://chirpstack:chirpstack@postgresql/chirpstack?sslmode=disable
      - REDIS__SERVERS[0]=redis://redis:6379
      - NETWORK__NET_IDS[0]=000000
      - REGIONS[0]=eu868
    ports:
      - "8080:8080"     # Web UI
    depends_on:
      - postgresql
      - redis

  chirpstack-gateway-bridge:
    image: chirpstack/chirpstack-gateway-bridge:4
    ports:
      - "1700:1700/udp"   # Gateway UDP
    environment:
      - INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }}

  postgresql:
    image: postgres:14
    environment:
      - POSTGRES_PASSWORD=chirpstack
      - POSTGRES_USER=chirpstack
      - POSTGRES_DB=chirpstack
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7
    volumes:
      - redisdata:/data

  mosquitto:
    image: eclipse-mosquitto:2
    ports:
      - "1883:1883"

  grafana:
    image: grafana/grafana:10
    ports:
      - "3000:3000"
    volumes:
      - grafanadata:/var/lib/grafana

volumes:
  pgdata:
  redisdata:
  grafanadata:
ChirpStack başlatma
docker compose up -d

## Web UI
xdg-open http://localhost:8080
## Varsayılan giriş: admin / admin

## Gateway kaydı için EUI gerekli:
## Gateway → "Add gateway" → Gateway EUI gir

## MQTT topic izle
mosquitto_sub -h localhost -t "eu868/gateway/#" -v

gRPC API ile cihaz yönetimi

chirpstack_api.py — Python gRPC
#!/usr/bin/env python3
"""
pip install chirpstack-api grpcio
"""
import grpc
from chirpstack_api import api

server  = "localhost:8080"
api_key = "eyJ0..."  # ChirpStack API key

channel = grpc.insecure_channel(server)
auth    = [("authorization", f"Bearer {api_key}")]

# Cihaz listesini al
device_client = api.DeviceServiceStub(channel)
req = api.ListDevicesRequest(application_id="my-app-uuid", limit=100)
resp = device_client.List(req, metadata=auth)

for item in resp.result:
    print(f"{item.dev_eui}  {item.name}  lastSeen={item.last_seen_at}")

Grafana entegrasyonu

ChirpStack, InfluxDB veya PostgreSQL'e veri yazabilir. Grafana bu veri kaynaklarına bağlanarak gerçek zamanlı sensör panoları oluşturur. Alternatif olarak MQTT → Node-RED → InfluxDB → Grafana pipeline'ı yaygın kullanılan yöntemdir.

MQTT → InfluxDB bridge (Node-RED akışı)
// Node-RED flow (JSON dışa aktarma)
[
  { "id": "mqtt-in",   "type": "mqtt in",
    "topic": "eu868/gateway/+/event/up",
    "broker": "localhost" },
  { "id": "parse",     "type": "function",
    "func": "var d=JSON.parse(msg.payload);\nmsg.payload={temperature:d.rxInfo[0].rssi};\nreturn msg;" },
  { "id": "influx-out","type": "influxdb out",
    "measurement": "lorawan_rx" }
]

08 Pratik: RPi gateway + TTN + DHT22 end device

Uçtan uca bir LoRaWAN sistemi: Raspberry Pi 4 üzerinde SX1302 HAT ile gateway, MicroPython ile DHT22 sıcaklık/nem sensörü end device, TTN üzerinde uygulama.

Sistem topolojisi

  ┌──────────────────────┐  LoRa RF 868 MHz   ┌──────────────────┐
  │  End Device          │───────────────────▶│  RPi 4 Gateway   │
  │  Raspberry Pi Pico W │                    │  + SX1302 HAT    │
  │  + SX1276 breakout   │                    │  Semtech UDP PF  │
  │  + DHT22 sensör      │                    └────────┬─────────┘
  │  MicroPython         │                             │ UDP 1700
  └──────────────────────┘                             ▼
                                          ┌────────────────────────┐
                                          │  eu1.cloud.thethings   │
                                          │  .network (TTN v3)     │
                                          └────────────┬───────────┘
                                                       │ MQTT 8883
                                                       ▼
                                          ┌────────────────────────┐
                                          │  Python MQTT istemci   │
                                          │  (sıcaklık/nem ekranı) │
                                          └────────────────────────┘
    

1. Gateway: Raspberry Pi SX1302 HAT kurulumu

gateway_setup.sh
#!/bin/bash

## SX1302 HAL derle
sudo apt install -y git gcc make libssl-dev
git clone https://github.com/Lora-net/sx1302_hal.git
cd sx1302_hal && make

## Paket forwarder konfigürasyonu (EU868)
cat > packet_forwarder/global_conf.json <<'EOF'
{
  "SX130x_conf": {
    "spidev_path": "/dev/spidev0.0",
    "lorawan_public": true,
    "clksrc": 0,
    "chan_multiSF_0": {"enable": true, "radio": 0, "if": -400000},
    "chan_multiSF_1": {"enable": true, "radio": 0, "if": -200000},
    "chan_multiSF_2": {"enable": true, "radio": 0, "if":       0},
    "chan_multiSF_3": {"enable": true, "radio": 1, "if": -400000},
    "chan_multiSF_4": {"enable": true, "radio": 1, "if": -200000},
    "chan_multiSF_5": {"enable": true, "radio": 1, "if":       0},
    "chan_multiSF_6": {"enable": true, "radio": 0, "if":  200000},
    "chan_multiSF_7": {"enable": true, "radio": 0, "if":  400000},
    "chan_Lora_std":  {"enable": true, "radio": 1, "if":  200000,
                       "bandwidth": 250000, "spread_factor": 7},
    "chan_FSK":       {"enable": false},
    "radio_0": {"enable": true, "type": "SX1250", "freq": 867500000,
                "rssi_offset": -215.4, "tx_enable": true},
    "radio_1": {"enable": true, "type": "SX1250", "freq": 868500000,
                "rssi_offset": -215.4, "tx_enable": false}
  },
  "gateway_conf": {
    "gateway_ID": "AA555A0000000000",
    "server_address": "eu1.cloud.thethings.network",
    "serv_port_up": 1700,
    "serv_port_down": 1700,
    "keepalive_interval": 10,
    "stat_interval": 30,
    "push_timeout_ms": 100,
    "forward_crc_valid": true,
    "forward_crc_error": false,
    "forward_crc_disabled": false
  }
}
EOF

## Gateway EUI al ve TTN'ye kaydet
echo "Gateway EUI: $(cat /sys/class/net/eth0/address | sed 's/://g' | head -c 6)FFFE$(cat /sys/class/net/eth0/address | sed 's/://g' | tail -c +7)"

## Çalıştır
./tools/reset_lgw.sh start
./packet_forwarder/lora_pkt_fwd -c packet_forwarder/global_conf.json

2. End device: Raspberry Pi Pico W + SX1276 + DHT22

main.py — MicroPython OTAA + DHT22
#!/usr/bin/env micropython
"""
Gereksinimler:
  pip install mpremote
  mpremote mip install micropython-lora
  Bağlantı: SX1276 → SPI0 (SCK=18, MOSI=19, MISO=16, CS=17)
             RST=20, DIO0=15 / DHT22 → GP22
"""
import machine, time, struct
import dht
from lora import SX1276, LoRaWAN, SF9, BW125

# DHT22 sensörü
dht_pin = machine.Pin(22)
sensor  = dht.DHT22(dht_pin)

# SX1276 SPI kurulumu
spi = machine.SPI(0, baudrate=1_000_000,
                  sck=machine.Pin(18), mosi=machine.Pin(19),
                  miso=machine.Pin(16))
lora_radio = SX1276(spi,
                    cs=machine.Pin(17),
                    rst=machine.Pin(20),
                    dio0=machine.Pin(15))

# LoRaWAN OTAA parametreleri (TTN konsolundan kopyala)
DEV_EUI = bytes.fromhex("0011223344556677")
APP_EUI = bytes.fromhex("70B3D57ED0000000")
APP_KEY = bytes.fromhex("AABBCCDDEEFF00112233445566778899")

lorawan = LoRaWAN(lora_radio, dev_eui=DEV_EUI,
                  app_eui=APP_EUI, app_key=APP_KEY,
                  region="EU868")

print("OTAA join başlıyor...")
while not lorawan.joined():
    if lorawan.join():
        print("Join başarılı!")
        break
    print("Join başarısız, 30s bekleniyor...")
    time.sleep(30)

def encode_payload(temp_c, hum_pct):
    """Sıcaklık ve nemi 4 byte'a sıkıştır (x10 ölçeği)"""
    t = int(temp_c * 10)
    h = int(hum_pct * 10)
    return struct.pack(">hH", t, h)

# Ana döngü: her 60 saniyede bir ölç ve gönder
while True:
    try:
        sensor.measure()
        temp = sensor.temperature()
        humi = sensor.humidity()
        print(f"Sıcaklık: {temp:.1f} °C  Nem: {humi:.1f} %")

        payload = encode_payload(temp, humi)
        lorawan.send(payload, port=1)
        print(f"Gönderildi: {payload.hex()}")
    except Exception as e:
        print(f"Hata: {e}")

    time.sleep(60)   # 60 saniye uyku (duty cycle uyumu)

3. Veri alma — Python MQTT istemcisi

ttn_monitor.py — sıcaklık/nem monitörü
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import json, base64, struct

APP_ID  = "my-sensor-app"
API_KEY = "NNSXS.xxx..."

def decode_dht22(payload_b64):
    raw = base64.b64decode(payload_b64)
    if len(raw) >= 4:
        temp, humi = struct.unpack(">hH", raw[:4])
        return temp / 10.0, humi / 10.0
    return None, None

def on_message(client, userdata, msg):
    data    = json.loads(msg.payload)
    dev_id  = data["end_device_ids"]["device_id"]
    uplink  = data["uplink_message"]
    temp, humi = decode_dht22(uplink["frm_payload"])
    rssi    = uplink["rx_metadata"][0]["rssi"]
    snr     = uplink["rx_metadata"][0]["snr"]
    sf      = uplink["settings"]["data_rate"]["lora"]["spreading_factor"]

    print(f"[{dev_id}]  {temp:.1f}°C  {humi:.1f}%  "
          f"RSSI={rssi} SNR={snr} SF{sf}")

client = mqtt.Client()
client.username_pw_set(f"{APP_ID}@ttn", API_KEY)
client.tls_set()
client.on_message = on_message
client.connect("eu1.cloud.thethings.network", 8883, 60)
client.subscribe(f"v3/{APP_ID}@ttn/devices/+/up")

print("TTN'den veri bekleniyor...")
client.loop_forever()

Beklenen çıktı

örnek çıktı
[sensor-01]  23.4°C  61.2%  RSSI=-87 SNR=8.5 SF9
[sensor-01]  23.5°C  61.0%  RSSI=-88 SNR=8.2 SF9
[sensor-01]  23.4°C  61.5%  RSSI=-86 SNR=9.1 SF9
ÖZET

LoRaWAN, pil ile çalışan sensörlerden bulut uygulamasına kadar eksiksiz bir IoT yığını sunar. SF ve BW parametreleri menzil-hız dengesini belirler, OTAA güvenli aktivasyon sağlar. TTN ücretsiz ve hızlı başlangıç için idealdir; ChirpStack ise kurumsal dağıtımlar için tam kontrol sunar.