這個存儲庫是我為論文開發的所有項目的所有項目。我提供
projects文件夾中的所有項目。從互聯網上散佈的許多不同項目中收集的所有開發項目,但我試圖簡化並將其修飾為一個工作和可理解的項目。我主要在ESP32板上開發,該板與RFM95 Lora芯片相連。它在915 MHz上傳輸。我在2個環境,Arduino IDE,平台IO VSCODE插件上開發。
隨時使用它們,如果可以的話,請與我聯繫!
此示例草圖顯示瞭如何使用RHMESH類創建一個簡單的,路由的可靠消息客戶端。它旨在與其他示例一起使用RF95_MESH_SERVER
#define SELF_ADDRESS NODE3_ADDRESS
#define TARGET_ADDRESS FINAL_ADDRESS
RH_TEST_NETWORK在Rhrouter.cpp中定義您的拓撲來模擬其他網絡拓撲。在強制拓撲部分中閱讀更多 [RFM95] ------------- [ESP32]
RESET -------------- GPIO14
NSS/CS -------------- GPIO5
SCK -------------- GPIO18
MOSI -------------- GPIO23
MISO -------------- GPIO19
DIO0 -------------- GPIO2
3.3V -------------- 3.3V
GND -------------- GND


如果您有不同的接線方案,請不要忘記在main.cpp中更改這些行
#define RFM95_CS 5
#define RFM95_RST 14
#define RFM95_INT 2

這個4節點拓撲的示例,其中FINAL_ADDRESS節點有望成為網絡中的最後一個節點,模擬了一個通用拓撲,其中最後一個節點將充當連接到Internet的邊界節點,在其一生中收集來自其他節點的消息,然後將它們發送到雲。節點1-3將收集傳感器數據,然後發送到最終節點,在過程中,節點1-3可能是彼此的中間節點。隨意制定完全不同的尋址計劃。
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define FINAL_ADDRESS 255 // purposefully using the last namber
您可以通過更改此行來積極更改當前節點的行為。確保為每個不同節點更改它!
const uint8_t selfAddress_ = NODE3_ADDRESS;
const uint8_t targetAddress_ = FINAL_ADDRESS;

在發現目標節點的路由後,它將作為該單個節點內的路由表的路線入口保存。通過保存下一個直接節點,即使作為中介機構也可以將其連接到目標節點。因此,在此示例中, node 2僅在其路由輸入中保存node 1與node final連接,而不知道node 1是唯一的中間節點,還是可能還有更多。因此, node 1有望具有與node final連接的路線,在此示例中,它將是直接連接。 node 2沒有直接通往node final路由,但是它與node 3具有直接連接
更改為915.0、434.0或其他頻率,必須匹配Lora芯片/RX的Freq!
#define RF95_FREQ 915.0
通過使用網格,它的內存需求不僅僅是RH或RHROUTER,您可能需要限制最大消息長度(字符)以防止Wierd崩潰。儘管您可以通過更改消息長度進行更改和實驗
#define RH_MESH_MAX_MESSAGE_LEN 50
您可以通過編輯rhSetup()來為RFM95模塊添加特定的LORA模式。初始化後(沒有任何顯式.set )後的默認值為434.0MHz,0.05MHz AFC拉入,調製FSK_RB2_4FD36。
RHDriver.setTxPower(23, false);
RHDriver.setFrequency(RF95_FREQ);
RHDriver.setCADTimeout(500);
即使這個項目在RHMESH上運行,該項目希望用戶具有完全動態的流體拓撲,您也可以強制路線/拓撲。它需要一些硬編碼,您可以在rhrouter.cpp中檢查代碼(第223-263行)。它已經有了一些預製拓撲示例,這些示例可以以某種方式迫使路由(通過刪除/不處理不符合路徑的消息來實現此操作),並且需要定義宏RH_TEST_NETWORK (在調用#include“ rhmesh.h”)以激活這種強制拓撲。當然,您可以添加自己的代碼,它類似於您所需的拓撲。
...
#ifdef RH_TEST_NETWORK
if (
#if RH_TEST_NETWORK==1
// This network looks like 1-2-3-4
(_thisAddress == 1 && _from == 2)
|| (_thisAddress == 2 && (_from == 1 || _from == 3))
|| (_thisAddress == 3 && (_from == 2 || _from == 4))
|| (_thisAddress == 4 && _from == 3)
#elif RH_TEST_NETWORK==2
// This network looks like 1-2-4
// | | |
// --3--
(_thisAddress == 1 && (_from == 2 || _from == 3))
|| _thisAddress == 2
|| _thisAddress == 3
|| (_thisAddress == 4 && (_from == 2 || _from == 3))
...
我們將使用此代碼將消息發送到另一個Rhmesh節點,將自動發現通往目標的路由。此發現函數是使用RHMESH的重點,它會自動為該節點生成路由表(要進行進一步研究,請查看函數bool doArp(uint8_t address); in RHMesh.h中。
if (RHMeshManager.sendtoWait(reinterpret_cast<uint8_t *>(&msgSend[0]), msgSend.size(), targetAddress_) == RH_ROUTER_ERROR_NONE) {
在那條線之後, true的回報意味著我們已可靠地將消息傳遞到下一個節點,下一個節點向我們發送了一個“ ack”。如果一定時間沒有ACK,則SendTowait將返回一個false 。一個重要的說明是,ACK不是來自目標節點,而是成功收到消息的任何表(目標節點除外,是中間節點)。當前,Rhmesh並未確定是否已成功收到了“最終”分配的目標節點的消息。解決此問題的方法是“簡單地”在“最終”目標節點中添加高級別/應用程序層邏輯,在收到消息後,將某些REPLY_TYPE消息發送到'初始'發件人節點(作為人造ACK)(當前在此存儲庫中未實現此功能)。
成功發送消息後,我們將其變成RECEIVING_MODE ,並等待來自另一個節點的消息。雖然recvfromAckTimeout處於活動狀態,但它將舉辦活動,直到消息到達或達到超時為止。
if (RHMeshManager.recvfromAckTimeout(_msgRcvBuf, (uint8_t *) sizeof(_msgRcvBuf), 3000, &_msgFrom)) {
localVariable_
_tempVariable
globalVariable