這篇是去年 10 月底對 LoRa 模組進行初步測試的紀錄, 後來忙著幫二哥準備 APCS 而暫停下來. 昨天有網友問我空曠處實測距離多少, 才想起這篇還沒完成的草稿, 稍作整理如下備查. 在傳送距離方面, 網友與我的實測距離都約 200~250 米而已, 據說使用 IPEX 天線似乎沒有好到哪裡去, 實在殘念! 我還抱著一絲希望的說.
會接觸 LoRa 是因為去年十月初有另一位網友詢問我有無用過 LoRa, 當時我連買了放在零件箱好久的 nRF24L01 模組都還沒動哩! 為此我除了找出 nRF24L01 先測試一番以產生比較資料外, 還上網對此新興無線射頻技術做了初步研究, 整理了一篇知識摘要, 參見 :
#
長距離低功耗無線通訊技術 LoRa
接著在露天購買了一對最便宜的 LoRa 模組來測試 (跟 nRF24L01 一樣要成對地買, 一個傳送, 一個接收, 或者互相傳送接收), 此板用的是 SX1278 晶片 (433 MHz) :
# [史塔克實驗室][Arduino/RPi]每個180元2個一組販售SX1278 Lora module 模組433MHz $180
由於這是 2.0mm 腳距的裸板, 所以特地跑去禾樺買了 2.0 mm 的排針與排母, 在焊接前試試看到底要用排針或排母比較適合, 結果發現排針根本不能用, 因為 2.0mm 的排針比較細, 杜邦線母頭插上去鬆鬆的會接觸不良, 應該要用排母才對, 因為 2.0mm 的排母上的洞與一般 2.54mm 者一樣, 插杜邦線沒問題.
我買的這組 LoRa 模組每邊 8 隻腳, 其腳位布局如下 :
DIO2 GND
DIO1 MISO
DIO0 MOSI
3.3V SCK
DIO4 NSS
DIO3 RESET
GND DIO5
ANT GND
由於 ANT 腳要焊彈簧天線, 因此左邊的排母只要 7 隻腳, 而右邊的則需 8 隻腳, 使用小型電鑽前面裝上鑽石圓盤分別切出 7 支與 8 支腳的排母各一對, 然後用三秒膠少許加以固定後進行焊接. 注意, 三秒膠不可用太多, 否則萬一滲入排母內會讓排針插不下去.
Lora 板子焊好後就可以進行測試了, 我使用 Arduino 當作 MCU 主控, 首先是到下列 GitHub 網站下載 Arduino 的 Lora 函式庫 :
#
https://github.com/sandeepmistry/arduino-LoRa
按右邊的 "Clone or download" 鈕, 選 "Download ZIP" 下載壓縮檔 arduino-LoRa-master.zip, 將其複製到 Arduino IDE 安裝目錄的 libraries 下解開即可. 重新開啟 IDE 就可存取到此函式庫了. 此函式庫的 API 說明如下 :
#
https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md
此函式庫使用 SPI 協定與 LoRa 模組通訊, 預設傳輸速率是 10 MHz. 接下來是硬體接線, 此 LoRa 模組採用 SPI 介面 (也有用 Serial 介面的), Arduino 有特定的 SPI 接腳, 與 LoRa 的預設對應如下 :
不過其中 NSS, RESET, 與 DIO0 這三隻腳不一定要對應到 D10, D9, 與 D2 這三支 Arduino 腳, 可以連接到除 D13, D12, D11 以外的任何 DIO 腳位, 但在程式中要用 LoRa.setPins(NSS, RESET, DIO0) 指令指定.
測試 1 :
傳送端程式 :
#include <SPI.h>
#include <LoRa.h>
int counter=0; //傳送次數計數器
void setup() {
Serial.begin(9600);
while (!Serial); //等待序列埠起始完畢
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6)) { //起始 433MHz LoRa
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
LoRa.beginPacket(); //封包傳送開始
LoRa.print("hello "); //封包內容
LoRa.print(counter); //封包內容
LoRa.endPacket(); //封包傳送結束
counter++; //計數器增量 1
delay(5000);
}
接收端程式 :
#include <SPI.h>
#include <LoRa.h>
void setup() {
Serial.begin(9600);
while (!Serial); //等待序列埠起始完畢
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) { //起始 LoRa
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
int packetSize=LoRa.parsePacket(); //讀取剖析 LoRa 封包大小
if (packetSize) { //若有封包進來
Serial.print("Received packet '");
while (LoRa.available()) { //若接收緩衝器有內容
Serial.print((char)LoRa.read()); //讀取緩衝器內容並輸出階收到的封包
}
Serial.print("' with RSSI="); //輸出接收封包之 RSSI
Serial.print(LoRa.packetRssi()); //顯示接收信號強度
Serial.print(" and SNR="); //輸出接收封包之 SNR (信噪比)
Serial.println(LoRa.packetSnr()); //顯示接收信號信噪比
}
}
序列埠監控視窗輸出結果如下, 收到訊號時會顯示 "Received packet ... RSSI= .... SNR=...." :
.....
irqFlags 0
irqFlags 10
irqFlags 40
Received packet '
hello 29 ' with RSSI=-39 and SNR=16.00
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
.....
irqFlags 10
irqFlags 40
Received packet 'hello 30 ' with RSSI=-51 and SNR=15.75
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 0
irqFlags 80
irqFlags 0
.....
其中 RSSI (Received Signal Strength Indicator) : 接收信號强度指示.
用彈簧天線於空曠地區實測距離約 250 公尺, 似乎只比 nRF24L01 的 100 公尺長兩倍多而已, 與產品說明中所說的 1 公里相差達 4 倍. 不過信號穿透力可達 2~3 層樓, 在電梯中亦可收到信號, 這就比 nRF24L01 出色多了, nRF24L01 只要 5 公尺外轉個牆角就 GG 了, 參考 :
#
Arduino 無線傳輸模組 NRF24L01 測試
測試距離方面, 有空我還是會買支 IPEX 或其他廠家的 LoRa 模組來驗證看看.
參考 :
#
Arduino Arduino module communication by Lora Sx1278
#
https://github.com/matthijskooijman/arduino-lmic
#
【Acsip LoRa實作1】快速開發LoRa通訊功能-SPI介面篇
#
An Arduino library for sending and receiving data using LoRa radios
VIDEO