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
└──────────────────────────────────┘
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.
| SF | Bit hızı (BW 125 kHz) | Alıcı Hassasiyeti | Menzil (kentsel) | ToA (50B paket) |
|---|---|---|---|---|
| SF7 | 5470 bps | -123 dBm | ~2 km | ~56 ms |
| SF8 | 3125 bps | -126 dBm | ~3 km | ~103 ms |
| SF9 | 1757 bps | -129 dBm | ~5 km | ~185 ms |
| SF10 | 977 bps | -132 dBm | ~8 km | ~370 ms |
| SF11 | 537 bps | -134.5 dBm | ~12 km | ~741 ms |
| SF12 | 293 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 (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.
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ıf | Downlink alımı | Güç tüketimi | Gecikme | Tipik kullanım |
|---|---|---|---|---|
| Class A | Her uplink sonrası 2 RX penceresi | En düşük | Yüksek (bir sonraki uplink'e kadar) | Sensörler, pil cihazları |
| Class B | Beacon ile senkronize periyodik RX | Orta | Orta (beacon dönemi) | Aktüatörler, kısmen pil |
| Class C | Sü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!) │
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 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ı
| Özellik | OTAA | ABP |
|---|---|---|
| Güvenlik | Yüksek (her session farklı anahtar) | Düşük (sabit anahtarlar) |
| Kurulum kolaylığı | Orta (join prosedürü) | Kolay |
| Güç kesintisi sonrası | Yeniden join gerekebilir | Hemen çalışır |
| Frame sayacı | Join'da sıfırlanır | Güç kesintisinde sorun |
| Üretim tavsiyesi | Önerilen | Yalnı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
## /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
#!/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.
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-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
#!/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
// 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.
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
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:
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
#!/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.
// 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
#!/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
#!/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
#!/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ı
[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
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.