AVR-SX1262 LoRa Modül Kullanımı (DRF1262G)

 LoRa (Long Range) düşük güç ile uzun mesafelerde iletişim sağlayan bir modülasyon tekniğidir. LoRa hakkında çok sayıda kaynak bulunmakta ama modül kullanımıyla ilgili özellikle türkçe kaynak yok. Ben kendi ihtiyaçlarım için uzun zaman önce aldığım DRF1262 modülünü anlatmaya çalışacağım. Farklı nedenlerle zaman bulup kullanmaya başlayamadığım modülle ilgili nihayet sonuca ulaştım. Bu modülün üreticisine ve gerekli dosyalara buradan ulaşabilirsiniz. Linkte modülün bilgileri ve Arduino için hazırlanmış örnek dosyası var. Her zamanki gibi hazır kütüphanenin öğrenmeme bir faydası olmayacağından sadece deneme amaçlı olarak kullandığım örneklerdir. Eğer hazır kullanmak isterseniz Sx1262 üreticisi Semtech'in kütüphanesini değiştirerek kullanmışlar. Semtech sayfasında gerekli dökümanlar var. Asıl yardımcı kaynak olarak kullandığım örnek dosya CAD (kanal hareket algılama) kullanımı için paylaşılmış olan ve Stm MCU lar için yazılmış dosyadır. Örnek kütüphaneleri incelemiş olsam da birkaç basit şey dışında özgün bir dosya hazırladım. Bunun için de sx1262 datasheet rehberim oldu. Buradaki anlatım ve sıralama da datasheet'e göre olacaktır. Çok detaya girmeden oldukça kısa tutmaya çalışacağım. Özellikle komut kısmını kısa keseceğim çünkü çok fazla komut bulunmaktadır.

DRF1262

Sx1262 alıcı-verici modemi bulunan bu modülün pin bağlantılarıyla başlayalım. sx1262'nin tüm pinleri (DIO3)modül dışına taşınmış durumda değil. 16 adet pin bulunmakta. Bunlardan dört adeti SPI için,  ikisi IRQ (kesmeler) için ayrılmış.

Pin Bağlantıları

1.ANT: Anten bağlantısı.

2. GND: Negatif besleme pini.

3. SW: RF switch kontrol pini ama bağlantısı içeriden yapılmış etkisi yok.

4-7.GND: Negatif besleme pini.

8. VDD: +3,3Volt pozitif besleme pini.

9. DIO2: RF switch kontrol pini içeriden bağlanmış istenirse IRQ (kesme) için kullanılabilir. RF switch ayarlıyken RX "0" ve TX "1" olur. Kesme  olduğunda "1" olur.

10. DIO1: IRQ pini, kesme  olduğunda "1" olur.

11. BUSY: Modül meşgul kontrol pini, meşgul olduğunda "1" olur.

12. RST: Modül resetlemek için kullanılır, "0" olduğunda  resetlenir.

13. MISO: SPI Slave data çıkış.

14. MOSI: SPI Slave data giriş.

15. SCK: SPI Saat girişi.

16. NSS: SPI Slave seçme pini.

Pin bağlantıları bu şekilde olan modül en fazla 3,7 Volt ile çalışabiliyor. SPI ve diğer pinler için bağlantı yaparken dikkat etmek gerekiyor. Sınırlara geçmişken modül frekans aralığı 434/490/868/915MHz arasında bir değer olabiliyor.  Avrupa'da LoRa için çok özel sınırları belirlenmiş. Band genişliği yayılma faktörü gibi sınırlar var. Bizde böyle bir kaynak bulamadım, hangi frekanslar serbest veya yasak bilmiyorum. Sx1262 +22dBm ye kadar çıkış gücü verebiliyor, -148dBm alıcı hassasiyetine sahip. LoRa dışında FSK modülasyonu da kullanılabilir. Sx1262 32MHz osilatöre sahip bu modül dışında bazı modüller TCXO ile sıcaklıktan fazla etkilenmeden çalışabilmektedir. Dahili olarak 64kHz ve 13Mhz osilatöre sahiptir.

sx1262 de iki farklı güç seçeneği var. LDO veya DC DC kullanılabilir ama bunun için farklı bağlantılar mevcut. DRF1262 de DC DC için bağlantı yapılmış durumda. Modülün kullanımı besleme ayarları yapılırken buna göre ayarlamalar yapılacak. Bu bağlantılarda kullanılan ürünlerin kalitesi sinyal gücünü etkilemekte. Modülün giriş/çıkış (I/O) ayarları yapılıp Standby moda alınarak ilk yapılması gereken işlem regülatör ayarlaması yapmaktır. SetRegulatorMode komutuyla seçim yapılır. DC DC seçildiğinde akım sınırlaması devreye girer ve limit olarak 60mA ayarlanır.

LoRa Modem

Hata düzeltmeler ile gürültüden arındırarak uzun menzil (test yapmadım) iletişim sağlayabilen bir modem. Modem seçimi SetPacketType ile yapılmaktadır. Mevcut modemi sorgulamak için de GetPacketType kullanılır. LoRa modem dört parametreyle ayarlanır. Bunlar modülasyon parametreleri olarak isimlendirilir ve modem seçiminden sonra SetModulationParams ile yapılandırılır.

Band Genişliği (Bw)

Band genişliği artınca hassasiyet azalır ama veri iletim süresi de azalır. Bu hesaplamalar için LoRa Hesaplayıcı programı indirmekte fayda var. Aşağıdaki tabloda LoRa modemin band genişliği değerleri bulunmaktadır.

Yayılma Faktörü (Sf)

Sf 5-12 arası değer alır. Kısaca bir byte veri için kaç adet LoRa sembolü gönderileceği ayarlanır. Sf artınca veri hızı düşer ama hassasiyet artar.

Kodlama Oranı (Cr)

Hata düzeltme oranı. Oran yükseldikçe paket boyutu dolayısıyla iletişim hızı düşer ama daha sağlıklı iletişim gerçekleşir. Normal şartlarda 4/5 yeterlidir.

Veri Hız Optimizasyonu

Sf yüksek Bw düşük seçildiğinde iletişim süresi uzar. Alıcının sinyali takip edebilmesi için bu seçenek aktif olmalıdır. Sinyalin havada kalış süresi (symbol time)16,38ms veya daha büyükse (sf11-bw125 ve altı ile sf12-bw250 ve altı olduğunda) önerilir.

LoRa Veri Paketi

Şemada görüldüğü gibi önsöz, başık, veri ve veri hata denetimi paketi oluşturur.

Önsöz

Paket alıcının senkron olabilmesi için önsöz (preamble) ile başlar ve sembol sayısı ayarlanabilir. Preamble alıcı ve verici tarafında aynı olmalıdır. Boyutu bilinmediğinde en yüksek boyut bilgisi girilmelidir.

Başlık

İki tip ayar var açık ve kapalı başlık. Açık başlık seçili olduğunda CRC, Cr oranı ve veri uzunluğu içeren bir başlık gelir. Kapalı olarak ayarlandığında başlık pakete dahil edilmez. İki tarafta da CRC, Cr ve yük sabit ve önceden ayarlanmış olmalıdır.

Kanal Hareket Algılama (CAD)

LoRa sembollerini kontrol ederek sinyal tespiti yapılır. Yapılan ayarlara bağlı olarak belirli bir süre tarama yapar. Sembol tespit edilirse veya süre dolarsa kesme oluşur. Bununla ilgili dökümana buradan ulaşabilirsiniz. Ben ayarlamaları bu dökümana göre yaptım. Güç kazancı için farklı sembol sayısı 2 yapılabilir.

Veri Hafızası

Sx1262 256 byte RAM belleğe sahiptir. Alıcı (Rx) ve verici (Tx) Başlangıç adresleri SetBufferBaseAddresses ile değiştirilebilir şekilde bu hafızayı kullanır. Alıcı modda ayarlanan başlangıç adresi RxStartBufferPointer da saklanır. Veri geldiğinde veri boyutu başlangıca eklenerek artırılır. Veri okunacağı zaman bellekteki yeri için GetRxbufferStatus ile RxStartBufferPointer ve veri boyutu öğrenilir. Her yeni gelen veri ile başlangıç adresi bu şekilde artarak devam eder. Rx taşma durumunda Tx üstüne yazılır.

Verici modda SetBufferBaseAddresses ile belirlenen başlangıç adresine veri yazılır veri boyutu SetPacketParams ile bildirilir. Giden her byte sonrası tx başlangıç adresi bir artırılır. Veri boyutu sınırına geldiğinde işlem biter. Her yeni işlemde başlangıç adresi başa alınır.  Bellekten okuma ve yazma işlemi ReadBuffer ve WriteBuffer ile yapılır.

SPI Arayüz

SPI arayüzü ile veri alış verişi yapan Sx1262 Motorola/Freescale terminolojisine göre CPOL=0 ve CPHA=0 ayarlarıyla çift yönlü slave modda bağlantı kurar. 16MHz  hızında veri alış verişi yapabilir. NSS pini "0" olduğunda iletişim başlar. SCK pini yükselirken master veri yollar, düşerken slave veri yollar.

Giriş Çıkış Pinleri (Input/Output)

Giriş çıkış pinlerine geçmeden Sx1262'yi RST pini ile fabrika ayarlarına döndürebiliriz. Bunun için 100μs "0" yapmak yeterlidir. Reset sonrası otomatik  kalibrasyon işlemi başlar. Sx1262 de 4 adet I/O pini bulunur. Busy ve üç adet dijital giriş/çıkış pini vardır.

Busy pini sx1262 iletişime hazır olduğunda "0" olur. İşlem tamamlanmadığında ise "1" olur. Komut sonrası en fazla 600ns sonra çip işleme hazır duruma gelir.

DIO3 bu modülde dışarı çıkartılmamıştır. TCXO kullanımında SetDioTCXOCtrl açma kapatma işlevi yanında kesme pini olarak kullanılır.

DIO2 pini Rf switch kontrol SetDio2AsRfSwitchCtrl veya kesme pini olarak ayarlanabilir. Bu modülde Rf switch kontrol etmek için bağlı görünmektedir. Bu nedenle kesme işlevini kullanmadım.  DIO2 Rf switch kontrol ayarında Rx ile diğer modlarda "0" ve Tx modunda "1" olur.

DIO1 kesme pini olarak kullanılır. Tüm DIO pinleri 50kΩ pull down direnç ile bağlıdır. Kesme oluştuğunda "1" olur. DIO pinlerinin üçü de kesme için kullanılabilir. Bunu SetDioIrqParams ile yapabiliriz. Kesme oluştuğunda kesme kaynağını öğrenmek için GetIrqStatus ve kesme bayraklarını temizlemek için ClearIrqStatus kullanılır. Toplamda 10 adet kesme kaynağı vardır.

Başlatma

İlk enerji verildiğinde veya reset sonrası Sx1262 başlatma durumuna geçer. Otomatik olarak kalibrasyon yapılır. Bu işlemler sırasında busy "1" durumundadır. İşlem bitince bekleme (STDBY) moduna geçilir.

STDBY

Kalibrasyon sonrası bu modda hangi osilatörün kullanılacağı belirlenir. Güç kazanımı için  13MHz (RC-Resistance-Capacitance Oscillator) veya 32MHz (XOSC-Crystal Oscillator) seçimi SetStandby ile yapılır. Rx veya Tx moduna geçmeden regülatör seçimi yapılmalıdır. STDBY_XOSC modunda DC-DC regülatör otomatik seçilir. ISM frekans aralığında CalibrateImage komutu freq1 ve freq2 değerleriyle frekans kalibrasyonu yapılır.

Uyku Modu: Kullanmayı düşünmediğim için incelemedim. Belki ilerde ekleme yaparım.

FS: Hata ayıklama modu olarak tanımlı.

Alıcı Rx Modu

Seçilen modem ve Rf açılır, paket alındığında tampona yazılır. Güç kazancı veya hassaiyet için RxGain ayarlaması yapılmalıdır. Rx alt modları vardır.

Sürekli mod: Bir paket alınana veya MCu tarafından mod değiştirilene kadar bu modda kalır.

Tekil mod: Bir paket aldıktan sonra STDBY_RC moduna geçer.

Zaman aşımlı tekil mod: Bir paket aldıktan sonra veya belirlenen süre sonunda STDBY_RC moduna geçer. SetLoRaSymbNumTimeout ile belirlenen sayıda sembol tespit edildiğinde zamanlayıcı durdurulur. Bu yapılmazsa toplam sembol tespit edilene kadar zamanlayıcı durmaz ve zaman aşımı kesmesi oluşabilir.

Dinleme modu: Uyku moduyla Rx modu arasında değişim yapılır.

Verici Tx Modu

Güç Amplifikatörünü (PA) etkinleştirilip hazırlanır ve tampondaki veri iletilir. Pa hazırlanma süresi SetTxParams ile ayarlanabilir. Tx modun alt modları vardır.

Tekil mode: Veri gönderilir ve sonra STDBY_RC moduna geçer.

Zaman aşımlı tekil mod: Veri gönderiminde sorun olur ve işlem tamamlanamazsa bir döngü içinde kalmamak için zaman aşımı ayarlanır.


Bu şema modlar arası geçişi göstermektedir.

MCU ile Kontrol Arayüzü

SPI ile kontrol edilen sx1262 yapılan işlemler için işlem kodları kullanır. Parametre içermeyen bir komut için sadece işlem kodu gönderilir. Parametre içeren komutlar için işlem kodu sonrası parametreler gönderilir. Tüm parametreler gönderilmeden NSS pini "1" olursa sx1262 ile iletişim tamamlanamaz ve tanımsız değerler alabilir. Komut listesi datasheet 11. bölümde yer almaktadır.

Bunun dışında yapılması gereken bazı ayarlamalar işlem kodlarıyla değil doğrudan register kayıtlarıyla yapılmaktadır. Register adres ve içerikleri datasheet 12. bölümde bulunmaktadır.

Komut Arayüzü

Tüm komutları tek tek yazmayı düşünmüyorum örnek olarak birkaç komut paylaşacağım. Zaten aşağıda paylaşacağım dosyada gerekli tüm fonksiyonlar var. Her fonksiyon bu komutları içermektedir.

SetStandby: İşlem kodu (opcode) 0x80 ve StdbyConfig isimli bir parametre bulunmaktadır. Bu parametre hangi osilatörün kullanılacağını belirtir. Bekleme moduna geçmek ve RC13Mhz osilatörü kullanmak için SPI ile göndermemiz gereken veri sırasıyla 0x80,0x00 olmalıdır.

ReadBuffer: İşlem kodu (opcode) 0x1E, ardından okunmak istenen bellek adresi (offset) , ve  sonrasında bir NOP ile okunacak veri boyutu kadar SPI ile NOP (boş komut) göndermek gerekir. Örnek olarak 0x02 adresinde 2 byte veri okumak için SPI ile sırasıyla 0x1E,0x02,0x00,0x00,0x00 gönderilir. Bu işem sonucunda gelen verinin ilk ikisi sx1262 durum (status), sonraki ikisi bellekteki veridir.

SetDioIrqParams: İşlem kodu 0x08 dir. Kesme için DIO pinlerinin ayarlaması yapılır. Bunun için öncelikle hangi durumda kesme oluşacağı (IrqMask) bildirilir. Ardından sırasıyla DIO1-2 ve 3 pinlerinde hangi kesmenin oluşacağı seçilir.

Burada görülen 10 adet kesme kaynağından seçilen her hangi bir kesme, istenen bir pine yönlendirilebilir. Örnek olarak Rx modundayız, RxDone, CrcErr ve Timeout kesmesi oluşmasını istiyoruz. RxDone ve CrcErr DIO1 de Timeout DIO2 de oluşsun istersek Spı ile gönderilen veri şu şekilde olmalıdır: 0x08,(0x02,0x42),(0x00,0x42),(0x02,0x00),(0x00,0x00)

Bu üç örnek bir fikir vermiştir, diğer komutların farkı yok.

Örnek Başlatma

Datasheette Tx ve Rx için yapılması gerekenler belirtilmiş Ben de burada başlangıcın nasıl yapılacağını aktarmaya çalışacağım. Öncelikle modülün MCU ile bağlı olduğu pinlerin giriş/çıkış durumlarını ayarlanmalıdır. Modül resetlenir ve iletişim için SPI başlatılır. STDBY_RC moduna geçilir, regülatör ayarlanır. Çalışılacak frekans ve kalibrasyon yapılır. Modem seçilir burada LoRa seçildi. Modemle ilgili ayarlardan modülasyon ve paket parametreleri girilir. Bellek adresi belirlenir. DIO2 pininin durumu belirlenir. Buraya kadar olan kısım ortaktır.

Tx modundan önce PA ayarları  yapılır. Belleğe veri yazılır, paket parametresi olarak veri boyutu ayarlanır. İlgili kesmeler ayarlanır ve Tx moda geçilir. Rx te ise kesmeler ayarlanır ve Rx moda geçilir.  Paket alındığında Crc kontrol edilir. Sorun yoksa bellek adresi ve veri boyutu öğrenilir ve bellekten okunur.

Burada veri gönderilirken veri boyutunu SetPacketParams ile önceden ayarlamamız gerekiyor. Belleğe yazıp Tx moduna geçerek işlem yapılamıyor. SetPacketParams LoRa modemde 4 parametre alıyor. Her veri gönder dediğimizde diğer parametreleride girmek zorundayız. Ben global değişkenler tanımlayarak yapıyordum. Örnek kütüphanede bunun için Struct yapısı kullanılmış ve oldukça işlevsel olmuş. Ben de bu şekilde kullandım ve önceden diğer parametreleri girdiğim için sadece veri gönderirken veri boyutunu değiştirerek struct pointer SetPacketParams ile yapılandırdım.

Yüzeysel olarak anlatmaya çalıştım. Belki de çok yüzeysel oldu bilemiyorum. Bununla ilgili dönüş olursa değişiklik yapabilirim. Aşağıda çalışan kodları paylaşacağım. Üstünde açıklamalar da yaptım.

NOT:  sx1262.c tanımlı sx_rx_ring[Sx1262_Rx_Mask]; satırını aşağıdaki şekilde düzeltilmesi gerekir.

static uint8_t sx_rx_ring[Sx1262_Rx_Boyut];


Dosyalar burada.


Bu yazıda kullanılan modül yetersiz geldiğinden farklı bir marka kullanmaya başladım. Bu ve şu anda kullandığım modüllerin bağlantıları benzer.