Ce référentiel est un endroit où j'inclut tous les projets pour le développement de Lora Rhmesh pour ma thèse. Je fournis tous les projets dans le dossier
projects. Tous les développements collectés dans de nombreux projets différents dispersés sur Internet, mais j'essaie de les simplifier et de les préparer à un projet de travail et compréhensible.Je me développe principalement sur une carte ESP32, connecté avec une puce LORA RFM95. Il transmet à 915 MHz. Je me développe sur 2 environnements, Arduino IDE, Plateforme IO VScode Plugin.
N'hésitez pas à les utiliser et contactez-moi si vous voulez!
Cet exemple de croquis montre comment créer un client de messagerie fiable adressé simple et acheminé avec la classe RhMesh. Il est conçu pour fonctionner avec les autres exemples RF95_Mesh_Server
#define SELF_ADDRESS NODE3_ADDRESS
#define TARGET_ADDRESS FINAL_ADDRESS
RH_TEST_NETWORK définir votre topologie dans rhrouter.cpp. En savoir plus dans la section Topologie forcée [RFM95] ------------- [ESP32]
RESET -------------- GPIO14
NSS/CS -------------- GPIO5
SCK -------------- GPIO18
MOSI -------------- GPIO23
MISO -------------- GPIO19
DIO0 -------------- GPIO2
3.3V -------------- 3.3V
GND -------------- GND


Si vous avez un schéma de câblage différent, n'oubliez pas de changer ces lignes dans Main.cpp
#define RFM95_CS 5
#define RFM95_RST 14
#define RFM95_INT 2

Cet exemple de topologie de 4 nœuds, dans lequel le nœud FINAL_ADDRESS devrait être le dernier nœud du réseau, simulant une topologie commune dans laquelle ce dernier nœud agirait comme un nœud de bordure connecté à Internet, collectant des messages à partir d'autres nœuds pendant sa durée de vie, puis les envoyant à Cloud. Le nœud 1-3 collecterait les données du capteur puis envoyait au nœud final et, dans le processus, le nœud 1-3 pourrait être un nœud intermédiaire l'un pour l'autre. N'hésitez pas à faire un schéma d'adressage totalement différent.
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define FINAL_ADDRESS 255 // purposefully using the last namber
Vous pouvez changer activement le comportement des nœuds actuel en modifiant cette ligne. Assurez-vous de le changer pour chaque nœud différent!
const uint8_t selfAddress_ = NODE3_ADDRESS;
const uint8_t targetAddress_ = FINAL_ADDRESS;

Une fois un itinéraire découvert pour un nœud cible, il sera enregistré comme entrée d'itinéraire de sa table de routage dans ce nœud individuel. En enregistrant le prochain nœud direct qui devrait pouvoir le connecter avec le nœud cible, même en tant qu'intermédiaire. Ainsi, dans cet exemple, node 2 enregistre uniquement node 1 dans son entrée d'itinéraire pour se connecter avec node final , sans savoir si node 1 est le seul nœud intermédiaire, ou pourrait-il y en avoir plus. Par conséquent, node 1 devrait avoir une route pour se connecter avec node final , dans cet exemple, ce sera une connexion directe. node 2 n'a pas de route directe vers node final , mais il a une connexion directe avec node 3
Passez à 915.0, 434,0 ou autre fréquence, doit correspondre à Freq de Lora Chip / RX!
#define RF95_FREQ 915.0
En utilisant le maillage, il a des exigences de mémoire beaucoup plus importantes que RH ou Rhrouter, et vous devrez peut-être limiter la longueur du message maximum (caractères) pour éviter les collisions bizarres. Bien que vous puissiez changer et expérimenter avec des longueurs de message en modifiant ce
#define RH_MESH_MAX_MESSAGE_LEN 50
Vous pouvez ajouter des modes LORA spécifiques pour le module RFM95 en modifiant le rhSetup() . Les défauts par défaut après init (sans aucun .set explicite) sont 434.0 MHz, 0,05 MHz AFC Pull-In, modulation FSK_RB2_4FD36.
RHDriver.setTxPower(23, false);
RHDriver.setFrequency(RF95_FREQ);
RHDriver.setCADTimeout(500);
Même si ce même projet fonctionne sur Rhmesh, qui s'attendrait à ce que l'utilisateur ait une topologie entièrement dynamique et fluide, vous pouvez forcer les itinéraires / topologie. Cela nécessite un peu de codage rigide, vous pouvez inspecter le code dans rhrouter.cpp (ligne 223-263). Il a déjà des exemples de topologie pré-même qui oblige le routage d'une certaine manière (il le fait en supprimant / ne traitant pas des messages qui ne respectent pas le chemin), et la macro RH_TEST_NETWORK doit être définie (avant d'appeler #include "rhmesh.h") pour activer cette topologie forcée. Vous pouvez bien sûr ajouter votre propre code qui ressemble à la topologie souhaitée.
...
#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))
...
Nous enverrons un message à un autre nœud RhMesh en utilisant ce code, une route vers la destination sera automatiquement découverte. Cette fonction de découverte est le point principal de l'utilisation de RhMesh, il génère automatiquement une table de routage pour ce nœud (pour une enquête plus approfondie, consultez la fonction bool doArp(uint8_t address); dans RHMesh.h ).
if (RHMeshManager.sendtoWait(reinterpret_cast<uint8_t *>(&msgSend[0]), msgSend.size(), targetAddress_) == RH_ROUTER_ERROR_NONE) {
Après cette ligne, un retour de true signifie que nous avons été transmis de manière fiable le message au nœud suivant, et le nœud suivant nous a envoyé un «ack». Si après un certain temps, il n'y a pas de ACK, le SendTowait renvoie un false . Une note importante est que l'ACK ne provient pas du nœud cible, mais AnyNode qui a réussi le message (autre que le nœud cible, est un nœud intermédiaire). Actuellement, RhMesh ne dit pas si un message a été reçu avec succès au nœud cible affecté «final». Un moyen de contourner cela est "simplement" en ajoutant une logique de couche de niveau / application de haut niveau au nœud cible 'final', en envoyant un message quelque peu REPLY_TYPE au nœud d'expéditeur 'initial' après avoir reçu un message, en tant que ACK artificiel (une telle fonctionnalité n'est actuellement pas implémentée dans ce repo).
Après avoir réussi un message, nous nous transformons en RECEIVING_MODE et attendons un message provenant d'un autre nœud. Bien que recvfromAckTimeout soit actif, il organisera des activités jusqu'à ce qu'un message arrive ou que le délai est atteint.
if (RHMeshManager.recvfromAckTimeout(_msgRcvBuf, (uint8_t *) sizeof(_msgRcvBuf), 3000, &_msgFrom)) {
localVariable_
_tempVariable
globalVariable