這篇文章來源于DevicePlus.com英語網站的翻譯稿。
點擊這里閱讀 LoRaLib 開發板 >
為了控制 Arduino長距離通信教程–LoRenz 開發板中構建的LoRenz開發板,我開發了LoRaLib——用于SX1278芯片的開源Arduino庫。這個庫從零開始設計,目的只有一個:制作易于使用的API,即使是初學者也可以實現LoRa通信。該庫的目標是使遠程通信與串行通信一樣簡單。
軟件
Arduino IDE
LoRaLib Arduino 庫 (可在 GitHub 上獲得)
LoRaLib 庫
SX1278有多種不同設置,允許用戶完全自定義范圍、數據速率和功耗,但是最重要的三個設置如下所示:
帶寬 SX1278允許的帶寬設置為7.8 kHz至500 kHz。帶寬值越高,數據傳輸越快。然而,這是以降低總靈敏度為代價的,因此降低了最大范圍。
擴頻因子 在LoRa調制中,每個信息位由多個啁啾表示。擴頻因子是指每位數據有多少啁啾。SX1278支持7種不同的設置,擴頻因子越高,數據傳輸越慢,范圍越大。
編碼速率 為了提高傳輸的穩定性,SX1278可以執行錯誤檢查功能。此錯誤檢查的度量稱為編碼速率,可以設定四個值。編碼速率設為最低的4/5時,傳輸不太穩定,速度稍快。編碼速率設為最高的4/8時,鏈路更可靠,但代價是數據傳輸速率較慢。
庫的默認設置為:帶寬為500 kHz、編碼速率為4/5和擴頻因子為12。這些設置是范圍、穩定性和數據速率之間的合理平衡。當然,這些設置可以通過函數隨時更改。
該庫內置數據包類和尋址系統。地址長度為8字節,那么最大的尋址數量就是1.8千億億(1.8 × 10^19)。這個數值大的離譜。相比之下,NASA估計我們銀河系中的恒星數量僅為“4億”(4×10^11)。每個數據包由源地址、目標地址和最多240字節的有效負載組成。當然,該庫還提供了幾種讀取和寫入分組數據的方法。
讓我們來看一下使用這個庫是多么容易。假設我們有兩個帶有SX1278模塊的LoRenz開發板。它們相距幾百米,所以我們可以使用默認設置。首先,我們必須包含庫頭文件。然后,我們用默認設置創建 LoRa 類的一個實例,用目標地址和消息創建 packet 類的一個實例。源地址由庫自動生成并寫入Arduino EEPROM。要檢查所有內容是否已正確保存,我們會讀取數據包信息并將其打印到串行端口。接下來,我們只需調用 tx() 函數即可。一會兒之后……完成!只需一個命令,我們的數據包就傳送成功了!
// include the library #include // create instance of LoRa class with default settings LoRa lora; // create instance of packet class // destination: "20:05:55:FE:E1:92:8B:95" // data: "Hello World !" packet pack("20:05:55:FE:E1:92:8B:95", "Hello World!"); void setup() { Serial.begin(9600); // initialize the LoRa module with default settings lora.init(); // create a string to store the packet information char str[24]; // print the source of the packet pack.getSourceStr(str); Serial.println(str); // print the destination of the packet pack.getDestinationStr(str); Serial.println(str); // print the length of the packet Serial.println(pack.length); // print the data of the packet Serial.println(pack.data); } void loop() { Serial.print("Sending packet "); // start transmitting the packet uint8_t state = lora.tx(pack); if(state == 0) { // if the function returned 0, a packet was successfully transmitted Serial.println(" success!"); } else if(state == 1) { // if the function returned 1, the packet was longer than 256 bytes Serial.println(" too long!"); } // wait a second before transmitting again delay(1000); }
當然,我們需要第二套配有LoRenz 開發板的Arduino來接收該數據包。 系統設置不變,只是這次我們調用 rx() 函數,然后打印接收到的數據包。此函數將等待數據包,如果數據沒有在某個時間內到達,該函數將超時,以便您的代碼不會完全掛起。該庫甚至還會檢查傳輸的數據包是否已損壞,如果是,則將其丟棄。
// include the library #include // create instances of LoRa and packet classes with default settings LoRa lora; packet pack; void setup() { Serial.begin(9600); // initialize the LoRa module with default settings lora.init(); } void loop() { Serial.print("Waiting for incoming transmission ... "); // start receiving single packet uint8_t state = lora.rx(pack); if(state == 0) { // if the function returned 0, a packet was successfully received Serial.println("success!"); // create a string to store the packet information char str[24]; // print the source of the packet pack.getSourceStr(str); Serial.println(str); // print the destination of the packet pack.getDestinationStr(str); Serial.println(str); // print the length of the packet Serial.println(pack.length); // print the data of the packet Serial.println(pack.data); } else if(state == 1) { // if the function returned 1, no packet was received before timeout Serial.println("timeout!"); } else if(state == 2) { // if the function returned 2, a packet was received, but is malformed Serial.println("CRC error!"); } }
當然,這只是最基本的例子。庫本身可以做更多事情,而且我還在繼續開發更多的功能。有關該庫和所有其他功能的更深入信息,請參閱我的 GitHub 以及那里托管的文檔。
Arduino 加密
本文結束之前,我還想討論一下Arduino的加密。我在上一篇文章中提到了這個問題。現在,我們發送的所有數據都是未加密的。這意味著擁有相同配置、使用相同模塊和相同設置的任何人都能攔截和閱讀我們的消息。攻擊者甚至可以發送自己的消息,而我們卻無法分辨。顯然,這并不安全。
最簡單的解決方案就是使用某種加密。具體地,我決定使用 Rijndael 密碼。沒聽說過吧?這是因為這個名字是荷蘭語,因此不好記憶和發音。密碼本身實際上非常普遍,但名稱更加引人注目:AES。它是一種對稱密碼,可在加密速度和安全性之間提供出色的平衡。此外,Arduino還提供了幾個AES庫!本項目使用的庫是Davy Landman開發的AESLib(可從 GitHub 上獲得)。
如上所述,AES是一種對稱密碼 – 這意味著它使用相同的密鑰來加密和解密消息?,F在,我們只有兩個設備,因此將密鑰硬編碼到Arduino中非常容易。當然,如果我們想要動態添加更多設備并創建某種無線網絡,我們必須以某種方式實現安全密鑰交換,例如使用Diffie-Hellman交換。但是我們現在不會深入這個領域,我們只需將密鑰硬編碼到我們的Arduino程序中即可。
那么我們應該如何修改上一章的代碼呢?修改并不多,說實話,我們只需添加密鑰以及一個加密或解密數據包中的數據。這是發射機部分,加密通過 aes128_enc_single() 函數完成。
// include the libraries #include #include // create instance of LoRa class with default settings LoRa lora; // create instance of packet class // destination: "20:05:55:FE:E1:92:8B:95" // data: "Hello World !" packet pack("20:05:55:FE:E1:92:8B:95", "Hello World! "); // our secret 16-byte long key uint8_t key[] = {0x2C, 0x66, 0x54, 0x94, 0xE3, 0xAE, 0xC7, 0x32, 0xC4, 0x66, 0xC8, 0xBE, 0xF3, 0x71, 0x22, 0x36}; void setup() { Serial.begin(9600); // initialize the LoRa module with default settings lora.init(); // create strings to store the packet information char src[24]; char dest[24]; // print the source of the packet pack.getSourceStr(src); Serial.print("Source:ttt"); Serial.println(src); // print the destination of the packet pack.getDestinationStr(dest); Serial.print("Destination:tt"); Serial.println(dest); // print the length of the packet Serial.print("Total # of bytes:t"); Serial.println(pack.length); // print the contents of unencrypted packet Serial.println("-------- Plain text ---------"); Serial.println(pack.data); // encrypt the data aes128_enc_single(key, pack.data); // print the contents of encrypted packet Serial.println("--- Encrypted with AES128 ---"); Serial.println(pack.data); } void loop() { Serial.print("Sending packet "); // start transmitting the packet uint8_t state = lora.tx(pack); if(state == 0) { // if the function returned 0, a packet was successfully transmitted Serial.println(" success!"); } else if(state == 1) { // if the function returned 1, the packet was longer than 256 bytes Serial.println(" too long!"); } // wait a second before transmitting again delay(1000); }
接收機部分如下所示,解密通過相同密鑰和函數 aes128_dec_single() 完成。
// include the libraries #include #include // create instances of LoRa and packet classes with default settings LoRa lora; packet pack; // our secret 16-byte long key uint8_t key[] = {0x2C, 0x66, 0x54, 0x94, 0xE3, 0xAE, 0xC7, 0x32, 0xC4, 0x66, 0xC8, 0xBE, 0xF3, 0x71, 0x22, 0x36}; void setup() { Serial.begin(9600); // initialize the LoRa module with default settings lora.init(); } void loop() { Serial.print("Waiting for incoming transmission ... "); // start receiving single packet uint8_t state = lora.rx(pack); if(state == 0) { // if the function returned 0, a packet was successfully received Serial.println("success!"); // create strings to store the packet information char src[24]; char dest[24]; // print the source of the packet pack.getSourceStr(src); Serial.print("Source:ttt"); Serial.println(src); // print the destination of the packet pack.getDestinationStr(dest); Serial.print("Destination:tt"); Serial.println(dest); // print the length of the packet Serial.print("Total # of bytes:t"); Serial.println(pack.length); // print the contents of encrypted packet Serial.print("Encrypted (AES128):t"); Serial.println(pack.data); // decrypt the data aes128_dec_single(key, pack.data); // print the contents of unencrypted packet Serial.print("Plain text:tt"); Serial.println(pack.data); } else if(state == 1) { // if the function returned 1, no packet was received before timeout Serial.println("timeout!"); } else if(state == 2) { // if the function returned 2, a packet was received, but is malformed Serial.println("CRC error!"); } }
使用了密鑰之后,我們的消息現在是安全的。如果有人偷聽我們的談話,他無法看到除地址之外的任何內容,每個數據包中都是240字節的亂碼。同樣,如果攻擊者試圖傳輸他自己的消息,我們會立即知道,因為他傳輸的消息不會加密。
在Arduino上用AES加密非常簡單,所以我推薦使用該加密方法。這不僅僅是一個很好的編程實踐。您永遠不知道誰以及為什么可能會偷聽您看似無辜的對話。
結論
現在,Arduino遠程無線通信的短暫旅途就要結束了。如果您開發自己的LoRenz開發板并將其應用于一些很酷的Arduino項目,請告訴我!如果您有改進LoRenz開發板和LoRaLib庫的想法,請在GitHub上與我分享。
我對開發板進行了測試,當帶寬為500kHz、擴展因子為12、編碼率為4/8時,在無障礙環境中我能夠實現超過500米的可靠傳輸;在茂密的森林中傳輸距離則超過200米。所有這一切都只是通過一根10cm天線實現的,而且發射器電源也只是廉價的9V電池而已(接收器從USB端口接電,最終通過Arduino板載穩壓器供電)。這個距離還可以更長(通過降低帶寬),但是這會導致傳輸速度顯著降低,在上述設置不變的情況下傳輸速度大約為1 kbps。
然而,對于我將來的項目,這些距離綽綽有余。請在社交媒體上關注DevicePlus,這樣您就不會錯過任何有趣的內容!
審核編輯:湯梓紅
-
通信
+關注
關注
18文章
6072瀏覽量
136432 -
開發板
+關注
關注
25文章
5121瀏覽量
98214 -
Arduino
+關注
關注
188文章
6477瀏覽量
187836
發布評論請先 登錄
相關推薦
請問USB模擬串口如何實現長距離通信?
長距離光模塊大全
長距離通信器S1503 的應用編程原理
超長距離光纖通信系統中的新型技術
長距離EPON的設計研究方案
![<b class='flag-5'>長距離</b>EPON的設計研究方案](https://file1.elecfans.com//web2/M00/A5/81/wKgZomUMOL6AafBhAAAkxzcJjro618.jpg)
長距離EPON的研究分析
基于Semtech的LoRa擴頻通信技術實現的超長距離低功耗物聯網解決方案
![基于Semtech的LoRa擴頻<b class='flag-5'>通信</b>技術實現的超<b class='flag-5'>長距離</b>低功耗物聯網解決方案](https://file1.elecfans.com//web2/M00/A7/2F/wKgZomUMQuKAd9g4AAAilkpHFyo690.png)
物聯網通信網絡層中短距離無線通信網與長距離無線通信網的區別
Arduino長距離通信教程–LoRenz開發板
![<b class='flag-5'>Arduino</b><b class='flag-5'>長距離</b><b class='flag-5'>通信教</b>程–LoRenz開發板](https://file.elecfans.com/web2/M00/92/7B/poYBAGPzFj2ATRO9AAI6wuHkqjk940.jpg)
評論