Dieses Repository ist ein Ort, an dem ich alle Projekte für die Entwicklung von Lora Rhmesh für meine These einbeziehe. Ich stelle alle Projekte im
projectsan. Alle Entwicklung, die aus vielen verschiedenen Projekten im Internet verstreut sind, aber ich versuche, sie zu einem funktionierenden und verständlichen Projekt zu vereinfachen und zu pflegen.Ich entwickle hauptsächlich auf einem ESP32 -Board, das mit einem RFM95 -Lora -Chip verbunden ist. Es überträgt auf 915 MHz. Ich entwickle in 2 Umgebungen, Arduino IDE, Plattform IO VSCODE -Plugin.
Fühlen Sie sich frei, sie zu verwenden und kontaktieren Sie mich, wenn Sie so wollen!
Diese Beispielskizze zeigt, wie Sie einen einfachen, adressierten, Routed zuverlässigen Messaging -Client mit der Rhmesh -Klasse erstellen. Es ist so konzipiert, dass es mit den anderen Beispielen rf95_mesh_server funktioniert
#define SELF_ADDRESS NODE3_ADDRESS
#define TARGET_ADDRESS FINAL_ADDRESS
RH_TEST_NETWORK festlegen. Lesen Sie mehr im Abschnitt "Zwangstopologie" [RFM95] ------------- [ESP32]
RESET -------------- GPIO14
NSS/CS -------------- GPIO5
SCK -------------- GPIO18
MOSI -------------- GPIO23
MISO -------------- GPIO19
DIO0 -------------- GPIO2
3.3V -------------- 3.3V
GND -------------- GND


Wenn Sie ein anderes Verkabelungsschema haben, vergessen Sie nicht, diese Linien in Main.cpp zu ändern
#define RFM95_CS 5
#define RFM95_RST 14
#define RFM95_INT 2

Dieses Beispiel einer 4 -Knoten -Topologie, bei der der FINAL_ADDRESS -Knoten der letzte Knoten im Netzwerk ist, der eine gemeinsame Topologie simuliert, in der dieser letzte Knoten als Grenzknoten fungieren würde, das mit dem Internet verbunden ist, während er während seiner Lebensdauer Nachrichten von anderen Knoten sammelt und dann an die Wolke gesendet wird. Der Knoten 1-3 würde Sensordaten sammeln und dann an den endgültigen Knoten senden, und in dem Prozessknoten 1-3 könnte ein Zwischenknoten für einander sein. Fühlen Sie sich frei, ein völlig anderes Adressierungsschema zu machen.
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define FINAL_ADDRESS 255 // purposefully using the last namber
Sie können das Verhalten des aktuellen Knotens aktiv ändern, indem Sie diese Zeile ändern. Stellen Sie sicher, dass Sie es für jeden verschiedenen Knoten ändern!
const uint8_t selfAddress_ = NODE3_ADDRESS;
const uint8_t targetAddress_ = FINAL_ADDRESS;

Nachdem eine Route für einen Zielknoten entdeckt wurde, wird sie als Routeneintrag seiner Routing -Tabelle in diesem einzelnen Knoten gespeichert. Durch das Speichern des nächsten direkten Knotens, von dem erwartet wird, dass er ihn mit dem Zielknoten verbinden kann, auch als Vermittler. In diesem Beispiel speichert node 2 nur node 1 in seinem Routeneintrag, um mit node final eine Verbindung herzustellen, ohne zu wissen, ob node 1 der einzige Zwischenknoten ist, oder möglicherweise mehr. Daher wird node 1 voraussichtlich eine Route zur Verbindung mit node final haben. In diesem Beispiel wird es eine direkte Verbindung sein. node 2 hat keinen direkten Weg zum node final , aber eine direkte Verbindung mit node 3
Wechseln Sie zu 915.0, 434.0 oder einer anderen Frequenz, müssen mit dem Freq von Lora Chip/RX übereinstimmen!
#define RF95_FREQ 915.0
Durch die Verwendung von Mesh hat es viel größere Speicheranforderungen als nur RH oder RHROUTER, und Sie müssen möglicherweise die maximale Nachrichtenlänge (Zeichen) einschränken, um seltsame Abstürze zu verhindern. Sie können sich jedoch ändern und mit Nachrichtenlängen experimentieren, indem Sie dies ändern
#define RH_MESH_MAX_MESSAGE_LEN 50
Sie können spezifische LORA -Modi für das RFM95 -Modul hinzufügen, indem Sie den rhSetup() bearbeiten. Standardeinstellungen nach Init (ohne explizit .set ) sind 434,0 MHz, 0,05 MHz AFC Pull-In, Modulation FSK_RB2_4FD36.
RHDriver.setTxPower(23, false);
RHDriver.setFrequency(RF95_FREQ);
RHDriver.setCADTimeout(500);
Obwohl dieses Projekt auf Rhmesh ausgeführt wird, was erwarten würde, dass der Benutzer eine voll dynamische und flüssige Topologie hat, können Sie die Routen/Topologie erzwingen. Es erfordert ein wenig hartcodieren, Sie können den Code in RHROUTER.CPP (Zeile 223-263) inspizieren. Es gibt bereits einige vorgefertigte Topologie -Beispiele, die das Routing auf eine bestimmte Art und Weise erzwingen (dies geschieht, indem sie Nachrichten fallen/nicht verarbeitet, die den Pfad nicht entsprechen), und das Makro RH_TEST_NETWORK muss definiert werden (bevor #include "Rhmesh.h" bezeichnet wird), um diese erzwungene Topologie zu aktivieren. Sie können natürlich Ihren eigenen Code hinzufügen, der Ihrer gewünschten Topologie ähnelt.
...
#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))
...
Wir senden eine Nachricht an einen anderen Rhmesh -Knoten mit diesem Code, eine Route zum Ziel wird automatisch festgestellt. Diese Erkennungsfunktion ist der Hauptpunkt bei der Verwendung von Rhmesh und generiert automatisch eine Routing -Tabelle für diesen Knoten (zur weiteren Untersuchung finden Sie die Funktion bool doArp(uint8_t address); in RHMesh.h ).
if (RHMeshManager.sendtoWait(reinterpret_cast<uint8_t *>(&msgSend[0]), msgSend.size(), targetAddress_) == RH_ROUTER_ERROR_NONE) {
Nach dieser Zeile bedeutet eine Rückkehr von true , dass uns die Nachricht zuverlässig an den nächsten Knoten abgegeben wurde, und der nächste Knoten hat uns einen "Ack" geschickt. Wenn es nach einer bestimmten Zeit keinen ACK gibt, gibt der SendTowait einen false zurück. Ein wichtiger Hinweis ist, dass der ACK nicht vom Zielknoten stammt, sondern Anynode, die die Nachricht erfolgreich empfangen hat (außer dem Zielknoten, ein Zwischenknoten). Derzeit zeigt Rhmesh nicht an, ob eine Nachricht erfolgreich an den 'endgültigen' zugewiesenen Zielknoten empfangen wurde. Ein Umgang mit "Simply" ist "Simply" zum Hinzufügen einer hohen Level-/Anwendungsschichtlogik zum "endgültigen" Zielknoten, wobei eine etwas REPLY_TYPE an den 'Anfangsabsenderknoten nach einer Nachricht als künstliche ACK gesendet wird (eine solche Funktion wird derzeit in diesem Repo derzeit nicht implementiert).
Nachdem wir eine Nachricht erfolgreich gesendet haben, wenden wir uns in RECEIVING_MODE und warten auf eine Nachricht, die von einem anderen Knoten stammt. Während recvfromAckTimeout aktiv ist, werden Aktivitäten durchgeführt, bis eine Nachricht eintrifft oder Timeout erreicht.
if (RHMeshManager.recvfromAckTimeout(_msgRcvBuf, (uint8_t *) sizeof(_msgRcvBuf), 3000, &_msgFrom)) {
localVariable_
_tempVariable
globalVariable