Este repositorio es un lugar en el que incluyo todos los proyectos para el desarrollo de Lora Rhmesh para mi tesis. Proporciono todos los proyectos dentro de la carpeta
projects. Todo el desarrollo recopilado de muchos proyectos diferentes dispersos en Internet, pero trato de simplificarlos y prepararlos a un proyecto que trabaja y comprensible.Desarrollo principalmente en una placa ESP32, conectada con un chip Lora RFM95. Transmite en 915 MHz. Desarrollo en 2 entornos, Arduino IDE, Plugin VSCode de plataforma IO.
¡Siéntase libre de usarlos y contácteme si es así,!
Este boceto de ejemplo muestra cómo crear un cliente de mensajería confiable enrutado y dirigido simple con la clase RHMESH. Está diseñado para funcionar con los otros ejemplos rf95_mesh_server
#define SELF_ADDRESS NODE3_ADDRESS
#define TARGET_ADDRESS FINAL_ADDRESS
RH_TEST_NETWORK define su topología en rhrouter.cpp. Leer más en la sección de topología forzada [RFM95] ------------- [ESP32]
RESET -------------- GPIO14
NSS/CS -------------- GPIO5
SCK -------------- GPIO18
MOSI -------------- GPIO23
MISO -------------- GPIO19
DIO0 -------------- GPIO2
3.3V -------------- 3.3V
GND -------------- GND


Si tiene un esquema de cableado diferente, no olvide cambiar estas líneas en main.cpp
#define RFM95_CS 5
#define RFM95_RST 14
#define RFM95_INT 2

Este ejemplo de una topología de 4 nodos, en la que se espera que el nodo FINAL_ADDRESS sea el último nodo en la red, simulando una topología común en la que este último nodo actuaría como un nodo fronterizo conectado a Internet, recopilando mensajes de otros nodos durante su vida y luego enviarlos a la nube. El nodo 1-3 recopilaría datos del sensor y luego se enviaría al nodo final, y en el proceso el nodo 1-3 podría ser un nodo intermediario entre sí. Siéntase libre de hacer un esquema de direccionamiento totalmente diferente.
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define FINAL_ADDRESS 255 // purposefully using the last namber
Puede cambiar activamente el comportamiento de los nodos actuales cambiando esta línea. ¡Asegúrate de cambiarlo por cada nodo diferente!
const uint8_t selfAddress_ = NODE3_ADDRESS;
const uint8_t targetAddress_ = FINAL_ADDRESS;

Después de descubrir una ruta para un nodo objetivo, se guardará como una entrada de ruta de su tabla de enrutamiento dentro de ese nodo individual. Al guardar el siguiente nodo directo que se espera que pueda conectarlo con el nodo de destino, incluso como intermediario. Entonces, en este ejemplo, node 2 solo guarda node 1 en su entrada de ruta para conectarse con node final , sin saber si node 1 es el único nodo intermediario, o podría haber más. Por lo tanto, se espera que node 1 tenga una ruta para conectarse con node final , en este ejemplo será una conexión directa. node 2 no tiene una ruta directa al node final , pero tiene una conexión directa con node 3
Cambiar a 915.0, 434.0 u otra frecuencia, ¡debe coincidir con la frecuencia de Lora Chip/RX!
#define RF95_FREQ 915.0
Al usar MESH, tiene requisitos de memoria mucho mayores que solo Rh o RhRouter, y es posible que deba limitar la longitud del mensaje máximo (caracteres) para evitar bloqueos extraños. Aunque puede cambiar y experimentar con longitudes de mensaje cambiando esto
#define RH_MESH_MAX_MESSAGE_LEN 50
Puede agregar modos LORA específicos para el módulo RFM95 editando el rhSetup() . Los valores predeterminados después de init (sin ningún .set .
RHDriver.setTxPower(23, false);
RHDriver.setFrequency(RF95_FREQ);
RHDriver.setCADTimeout(500);
Aunque este mismo proyecto se ejecuta en RhMesh, lo que esperaría que el usuario tenga una topología completamente dinámica y fluida, puede forzar las rutas/topología. Requiere un poco de codificación difícil, puede inspeccionar el código en rhrouter.cpp (línea 223-263). Ya tiene algunos ejemplos de topología prefabricados que obliga a la enrutamiento de cierta manera (lo hace soltando/no procesando mensajes que no cumplan la ruta), y la macro RH_TEST_NETWORK debe definirse (antes de llamar #include "rhmesh.h") para activar esta topología forzada. Puede, por supuesto, agregar su propio código que se asemeja a la topología deseada.
...
#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))
...
Enviaremos un mensaje a otro nodo RhMesh usando este código, se descubrirá automáticamente una ruta al destino. Esta función de descubrimiento es el punto principal de usar RhMesh, genera automáticamente una tabla de enrutamiento para este nodo (para una investigación adicional, consulte la función bool doArp(uint8_t address); en RHMesh.h ).
if (RHMeshManager.sendtoWait(reinterpret_cast<uint8_t *>(&msgSend[0]), msgSend.size(), targetAddress_) == RH_ROUTER_ERROR_NONE) {
Después de esa línea, una devolución de true significa que nos han entregado de manera confiable el mensaje al siguiente nodo, y el siguiente nodo nos ha enviado un 'ACK'. Si después de cierto tiempo no hay ACK, el SendTowait devolverá un false . Una nota importante es que el ACK no es del nodo de destino, pero AnyNode que ha recibido con éxito el mensaje (que no sea el nodo de destino, es un nodo intermediario). Actualmente, RhMesh no cuenta si se ha recibido un mensaje con éxito al nodo de destino asignado 'final'. Una forma de evitar esto es "simplemente" agregando una lógica de capa de alto nivel/aplicación al nodo de destino 'final', enviando un mensaje REPLY_TYPE a un poco al nodo 'inicial' después de recibir un mensaje, como una ACK artificial (dicha característica actualmente no se implementa en este repositorio).
Después de enviar con éxito un mensaje, nos convirtimos en RECEIVING_MODE y esperamos un mensaje que provenga de otro nodo. Mientras que recvfromAckTimeout está activo, mantendrá actividades hasta que llegue un mensaje o se alcance el tiempo de espera.
if (RHMeshManager.recvfromAckTimeout(_msgRcvBuf, (uint8_t *) sizeof(_msgRcvBuf), 3000, &_msgFrom)) {
localVariable_
_tempVariable
globalVariable