00 NB-IoT ve LTE-M — farklar ve kullanım senaryoları
NB-IoT (Narrowband IoT) ve LTE-M (LTE-MTC / Cat-M1), 3GPP Release 13 ile standardize edilmiş ve mevcut LTE altyapısı üzerinde çalışan düşük güç geniş alan (LPWAN) teknolojileridir.
Özellik NB-IoT (Cat-NB1/NB2) LTE-M (Cat-M1)
─────────────────────────────────────────────────────────
Bant genişliği 180 kHz 1.4 MHz
DL hız (maks.) 250 kbps 1 Mbps
UL hız (maks.) 250 kbps 1 Mbps
Gecikme 1–10 s 10–15 ms
Mobility Sınırlı (idle) Tam handover
VoLTE Hayır Evet
PSM desteği Evet Evet
eDRX desteği Evet (maksimum ~2.9 sa) Evet (maksimum ~43 dk)
Tipik kullanım Sayaç, sensör, tracker Araç takibi, wearable
MCL (dB) 164 dB 156 dB
01 PSM (Power Saving Mode) konfigürasyonu
PSM, 3GPP'nin tanımladığı en güçlü güç tasarrufu modudur. Cihaz aktif periyotta (TAU timer) şebekeyle iletişim kurar, ardından tüm radyo devrelerini kapatır. Yalnızca RTC aktif kalır.
PSM timer bitleri
T3412 — TAU (Tracking Area Update) periyodu
Bit 8–6: Timer birimi
000 → 2 dakika 001 → 30 dakika
010 → 4 saat 011 → 1 saat
101 → 1 dakika 110 → 320 saat
Bit 5–1: Değer (binary)
Örnek: "00100001" → 010 (4 saat) × 00001 (1) = 4 saat TAU
T3324 — Active Time (uyanık kalma süresi)
"00000010" → 000 (2 sn) × 00010 (2) = 4 saniye aktif
AT komutu ile PSM etkinleştirme
# PSM etkinleştir (mod=1), T3412=4 saat, T3324=4 saniye
AT+CPSMS=1,,,,"00100001","00000010"
# +CPSMS: 1,,,,"00100001","00000010"
# OK
# PSM durumu sorgula
AT+CPSMS?
# +CPSMS: 1,,,,"00100001","00000010"
# Şebekeden gerçek PSM parametrelerini al
AT+CEREG=5 # Genişletilmiş kayıt
AT+CEREG?
# +CEREG: 5,1,"1A2B","01234567",9,,,"00100001","00000010"
# ^NB-IoT ^TAU ^Active Time
Python ile PSM döngüsü
import serial, time, re
PORT = "/dev/ttyUSB2"
BAUDRATE = 115200
def at(ser, cmd, timeout=5):
ser.write((cmd + "\r\n").encode())
resp = b""
end = time.time() + timeout
while time.time() < end:
resp += ser.read(ser.in_waiting or 1)
if b"OK\r\n" in resp or b"ERROR" in resp:
break
return resp.decode(errors="ignore")
with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
# PSM konfigürasyonu
print(at(ser, 'AT+CPSMS=1,,,,"00100001","00000010"'))
# NB-IoT seç
print(at(ser, "AT+QCFG=\"iotopmode\",0,1")) # 0=NB-IoT, 1=LTE-M, 2=auto
# APN ayarla ve bağlan
print(at(ser, 'AT+CGDCONT=1,"IP","iot.operator.com"'))
print(at(ser, "AT+CGACT=1,1"))
# Veri gönder (bkz. bölüm 04)
send_sensor_data(ser)
# PSM moduna gir (AT+QPSMEXTCFG ile tetiklenebilir)
print(at(ser, "AT+QPSMEXTCFG=0,0")) # PSM'e hemen gir
print("Cihaz PSM moduna girdi. RTC ile uyanacak...")
02 eDRX (Extended Discontinuous Reception) konfigürasyonu
eDRX, PSM'den daha sık uyanan, bu nedenle daha düşük gecikme sunan bir güç tasarrufu modudur. Anlık bildirim gerektiren uygulamalar için PSM yerine eDRX tercih edilir.
eDRX döngü süreleri
NB-IoT eDRX döngüleri (T-eDRX):
"0010" → 40.96 sn "0011" → 81.92 sn
"0100" → 163.84 sn "0101" → 327.68 sn
"1010" → 2621.44 sn (~43 dk)
"1111" → 10485.76 sn (~2.9 saat)
LTE-M eDRX döngüleri:
"0000" → 5.12 sn "0001" → 10.24 sn
"0010" → 20.48 sn "1001" → 163.84 sn
"1010" → 327.68 sn (~5.5 dk)
eDRX AT komutu
# NB-IoT eDRX etkinleştir — 81.92 saniye döngü
AT+CEDRXS=2,5,"0011"
# 2=etkinleştir, 5=NB-IoT (S1 modu), "0011"=81.92sn
# LTE-M eDRX — 20.48 saniye döngü
AT+CEDRXS=2,4,"0010"
# 4=LTE-M
# Şebeke kabul ettiği değeri oku
AT+CEDRXRDP
# +CEDRXRDP: 5,"0011","0011","0001"
# Sıra: mode, talep edilen, şebeke verilen, PTW
# eDRX devre dışı bırak
AT+CEDRXS=0
PTW (Paging Time Window), eDRX döngüsünün başında cihazın paging kanalını dinlediği penceredir. Daha dar PTW → daha az enerji ama daha az güvenilir mesaj alımı. 3GPP, 1.28 saniyeye kadar PTW önerir.
03 AT komutları ile bağlantı kurma
NB-IoT/LTE-M modemlerinin büyük çoğunluğu, 3GPP standardına dayalı AT komut seti kullanır. Aşağıdaki akış Quectel BG95 ve u-blox SARA-R4 için geçerlidir.
# 1. Modem durumu
AT
# OK
AT+CIMI # IMSI sorgula
AT+CGSN # IMEI sorgula
AT+QNWINFO # Ağ bilgisi (band, operatör)
# 2. NB-IoT modunu seç
AT+QCFG="iotopmode",0,1 # 0=NB-IoT öncelikli
# 3. Arama bandlarını sınırla (B8 = 900 MHz örneği)
AT+QCFG="band",0,0,80,1 # B8 için 80 hex
# 4. APN yapılandırması
AT+CGDCONT=1,"IP","nb.iot.turk.net"
# 5. Ağa kayıt bekle
AT+CEREG?
# +CEREG: 0,1 → 1=kayıtlı, ev şebekesi
# +CEREG: 0,5 → 5=kayıtlı, roaming
# 6. PDP context aktifleştir
AT+CGACT=1,1
# 7. IP adresini al
AT+CGPADDR=1
# +CGPADDR: 1,"10.128.45.67"
# 8. Sinyal kalitesi
AT+CSQ
# +CSQ: 20,0 → 20 = -73 dBm RSSI
Bağlantı sorun giderme
# CEREG = 0,2 → arama devam ediyor (beklemeye devam et)
# CEREG = 0,3 → kayıt reddedildi (SIM/APN kontrol et)
# Detaylı hata kodu
AT+CEER
# +CEER: "No network service"
# Bant taraması (uzun sürebilir)
AT+QCFG="band",0,0,0,1 # tüm NB-IoT bantlarını tara
# Fabrika reset
AT+QPRTPARA=3
04 UDP socket üzerinden veri gönderme
NB-IoT'un düşük bant genişliği göz önüne alındığında UDP, TCP'ye göre düşük overhead sağlar ve güç açısından daha verimlidir. Quectel BG95 dahili TCP/UDP stack sunar.
AT komutuyla UDP gönderme
# Socket aç: TCP/UDP, protokol, uzak IP, uzak port, yerel port, erişim modu
AT+QIOPEN=1,0,"UDP","iot.server.com",5683,0,1
# 1=context, 0=socket ID, 1=doğrudan push modu
# Veri gönder (max 1460 byte, hex formatında)
AT+QISEND=0,11
# > (data terminali bekliyor)
# "HELLO NB-IoT" gönderdikten sonra Ctrl+Z veya 0x1A
# Veya hex formatında gönder
AT+QISENDEX=0,"48454C4C4F" # "HELLO"
# Veri al (push modunda URC gelir)
# +QIURC: "recv",0
AT+QIRD=0,100 # socket 0, max 100 byte oku
# Socket kapat
AT+QICLOSE=0
Python ile tam UDP örneği
import serial, time, struct
def at_cmd(ser, cmd, wait_for="OK", timeout=10):
ser.write((cmd + "\r\n").encode())
buf = ""
deadline = time.time() + timeout
while time.time() < deadline:
chunk = ser.read(ser.in_waiting or 1).decode(errors="ignore")
buf += chunk
if wait_for in buf or "ERROR" in buf:
break
return buf
def send_sensor_payload(ser, temp_c, hum_pct, batt_mv):
"""Sıcaklık, nem, batarya verisini UDP ile gönder"""
# Küçük binary paket: 1 byte tip + 2 byte temp + 1 byte nem + 2 byte batt
payload = struct.pack("!BhBH", 0x01,
int(temp_c * 10),
int(hum_pct),
batt_mv)
hex_str = payload.hex().upper()
# UDP socket aç
resp = at_cmd(ser, 'AT+QIOPEN=1,0,"UDP","iot.example.com",5600,0,1',
wait_for="+QIOPEN:", timeout=30)
if "+QIOPEN: 0,0" not in resp:
print("Socket açılamadı:", resp)
return False
# Hex gönder
at_cmd(ser, f'AT+QISENDEX=0,"{hex_str}"')
print(f"Gönderildi: temp={temp_c}°C hum={hum_pct}% batt={batt_mv}mV")
# Socket kapat (güç tasarrufu için)
at_cmd(ser, "AT+QICLOSE=0", timeout=5)
return True
with serial.Serial("/dev/ttyUSB2", 115200, timeout=2) as ser:
send_sensor_payload(ser, 23.5, 65, 3850)
05 MQTT over NB-IoT — MQTT-SN ve HiveMQ
Kısıtlı ağlar için MQTT-SN (MQTT for Sensor Networks, UDP tabanlı) veya standart MQTT (TCP/TLS) kullanılabilir. NB-IoT'da bant genişliği kısıtlı olduğundan küçük payload ve QoS 0/1 önerilir.
Quectel MQTT AT komutları
# MQTT parametrelerini yapılandır
AT+QMTCFG="recv/mode",0,0,1 # 0=client, doğrudan veri alma
AT+QMTCFG="ssl",0,0 # SSL devre dışı (test için)
AT+QMTCFG="keepalive",0,120 # 120 saniye keepalive
# Broker'a bağlan
AT+QMTOPEN=0,"mqtt.hivemq.com",1883
# +QMTOPEN: 0,0 → başarılı
# Client ID ile giriş
AT+QMTCONN=0,"nbiot-sensor-01"
# +QMTCONN: 0,0,0 → bağlandı
# Topic'e yayınla (QoS 0)
AT+QMTPUBEX=0,0,0,0,"sensors/temperature","23.5"
# 0=client, 0=msgID, 0=QoS, 0=retain, topic, payload
# Topic'e abone ol (QoS 1)
AT+QMTSUB=0,1,"commands/device01",1
# Bağlantıyı kapat
AT+QMTDISC=0
TLS ile güvenli MQTT
# Sertifikaları modem flash'ına yükle
AT+QFUPL="cacert.pem",1138,100
# > (sertifika içeriği) ... OK
# SSL context yapılandır
AT+QSSLCFG="cacert",2,"cacert.pem"
AT+QSSLCFG="seclevel",2,1 # 1=sunucu doğrula
AT+QSSLCFG="sslversion",2,4 # 4=TLS 1.2
# SSL ile MQTT bağlan
AT+QMTCFG="ssl",0,1,2 # SSL etkin, context 2
AT+QMTOPEN=0,"iot.example.com",8883
AT+QMTCONN=0,"device-001","user","pass"
06 CoAP protokolü — constrained uygulama katmanı
CoAP (Constrained Application Protocol, RFC 7252), UDP üzerinde çalışan REST benzeri hafif bir protokoldür. NB-IoT için en uygun uygulama katmanı protokollerinden biridir.
CoAP mesaj yapısı
CoAP Başlık (4 byte):
Bit 7–6: Ver=01
Bit 5–4: T (Type): 00=CON, 01=NON, 10=ACK, 11=RST
Bit 3–0: TKL (Token Length)
Byte 1: Code (sınıf.ayrıntı)
0.00=boş, 0.01=GET, 0.02=POST, 0.03=PUT
2.05=Content, 4.04=Not Found
Byte 2–3: Message ID
Options:
Uri-Path: kaynak yolu ("/sensors/temp")
Content-Format: 0=text/plain, 50=application/json
Payload: (opsiyonel, separator 0xFF)
Python ile CoAP istemci (aiocoap)
import asyncio
import aiocoap
import aiocoap.resource as resource
import json
async def post_sensor_data(server_uri, temp, hum):
protocol = await aiocoap.Context.create_client_context()
payload = json.dumps({"temp": temp, "hum": hum}).encode()
request = aiocoap.Message(
code=aiocoap.POST,
uri=f"{server_uri}/sensors",
payload=payload
)
# Content-Format: application/json (50)
request.opt.content_format = 50
try:
response = await protocol.request(request).response
print(f"Yanıt: {response.code} — {response.payload.decode()}")
except Exception as e:
print(f"CoAP hatası: {e}")
finally:
await protocol.shutdown()
asyncio.run(post_sensor_data("coap://iot.server.com:5683", 23.5, 65))
AT komutuyla CoAP (Quectel)
# CoAP context oluştur
AT+QCOAPOPEN=0,"coap://iot.server.com",5683
# +QCOAPOPEN: 0,0 → başarılı
# POST isteği gönder
AT+QCOAPHEAD=0,2,0,1,0 # POST, Non-confirmable, MsgID=1
AT+QCOAPSEND=0,"/sensors","23.5",0,50 # path, payload, flags, content-type
# Context kapat
AT+QCOAPCLOSE=0
07 Güç tüketimi ölçümü ve optimizasyon
NB-IoT/LTE-M uygulamalarında pil ömrü kritik tasarım parametresidir. Nordic PPK2 veya Otii Arc ile µA düzeyinde akım profili çıkarılabilir.
Tipik güç tüketimi profili
Durum Akım (tipik) Açıklama
──────────────────────────────────────────────────────────
PSM (derin uyku) 2.5 µA Yalnızca RTC aktif
eDRX uyku 15–30 µA Periyodik dinleme
Bekleme (idle, kayıtlı) 3–5 mA Ağa kayıtlı, radyo bekleme
NB-IoT TX (23 dBm) 220–500 mA Veri gönderme
NB-IoT RX 40–80 mA Veri alma
LTE-M TX (23 dBm) 200–450 mA Veri gönderme
Pil ömrü hesabı
def battery_life_years(capacity_mah, profile):
"""
profile: [(akım_mA, süre_sn), ...]
capacity_mah: pil kapasitesi mAh
"""
total_charge_per_cycle_mah = sum(
current_ma * duration_s / 3600
for current_ma, duration_s in profile
)
cycle_period_h = sum(d for _, d in profile) / 3600
cycles_per_year = 8760 / cycle_period_h
annual_consumption_mah = total_charge_per_cycle_mah * cycles_per_year
years = capacity_mah / annual_consumption_mah
return years
# 4 saatte bir 10 byte veri gönderen sensör
profile = [
(220, 0.5), # TX 500ms @ 220mA
(60, 0.3), # RX 300ms @ 60mA
(4, 5.0), # idle 5sn @ 4mA
(0.0025, 4 * 3600 - 5.8), # PSM ~4 saat @ 2.5µA
]
print(f"Pil ömrü: {battery_life_years(2000, profile):.1f} yıl")
# Pil ömrü: 9.3 yıl
Optimizasyon teknikleri
08 Yaygın modem modülleri — Quectel BG95, u-blox SARA-R4
Piyasadaki başlıca NB-IoT/LTE-M modül ailelerinin özellikleri ve Linux entegrasyon notları.
Modül Protokol Frekans Band Özellik
──────────────────────────────────────────────────────────────────
Quectel BG95-M2 NB-IoT+LTE-M B1/B2/B3/B4/B5/ GNSS dahili,
B8/B12/B13/B20/ MQTT/CoAP/HTTP
B25/B28/B66/B71 AT stack dahili
u-blox SARA-R410M LTE-M+NB-IoT B1/B2/B3/B4/B5/ uFOTA OTA güncelleme,
B8/B12/B13/B18/ u-blox m-center
B19/B20/B25/B26/ destekli
B28/B39/B66
Nordic Thingy:91 LTE-M+NB-IoT Çok bant nRF9160 SiP,
(nRF9160) GPS LTE-M/NB-IoT Zephyr RTOS,
GPS dahili modem firmware OTA
SIM7080G NB-IoT+LTE-M Global çok bant SIM908 muadili,
HTTP/HTTPS/FTP dahili
Quectel BG95 Linux sürücü seçeneği
# BG95 USB olarak bağlandıysa
lsusb | grep Quectel
# Bus 001 Device 004: ID 2c7c:0700 Quectel Wireless Solutions Co.
# Seri portları
ls /dev/ttyUSB*
# /dev/ttyUSB0 (diagnostics)
# /dev/ttyUSB1 (NMEA GPS)
# /dev/ttyUSB2 (AT komutları)
# /dev/ttyUSB3 (PPP / data)
# Modül versiyonu
echo -e "ATI\r\n" | timeout 2 cat /dev/ttyUSB2
# Quectel BG95-M2
# Revision: BG95M2LAR02A06
09 Linux'ta PPP ve ofono ile entegrasyon
NB-IoT modemi Linux ağ yığınına entegre etmek için PPP veya ofono kullanılır. ofono, modern dağıtımlarda tercih edilen çözümdür ve ModemManager ile birlikte çalışır.
PPP ile bağlantı
/dev/ttyUSB3
115200
connect '/usr/sbin/chat -v -f /etc/ppp/chat-nbiot'
noauth
defaultroute
usepeerdns
persist
maxfail 3
ABORT "BUSY"
ABORT "NO CARRIER"
"" ATZ
OK AT+CGDCONT=1,"IP","nb.iot.operator.com"
OK ATD*99#
CONNECT ""
sudo pon nbiot
# pppd[1234]: local IP address 10.128.45.67
# pppd[1234]: remote IP address 10.64.64.64
ip route show
# default via 10.64.64.64 dev ppp0
# Bağlantı testi
ping -c 3 -I ppp0 8.8.8.8
ModemManager ile yönetim
sudo apt install modemmanager
# Modem listesi
mmcli -L
# /org/freedesktop/ModemManager1/Modem/0 [Quectel] BG95-M2
# Modem detayları
mmcli -m 0
# Bağlantı başlat
mmcli -m 0 --simple-connect="apn=nb.iot.operator.com"
# Bearer bilgisi
mmcli -m 0 --list-bearers
mmcli -b 0 # bearer detayları (IP, gateway, DNS)