Comunicação LoRa ponto-a-ponto com Módulos ESP32 LoRa 2

LoRa é, sem dúvidas, uma das tecnologias que mais chama a atenção dentro de toda a gama de tecnologias que engloba a Internet das Coisas. Isso se deve principalmente ao fato do LoRa ser uma tecnologia de rádio que permite comunicação entre dispositivos muito distantes entre si (distância na ordem de quilômetros) utilizando para isso pouca energia elétrica. Isso significa que dispositivos portáteis e/ou alimentados a bateria possam se comunicar com uma central ou outros dispositivos distantes alguns quilômetros entre si, sem comprometer drasticamente a vida útil da bateria.

Este post explicará o que é LoRa, o porquê de se usar esta tecnologia e, ainda, mostrar um exemplo de comunicação ponto-a-ponto entre dois módulos ESP32 LoRa 868/915Mhz.

Material necessário

Para fazer o projeto deste post, você precisará de:

Comunicação LoRa: o que é?

Em poucas palavras, LoRa (Long Range) consiste de uma tecnologia de radiofrequência que permite comunicações em longas distâncias (na ordem de grandeza de alguns quilômetros), utilizando para isso um baixo consumo de energia elétrica.
Em termos de frequências de operação, a tecnologia LoRa utiliza frequências sub-gigahertz (abaixo de 1GHz), em bandas dedicadas de acordo com as regiões do planeta.

Cada região do planeta ou país possui uma frequência de operação homologada para o LoRa, sendo no Brasil a frequência de 915MHz.

Importante: sempre respeite essa frequência em seus projetos e produtos. Não obedecer isso pode levar a não homologação de seu produto (logo, a proibição de sua venda) e também interferências em outros sistemas. A depender do dano causado por tais interferências a sistemas terceiros, pode haver consequências legais / jurídicas para a empresa responsável pelo projeto.

Porque utilizar a comunicação LoRa?

Com base nas suas características, LoRa é a tecnologia de rádio adequada para ser uma integradora de dispositivos à Internet. Ou seja, LoRa é uma tecnologia de rádio adequada para fazer com que dispositivos que estão em zona sem cobertura de Internet (ou que não possuam recursos de hardware para se conectar à Internet) consigam enviar e receber dados da Internet. Isso é feito da seguinte forma:

  • Os dispositivos com LoRa enviam dados a uma central que também possui conectividade LoRa, assim como conectividade à Internet. Essa central é chamada de gateway.
  • O gateway, por sua vez, envia tais dados aos serviços / plataforma IoT através da Internet. Dessa forma, os dados dos dispositivos, vitais aos sistemas IoT relacionados, chegam ao seu destino.
  • Da mesma forma, informações disponíveis na Internet que precisam ser repassadas aos dispositivos são enviadas aos mesmos pelo gateway.

Observe a figura 1, que ilustra esta aplicação do LoRa.

Comunicação LoRa ponto-a-ponto

Figura 1 – aplicação da tecnologia de radiofrequência LoRa

Em suma, com LoRa, mesmo dispositivos que não possuam conectividade à Internet podem ser partes integrantes de projetos / plataformas IoT.

Preparação para programar o Módulo ESP32 LoRa 868/915Mhz

Módulo ESP32 LoRa 868/915Mhz trata-se de um módulo muito útil e poderoso, pois reúne numa só placa um ESP32 (portanto, possui conectividade wi-fi e Bluetooth), conectividade LoRa, GPIOs e um display OLED 0.96″. Logo, trata-se de um módulo completo para projetos e protótipos de dispositivos relacionados a Internet das Coisas.

Antes de fazer efetivamente projetos utilizando o Módulo ESP32 LoRa 868/915Mhz, é preciso instalar as bibliotecas necessárias à sua programação. Infelizmente, a documentação da instalação e uso das bibliotecas deste módulo não é muito completa, logo desenvolvi um procedimento detalhado para esta preparação. Apesar do procedimento ser originalmente feito para o Módulo Heltec Wifi LoRa (V2), este se aplica aos Módulos ESP32 LoRa 868/915Mhz pois o Heltec Wifi LoRa (V2) trata-se de um clone do Módulo ESP32 LoRa 868/915Mhz.

Projeto de comunicação LoRa ponto-a-ponto

O projeto deste post consiste de dois Módulos ESP32 LoRa 868/915Mhz se comunicando ponto-a-ponto via LoRa, num fluxo de dados simples (um módulo envia e outro módulo recebe os dados).

A informação enviada é um número (iniciado em zero e incrementado a cada segundo), gerado no módulo emissor e posteriormente enviado para o módulo receptor.  Ao receber este número, o módulo receptor escreve o número recebido no display OLED 0.96″, de modo que possa ser visto em tempo real o incremento deste número, o que valida portanto a transmissão. Além disso, o módulo transmissor também escreve no display a informação de RSSI (parâmetro que indica a intensidade do sinal LoRa, medido em dBm), sendo portanto muito útil para testes de alcance máximo de transmissão.

Comunicação LoRa ponto-a-ponto: emissor

Uma vez instaladas as bibliotecas necessárias, está tudo pronto para programar os Módulos ESP32 LoRa 868/915Mhz. Primeiramente, será programado o emissor da comunicação ponto-a-ponto. Para isso, utilize o código-fonte abaixo e faça o upload do programa para um dos Módulos ESP32 LoRa 868/915Mhz.

Observações:
1) Antes de compilar e rodar, certifique-se que a placa do Heltec_Wifi_LoRa_32 esteja selecionada em Tools > Board da Arduino IDE.
2) Leia atentamente os comentários do código-fonte para maior compreensão do mesmo.

#include <LoRa.h>
#include <SPI.h>
#include <Wire.h>

/* Definicoes para comunicação com radio LoRa */
#define SCK_LORA           5
#define MISO_LORA          19
#define MOSI_LORA          27
#define RESET_PIN_LORA     14
#define SS_PIN_LORA        18

#define HIGH_GAIN_LORA     20  /* dBm */
#define BAND               915E6  /* 915MHz de frequencia */

/* Definicoes gerais */
#define DEBUG_SERIAL_BAUDRATE    115200

/* Variaveis globais */
long informacao_a_ser_enviada = 0;

/* Local prototypes */
bool init_comunicacao_lora(void);

/* Funcao: inicia comunicação com chip LoRa
 * Parametros: nenhum
 * Retorno: true: comunicacao ok
 *          false: falha na comunicacao
*/
bool init_comunicacao_lora(void)
{
    bool status_init = false;
    Serial.println("[LoRa Sender] Tentando iniciar comunicacao com o radio LoRa...");
    SPI.begin(SCK_LORA, MISO_LORA, MOSI_LORA, SS_PIN_LORA);
    LoRa.setPins(SS_PIN_LORA, RESET_PIN_LORA, LORA_DEFAULT_DIO0_PIN);
    
    if (!LoRa.begin(BAND)) 
    {
        Serial.println("[LoRa Sender] Comunicacao com o radio LoRa falhou. Nova tentativa em 1 segundo...");        
        delay(1000);
        status_init = false;
    }
    else
    {
        /* Configura o ganho do receptor LoRa para 20dBm, o maior ganho possível (visando maior alcance possível) */ 
        LoRa.setTxPower(HIGH_GAIN_LORA); 
        Serial.println("[LoRa Sender] Comunicacao com o radio LoRa ok");
        status_init = true;
    }

    return status_init;
}

/* Funcao de setup */
void setup() 
{    
    Serial.begin(DEBUG_SERIAL_BAUDRATE);
    while (!Serial);

    /* Tenta, até obter sucesso, comunicacao com o chip LoRa */
    while(init_comunicacao_lora() == false);       
}

/* Programa principal */
void loop() 
{
    /* Envia a informação */
    LoRa.beginPacket();
    LoRa.write((unsigned char *)&informacao_a_ser_enviada, sizeof(informacao_a_ser_enviada));
    LoRa.endPacket();
   
    /* Incrementa a informação para o próximo envio e aguarda 
       1 segundo até enviar a próxima informação */
    informacao_a_ser_enviada++;
    delay(1000);
    
}

Comunicação LoRa ponto-a-ponto: receptor

Agora é chegada a hora de programar o módulo receptor da comunicação ponto-a-ponto. Para isso, utilize o código-fonte abaixo e faça o upload do programa para um dos Módulos ESP32 LoRa 868/915Mhz.

Observações:
1) Antes de compilar e rodar, certifique-se que a placa do Heltec_Wifi_LoRa_32 esteja selecionada em Tools > Board da Arduino IDE.
2) Leia atentamente os comentários do código-fonte para maior compreensão do mesmo.

#include <LoRa.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

/* Definicoes para comunicação com radio LoRa */
#define SCK_LORA           5
#define MISO_LORA          19
#define MOSI_LORA          27
#define RESET_PIN_LORA     14
#define SS_PIN_LORA        18

#define HIGH_GAIN_LORA     20  /* dBm */
#define BAND               915E6  /* 915MHz de frequencia */

/* Definicoes do OLED */
#define OLED_SDA_PIN    4
#define OLED_SCL_PIN    15
#define SCREEN_WIDTH    128 
#define SCREEN_HEIGHT   64  
#define OLED_ADDR       0x3C 
#define OLED_RESET      16

/* Offset de linhas no display OLED */
#define OLED_LINE1     0
#define OLED_LINE2     10
#define OLED_LINE3     20
#define OLED_LINE4     30
#define OLED_LINE5     40
#define OLED_LINE6     50

/* Definicoes gerais */
#define DEBUG_SERIAL_BAUDRATE    115200

/* Variaveis e objetos globais */
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

/* Local prototypes */
void display_init(void);
bool init_comunicacao_lora(void);

/* Funcao: inicializa comunicacao com o display OLED
 * Parametros: nenhnum
 * Retorno: nenhnum
*/ 
void display_init(void)
{
    if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) 
    {
        Serial.println("[LoRa Receiver] Falha ao inicializar comunicacao com OLED");        
    }
    else
    {
        Serial.println("[LoRa Receiver] Comunicacao com OLED inicializada com sucesso");
    
        /* Limpa display e configura tamanho de fonte */
        display.clearDisplay();
        display.setTextSize(1);
        display.setTextColor(WHITE);
    }
}

/* Funcao: inicia comunicação com chip LoRa
 * Parametros: nenhum
 * Retorno: true: comunicacao ok
 *          false: falha na comunicacao
*/
bool init_comunicacao_lora(void)
{
    bool status_init = false;
    Serial.println("[LoRa Receiver] Tentando iniciar comunicacao com o radio LoRa...");
    SPI.begin(SCK_LORA, MISO_LORA, MOSI_LORA, SS_PIN_LORA);
    LoRa.setPins(SS_PIN_LORA, RESET_PIN_LORA, LORA_DEFAULT_DIO0_PIN);
    
    if (!LoRa.begin(BAND)) 
    {
        Serial.println("[LoRa Receiver] Comunicacao com o radio LoRa falhou. Nova tentativa em 1 segundo...");        
        delay(1000);
        status_init = false;
    }
    else
    {
        /* Configura o ganho do receptor LoRa para 20dBm, o maior ganho possível (visando maior alcance possível) */ 
        LoRa.setTxPower(HIGH_GAIN_LORA); 
        Serial.println("[LoRa Receiver] Comunicacao com o radio LoRa ok");
        status_init = true;
    }

    return status_init;
}

/* Funcao de setup */
void setup() 
{
    /* Configuracao da I²C para o display OLED */
    Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN);

    /* Display init */
    display_init();

    /* Print message telling to wait */
    display.clearDisplay();    
    display.setCursor(0, OLED_LINE1);
    display.print("Aguarde...");
    display.display();
    
    Serial.begin(DEBUG_SERIAL_BAUDRATE);
    while (!Serial);

    /* Tenta, até obter sucesso, comunicacao com o chip LoRa */
    while(init_comunicacao_lora() == false);       
}

/* Programa principal */
void loop() 
{
    char byte_recebido;
    int packet_size = 0;
    int lora_rssi = 0;
    long informacao_recebida = 0;
    char * ptInformaraoRecebida = NULL;
  
    /* Verifica se chegou alguma informação do tamanho esperado */
    packet_size = LoRa.parsePacket();
    
    if (packet_size == sizeof(informacao_recebida)) 
    {
        Serial.print("[LoRa Receiver] Há dados a serem lidos");
        
        /* Recebe os dados conforme protocolo */               
        ptInformaraoRecebida = (char *)&informacao_recebida;  
        while (LoRa.available()) 
        {
            byte_recebido = (char)LoRa.read();
            *ptInformaraoRecebida = byte_recebido;
            ptInformaraoRecebida++;
        }

        /* Escreve RSSI de recepção e informação recebida */
        lora_rssi = LoRa.packetRssi();
        display.clearDisplay();   
        display.setCursor(0, OLED_LINE1);
        display.print("RSSI: ");
        display.println(lora_rssi);
        display.setCursor(0, OLED_LINE2);
        display.print("Informacao: ");
        display.setCursor(0, OLED_LINE3);
        display.println(informacao_recebida);
        display.display();      
    }
}

Teste do projeto

Para testar o projeto, siga o procedimento abaixo:

  1. Alimente um dos módulos (emissor ou receptor) com a fonte DC chaveada 5 V / 2 A micro-USB.
  2. Utilizando o cabo micro-USB ligado no computador, alimente o outro módulo.
  3. Observe que no display do módulo receptor serão escritos o número incremental e o RSSI.

Sugestão de aplicação

Você pode aproveitar este projeto e testar o alcance máximo dos rádios LoRa de seus Módulos ESP32 LoRa 868/915Mhz.
Para isso, deixe o módulo emissor em uma localização fixa, alimentado pela fonte DC chaveada 5V/2A micro-USB e, utilizando um powerbank, alimente o módulo receptor. Feito isso, se distancie (a pé ou de carro) do módulo transmissor até que o número não seja mais recebido.

Você vai se surpreender com o alcance da comunicação.

Gostou deste post sobre como fazer uma comunicação LoRa ponto-a-ponto com Módulos ESP32 LoRa 868/915Mhz? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

2 Comentários

  1. Pedro, parabéns pelo artigo! Uma dúvida, é possível conectar 3 ou mais placas esp32 Lora, sendo que uma delas atua como um gateway?

    1. Daniel, obrigado pelos elogios!

      Sim, é possível sim. Nesse caso, considerando LoRa “puro”, você teria que implementar um protocolo / padrão de mensagens (incluindo endereçamento para cada módulo) e fazer com que um deles (o gateway) seja capaz de receber, interpretar o protocolo e enviar os dados para a nuvem da maneira que quiser.

      Já se quiser ir direto para LoRaWAN, o caminho pode ser mais simples. Você pode comprar um gateway LoRaWAN ou usar algum serviço de conectividade LoRaWAN do mercado (TTN ou American Tower, por exemplo), dai o gateway fica terceirizado e você só implementa os módulos restantes (não precisa implementar protocolos extras, loRaWAN já possui estas funcionalidades que deseja).