使用Arduino Nano驅動Lora模塊
為什么選用Lora
射頻通信芯片有很多種,但是一般在同樣功耗下,距離沒有Lora遠;同等范圍下,沒有Lora節能。
Lora通信只適用於低速率,高延時的場合,與WiFi正好相反。
- 考慮在野外,沒有移動通信網絡覆蓋的環境下,收集傳感器數據,適合使用。
- 在設密度大,使用移動通信網絡成本過高,使用Lora來統一收集數據,例如遠程抄表。
Lora作為物聯網的一種通信技術選型,正好是移動通信網絡,WiFi的補充。
完整項目
我使用一個Arduino Nano 來驅動Lora模塊,另外加了一個BMP085
(I2C接口)氣壓傳感器,一個光敏電阻,一個按鈕。
使用PlantformIO平台開發。(比Arduino IDE好用很多)
實現功能有:
- 參考arduino-LoRa雙向通行的自有簡單協議;
- 獲取傳感器的溫度,氣壓數據,光亮度;
- 獲取供電電池電壓;
- 定時通過Lora發送數據,按鍵強制發送一條數據;
- 使用鏈表緩存需要發送的內容,避免頻繁發送時候影響數據接收;
- 接收Lora數據:
- 指令led點亮燈2秒;
- 指令ping,返回pong;
項目地址: https://github.com/formatkm/lora_node
Lora模塊
- 串口模塊
- SPI接口模塊
一般串口模塊連接相對簡單,與其他無線模塊AT指令不同(例如:藍牙模塊、GPRS模塊),還需要對GPIO口連接控制引腳完成狀態配置操作,我想這個是因為需要比達到比較快的切換速度。
SPI口接口直接操作寄存器完成對芯片的操作和數據的發送接收。優點是可以自定義自己的通信協議,而且是要使用的是同種sx127X系列的芯片的模塊都可以相互通信。
串口模塊內部實際是有一個單片機控制Lora芯片,實現的自己的一套通信協議,一般同一個廠家的模塊才可以互相通信。
基本概念
-
RSSI:信號強度指示,用來判定鏈接質量,數字越大通信效果越好。
-
SNR:信噪比,電平與噪聲電平之比。數字越大通信效果越好。
-
Preamble
前導碼用於保持接收機與輸入的數據流同步。作用是提醒接收芯片,即將發送的是有效信號。 -
Header
可以通過操作模式,選擇顯示/隱式兩種Header類型:在RegModemConfig1寄存器上,通過設定ImplicitHeaderModeOn選擇 -
顯式報頭模式
LoRa默認都為顯式Header模式,在這種模式下,Header會包含Payload的相關信息,包括: -
Payload長度(byte)
-
前向糾錯編碼率
-
是否使用CRC(16位)
-
隱式報頭模式
在特定情況下,如果Payload長度、編碼率以及CRC為固定值或已知,則可以通過隱式Header模式來縮短發送時間。。該情況下 ,需要手動設置無線鏈路兩端的Payload長度、錯誤編碼率以及CRC。。。 -
IQ signal:極性信號反轉,用於標識上行,下行,避免多個節點間互相沖突,節點間不能互相通信
接線
按鈕接到D3,使用中斷引腳
- SPI接口
SCK <----> D13
MISO <----> D12
MOSI <----> D11
NSS <----> D10
REST <----> D09
DIO0 <----> D02 (中斷)
- I2C
SDA <----> A4
SCL <----> A5
- 其他
LED <----> D06
KEY <----> D03
光敏 <----> A2
驅動程序代碼
基於Arduino
的Sx1278
驅動有(測試使用順序):
- LoRaLib (已不在維護,使用RadioLib替代)
- RadioLib (支持多種無線芯片,更專業)
- arduino-LoRa (簡單好用,封裝配置)
最終選用的是arduino-LoRa,使用RadioLib 在實現雙向通行上遇到問題(C++功力不夠)。
arduino-LoRa最大的好處就是簡化了很多芯片參數的配置,如果業余選手要配置好參數能夠實現兩個模塊通信是個艱巨的挑戰,這也是串口Lora模塊的優勢,不用去關心復雜的通信參數配置。
閱讀arduino-LoRa代碼,你會發現很多參數都有范圍判斷的默認值,如果設置超出范圍也不會出錯。
要實現模塊連通,SPI接線基本不會有問題。最重要的是NSS
、REST
、DIO0
這三個不能接錯,對於Arduino板DIO0
一定要接在有中斷的引腳上。
DIO0
也稱IRQ
引腳,在模塊有數據接收,發送完畢后會有一個電平指示(高度單片機,要接受數據或者數據發送完畢),所以必須接到中斷引腳,普通GPIO腳速度達不到。
const int csPin = 7; // 也就是NSS接口
const int resetPin = 6; // reset引腳
const int irqPin = 2; // 必須是中斷引腳,Arduino Nano只有2、3腳為中斷
初始化模塊
LoRa.setPins(csPin, resetPin, irqPin);// set NSS, reset, DIO0 pin
if (!LoRa.begin(433E6)) { // 初始化使用頻率 433 MHz
Serial.println("LoRa init failed. Check your connections.");
while (true); // 失敗后停止執行
}
測試
使用arduino-LoRa的例子程序,如果接線正確,那么Arduino中燒入程序,會打贏出Sx1278的寄存器信息。
參考鏈接
- RSSI :百度百科
- SNR信噪比: 百度百科
- LoRaPingPang系統設計-許新天的博客