Este repositório é um lugar em que incluo todos os projetos para o desenvolvimento de Lora RhMesh para minha tese. Eu forneço todos os projetos na pasta
projects. Todo o desenvolvimento coletado de muitos projetos diferentes espalhados por toda a Internet, mas tento simplificar e prepará -los a um projeto funcional e compreensível.Eu desenvolvo principalmente uma placa ESP32, conectada a um chip RFM95 Lora. Transmite em 915 MHz. Eu desenvolvo em 2 ambientes, Arduino IDE, Platform IO VSCODE Plugin.
Sinta -se à vontade para usá -los e entre em contato comigo se quiser!
Este exemplo de esboço mostra como criar um cliente simples de mensagens confiável e endereçado e endereçado com a classe RHMESH. Ele foi projetado para funcionar com os outros exemplos RF95_MESH_SERVER
#define SELF_ADDRESS NODE3_ADDRESS
#define TARGET_ADDRESS FINAL_ADDRESS
RH_TEST_NETWORK Definir sua topologia em rhrouter.cpp. Leia mais na seção de topologia forçada [RFM95] ------------- [ESP32]
RESET -------------- GPIO14
NSS/CS -------------- GPIO5
SCK -------------- GPIO18
MOSI -------------- GPIO23
MISO -------------- GPIO19
DIO0 -------------- GPIO2
3.3V -------------- 3.3V
GND -------------- GND


Se você tem um esquema de fiação diferente, não se esqueça de mudar essas linhas em main.cpp
#define RFM95_CS 5
#define RFM95_RST 14
#define RFM95_INT 2

Este exemplo de uma topologia de 4 nós, na qual o nó FINAL_ADDRESS deve ser o último nó da rede, simulando uma topologia comum na qual esse último nó atuaria como um nó de fronteira conectado à Internet, coletando mensagens de outros nós durante a vida e depois enviando -os para a nuvem. O nó 1-3 coletaria dados do sensor e envia para o nó final e, no nó do processo, 1-3 poderia ser um nó intermediário um para o outro. Sinta -se à vontade para criar um esquema de endereçamento totalmente diferente.
#define NODE1_ADDRESS 1
#define NODE2_ADDRESS 2
#define NODE3_ADDRESS 3
#define FINAL_ADDRESS 255 // purposefully using the last namber
Você pode alterar ativamente o comportamento dos nós atuais alterando essa linha. Certifique -se de alterar para cada nó diferente!
const uint8_t selfAddress_ = NODE3_ADDRESS;
const uint8_t targetAddress_ = FINAL_ADDRESS;

Depois que uma rota é descoberta para um nó de destino, ela será salva como uma entrada de rota de sua tabela de roteamento dentro desse nó individual. Salvando o próximo nó direto que deve conectá -lo com o nó de destino, mesmo como intermediário. Portanto, neste exemplo, node 2 salva apenas node 1 na entrada de rota para se conectar à node final , sem saber se node 1 é o único nó intermediário ou pode haver mais. Portanto, espera -se que node 1 tenha uma rota para se conectar à node final ; neste exemplo, será uma conexão direta. node 2 não tem uma rota direta para a node final , mas tem uma conexão direta com node 3
Alterar para 915.0, 434.0 ou outra frequência, deve corresponder à Freq de Lora Chip/RX!
#define RF95_FREQ 915.0
Ao usar a malha, possui requisitos de memória muito maiores do que apenas RH ou RHRouter, e você pode precisar limitar o comprimento da mensagem máxima (caracteres) para evitar falhas estranhas. Embora você possa mudar e experimentar com comprimentos de mensagem alterando isso
#define RH_MESH_MAX_MESSAGE_LEN 50
Você pode adicionar modos LORA específicos para o módulo RFM95 editando o rhSetup() . Os padrões após o init (sem qualquer .set explícito) são 434,0MHz, 0,05MHz AFC Pull-In, modulação FSK_RB2_4FD36.
RHDriver.setTxPower(23, false);
RHDriver.setFrequency(RF95_FREQ);
RHDriver.setCADTimeout(500);
Embora esse projeto seja executado em RhMesh, o que esperaria que o usuário tivesse uma topologia totalmente dinâmica e fluida, você pode forçar as rotas/topologia. Requer um pouco de codificação, você pode inspecionar o código em rhrouter.cpp (linha 223-263). Ele já possui alguns exemplos de topologia pré -fabricados que força o roteamento de uma certa maneira (faz isso soltando/não processando mensagens que não cumprem o caminho), e a macro RH_TEST_NETWORK precisa ser definida (antes de chamar #include "rhMesh.h") para ativar essa topologia forçada. É claro que você pode adicionar seu próprio código que se assemelha à topologia desejada.
...
#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 uma mensagem para outro nó RHMESH usando este código, uma rota para o destino será descoberta automaticamente. Essa função de descoberta é o ponto principal do uso de RhMesh, gera automaticamente uma tabela de roteamento para este nó (para uma investigação mais aprofundada, confira a função bool doArp(uint8_t address); em RHMesh.h ).
if (RHMeshManager.sendtoWait(reinterpret_cast<uint8_t *>(&msgSend[0]), msgSend.size(), targetAddress_) == RH_ROUTER_ERROR_NONE) {
Após essa linha, um retorno do true significa que fomos entregues com segurança a mensagem para o próximo nó, e o próximo nó nos enviou um 'ACK'. Se, depois de um certo tempo, não houver ACK, o SendTowait retornará um false . Uma nota importante é que o ACK não é do nó de destino, mas qualquer nó que tenha recebido a mensagem com sucesso (que não seja o nó de destino, é um nó intermediário). Atualmente, RhMesh não informa se uma mensagem foi recebida com sucesso no nó de destino 'final' atribuído. Uma maneira de contornar isso é "simplesmente" adicionando uma lógica de camada de alto nível/aplicativo ao nó de destino 'final', enviando uma mensagem um pouco REPLY_TYPE para o nó do remetente 'inicial' 'depois de receber uma mensagem, como um ACK artificial (esse recurso não é implementado atualmente neste Repo).
Depois de enviar uma mensagem com sucesso, nos transformamos em RECEIVING_MODE e aguardamos uma mensagem proveniente de outro nó. Enquanto recvfromAckTimeout estiver ativo, ele realizará atividades até que uma mensagem chegue ou o tempo limite atingido.
if (RHMeshManager.recvfromAckTimeout(_msgRcvBuf, (uint8_t *) sizeof(_msgRcvBuf), 3000, &_msgFrom)) {
localVariable_
_tempVariable
globalVariable