Aplicações LoRaWAN® com Interfaces P2P

Criando Aplicações LoRaWAN® com Interfaces P2P Simultaneamente

Motivação

Comunicação de dados é um dos assuntos mais importantes quando falamos de aplicações em Internet das Coisas. Cada opção de interface possui suas características próprias que se traduzem em pontos fortes e fracos para cada situação de uso. Quando um produto precisa atender a requisitos em campo que são muito amplos ou contraditórios, podemos ter dificuldade ou até a impossibilidade de atender às especificações de forma satisfatória com as interfaces existentes. Combinar as interfaces é a maneira mais natural de atender às demandas complexas de campo.

Neste artigo vou discutir os aspectos relevantes e mostrar alguns caminhos possíveis para o projetista de nível intermediário poder navegar no ambiente de um stack LoRaWAN, encontrando os pontos adequados para combinar mais de um método de comunicação para o seu dispositivo IoT.

Comunicação P2P

Quando falamos em comunicação ponto a ponto (ou P2P da sigla em inglês peer to peer), estamos simplificando bastante a argumentação. Explico aqui o que tenho em mente.

Rigorosamente falando, toda comunicação acontece inicialmente entre dois pares, ou seja, é P2P na sua essência. A organização de diversos links de comunicação P2P de formas mais complexas é que gera os padrões existentes. A própria comunicação LoRaWAN® faz uso de links de rádio entre as entidades básicas Endpoint (EP) e Gateway (GW). A coleção de todas as ligações entre EPs e um único GW é o que gera a topologia de estrela típica do padrão. Ok, precisamos admitir que como o GW é considerado um concentrador, também podemos dizer que existe aqui uma diferença hierárquica entre os elementos. Porém em outros casos, quando falamos numa rede Mesh por exemplo, temos todos os indivíduos idênticos hierarquicamente comunicando-se entre si de forma organizada e compondo uma topologia que gera caminhos para os dados fluírem pela rede e chegarem até seu destino final. Bem ou mal, em toda rede acaba surgindo aqui uma organização hierárquica mesmo que temporária.

Esta separação dos elementos é um pouco arbitrária ou artificial, e talvez não seja o que de fato identifica o que é um protocolo padronizado e um P2P. Esta dificuldade de descrever os fatos não elimina a necessidade de termos métodos alternativos de comunicação.

Falando de casos práticos, um exemplo muito comum em campo é a criação de caminhos de contingência para que os elementos possam se comunicar entre si quando o fluxo principal pelo protocolo principal se encontra interrompido.
No final, adota-se de forma bastante informal a nomenclatura P2P para toda conexão que foge ao fluxo principal de comunicação pelo protocolo principal. Geralmente estes links buscam resolver questões bastante específicas e usam formatações que são proprietárias.

Questões Práticas

Toda interface de comunicação demanda em vários momentos atenção total seja do HW ou do SW para operar adequadamente. É raro um protocolo de comunicação que não tenha critérios de tempo relativamente rígidos.

No caso específico de dispositivos de baixo custo em IoT duas demandas se somam e se somam para tornar a vida do projetista mais difícil:

1) A necessidade de baixo consumo – portanto reduzir o tempo de operação ao máximo para economizar bateria é essencial. Reduzindo o tempo, a criticidade de cada operação torna-se mais relevante.

2) A pressão por um HW mais enxuto e consequentemente mais barato – é necessário portanto fazer com que um único processador trate de mais de uma tarefa crítica em tempo simultaneamente através de compartilhamento do processamento.

ALERTA: Aqui no nosso texto, vamos tratar daquele caso muito familiar ao projetista brasileiro onde o mesmo processador irá tratar de duas interfaces ao mesmo tempo e não há orçamento disponível para qualquer exagero. Ou seja, a otimização em custo aqui é tratada como essencial.

Acesso ao Código Fonte

Bem, quem precisa entrar neste nível de projeto irá precisar certamente de acesso a todos os detalhes de funcionamento do protocolo principal de comunicação. A separação das tarefas em unidades atômicas é condição básica para tais casos. Um stack (ou pilha) de comunicação que dá suporte a este tipo de acesso é geralmente organizado em uma API bastante padronizada, onde podem ser localizados facilmente os seguintes elementos:

    1. Funções básicas para inicialização e configuração do HW (Init)
    2. Funções de Transmissão de Dados (Tx) e Leitura dos Buffers de Recepção (Rx)
    3. Funções de Call Back para retornos de Interrupção
    4. Funções de Temporização e Loop de Comunicação de Dados, que são responsáveis pela execução das máquinas de estado do protocolo

Como cada momento do protocolo é organizado em processamentos separados, fica extremamente fácil de criar as conexões do sistema principal ao stack. Esta conexão pode ser feita de duas formas: a) Diretamente pela chamada das funções nos pontos de interesse, em arquiteturas baremetal (sem sistemas operacionais – OS); b) Com arquiteturas baseadas em sistemas operacionais de tempo real onde as chamadas são organizadas em tasks de forma padronizada.

Em qualquer dos dois casos, usa-se o restante do tempo de processamento não usado pelo protocolo de comunicação para que sejam realizadas as demais tarefas de comunicação de outros protocolos ou ainda tarefas relacionadas ao tratamento de sensores, atuadores ou inteligência local do equipamento.

É aqui que o planejamento de tempo é crucial. As duas interfaces de comunicação precisam ser intercaladas em tempo para que ocorra o processamento dos dois protocolos sem que qualquer dos lados seja prejudicado e cause a queda de qualquer dos links.

Combinando outras Comunicações com LoRaWAN®

O protocolo LoRaWAN® pode ser operado pelo dispositivo em 3 classes, conforme sua iniciativa e disponibilidade em tempo. A Classe A possui uma característica que facilita muito esta organização: a iniciativa da comunicação é sempre realizada pelo Endpoint e o momento do handshake é limitado a um período extremamente curto de Rx num tempo precisamente localizado após o evento de Tx. Esta altíssima disponibilidade do HW, previsibilidade e simplicidade do protocolo abre inúmeras possibilidades de combinar LoRaWAN® com outros protocolos.

Mesmo assim, cabe salientar que o outro protocolo usado precisa abrir mão do HW por algum tempo para que a comunicação LoRaWAN® aconteça. Se este requisito básico não puder ser atendido sem prejuízo grave às outras tarefas, temos uma impossibilidade de atender aos dois num mesmo processador de forma definitiva.

Aqui entra a questão de comunicação P2P como sendo uma alternativa bastante razoável. Como comunicações feitas de forma proprietária podem ser adaptadas para qualquer caso de uso, fica também muito fácil encontrar maneiras de atender a uma especificação básica de linke entre dois EPs.

Uma comunicação P2P, neste caso, é algo que fica sob responsabilidade total do projetista. Uma consulta bastante comum que recebo de clientes nestes momentos é onde encontrar um stack P2P pronto. A verdade é que existe muito pouco material livremente disponível na rede para quem procura isso. Existem alguns motivos para isso. O primeiro é que quase todos os protocolos P2P que são desenvolvidos por empresas acabam sendo mantidos como sigilosos. É o pulo do gato que garante alguma proteção dos produtos contra a cópia não autorizada. O segundo é que sendo tais protocolos predominantemente desenvolvidos para casos específicos, sua formatação não é pensada para ser universal.

Se por um lado isso representa uma dificuldade, por outro, também podemos dizer que não é tão difícil assim de criar um novo protocolo para atender a uma demanda simples. Isso vai demandar algum trabalho, mas geralmente é uma tarefa bem razoável.

Para quem não quer este trabalho ou precisa atender a outras interfaces padronizadas simultaneamente, temos diversos protocolos formais disponíveis. Para exemplificar este caso, lembramos o código das duas bibliotecas LoRaWAN® que estamos disponibilizando aqui contemplam a comunicação do EP também com um aparelho de celular pelo Bluetooth.

Prioridades entre Protocolos

Cada caso de uso vai exigir uma análise cuidadosa de qual protocolo precisará ser priorizado. Definido isso, o outro protocolo será acomodado em torno da codificação do primeiro. Estas definições normalmente seguem a regra de qual dos dois é mais crítico em tempo. Entretanto podemos ter outros motivos para priorizar um deles. No nosso exemplo com Bluetooth, o fato de existir uma aplicação pronta em torno de uma biblioteca fechada cria uma dificuldade adicional para modificar os pontos de chamada e controle do protocolo Bluetooth. Acaba que os motivos se somam aqui. Bluetooth exige uma temporização mais rígida e ao mesmo tempo seria quase impossível entrar no mérito do stack com uma biblioteca à qual não teremos acesso completo.

No caso de um protocolo proprietário P2P combinado com LoRaWAN® provavelmente a decisão seria invertida.

Outra consideração que merece destaque é sobre a utilização do próprio rádio LoRa já codificado no protocolo LoRaWAN®. Esta configuração é possível, sim. Desde que sejam tomados cuidados para que seja garantida a preservação de contexto (variáveis de estado principalmente) de cada interface bem como a completa configuração de todos os parâmetros de transmissão e recepção de pacotes de cada protocolo, não há qualquer problema em rodar dois protocolos sobre o mermo circuito de RF. No final o ambiente percebe o dispositivo como se ele tivesse de fato duas interfaces distintas, cada uma operando um protocolo próprio.

Certificação do Produto

Cada interface de um produto de comunicação por rádio frequência exige o cumprimento de regras legais. No caso do Brasil, a Anatel é quem determina o que pode e deve ser feito.

No caso de LoRaWAN® e Bluetooth, existem regras definidas e claras. Além disso, as entidades certificadoras possuem experiência de como realizar tanto o processamento da documentação quanto dos testes em laboratório. No caso de uma interface P2P proprietária, será necessário o investimento de tempo para entender as possibilidades e encontrar uma maneira autorizada de operar. Depois disso, a certificação desta interface também irá demandar um trabalho específico. Novamente, nada que não seja razoável. O importante é ter ciência do fato e reservar os tempos adequados no cronograma e o orçamento para cada caso.

O Material Básico

Feitas todas as considerações, vamos agora ao que interessa, o exemplo prático.

Existem diversos repositórios hoje disponíveis com exemplos de aplicações LoRaWAN®. O stack básico foi criado faz um certo tempo por uma empresa tradicional no mercado e foi disponibilizado pela Semtech à época da sua criação. Ao longo do tempo, diversos fabricantes de microcontroladores no mercado tomaram este material como base e desenvolveram suas versões adaptadas para diversos modelos de MCUs.

Os dois exemplos que vamos mostrar aqui operam em MCUs da Silicon Labs. Vamos deixar os links dos exemplos para uso com e sem Bluetooth. Mas como o objetivo é demonstrar a operação com interfaces simultaneamente, vamos focar no segundo caso.
Temos duas versões principais do mesmo stack hoje disponíveis para estes processadores:

1) Stack conforme adotado pela Arm e formatado conforme o ambiente mbed:

a. Com Bluetooth (para processador Blue Gecko 13):
https://github.com/udev-br/Silabs-Blue-LoRaWan-Mbed
b. Sem Bluetooth (Para processador Pearl Gecko 12):
https://github.com/udev-br/Silabs-Pearl-LoRaWan-Mbed

2) Stack conforme a herança original:

a. Com Bluetooth (para processador Blue Gecko 22):
https://github.com/udev-br/LoRaMac-Node-xG22-soc_thermometer
b. Sem Bluetooth (para Processador Pearl Gecko 22):
https://github.com/udev-br/LoRaMac-Node-PG22-DK2503A

Todos os exemplos acima foram feitos em implementação baremetal, ou seja, sem a utilização de um sistema operacional. As chamadas às funções da API do stack LoRaWAN acontecem por inclusões do código dentro do fluxo principal do exemplo, conforme veremos a seguir.

O Exemplo SoC Thermometer

Como aplicação exemplo, optamos por usar um medidor de temperatura e umidade disponível em diversos kits da Silabs.

Para maiores detalhes sobre este exemplo, deixamos aqui o link para um Application Note com todas as informações necessárias para repeti-lo da forma mostrada.

De modo geral, o fluxo de trabalho adotado foi o seguinte:

    1. Criar um projeto exemplo que implementasse uma aplicação de termômetro, conforme disponível nas ferramentas da Silabs;
    2. Incluir os arquivos e diretórios do stack LoRaWAN no mesmo projeto;
    3. Adaptar os arquivos para tornar o conjunto compilável (modificações dos includes, configurações, adaptação dos defines de configuração, dados de comissionamento LoRaWAN, etc);
    4. Incluir as chamadas de funções da API LoRaWAN nos pontos adequados.

Os Pontos de Conexão do Stack LoRaWAN® com a Aplicação Bluetooth
Além do procedimento óbvio de incluir os arquivos da pilha LoRaWAN® no código original do exemplo SoC Thermometer, existe uma tarefa que exige maior cuidado que é a própria chamada das funções principais da API que irão criar o funcionamento correto de ambos os protocolos simultaneamente.

Aqui mostramos o código do arquivo main.c onde fica a função main do código. Observe que foram removidos comentários do código original para deixar o conjunto mais legível.

Aplicações LoRaWAN com Interfaces P2P

Veja que existe um bloco de inicializações (e que precede o loop principal da função main). Outra coisa que chama a atenção é a chamada da função que faz o processamento do stack periodicamente como parte do loop principal. Apesar de ser a primeira coisa a ser feita, a organização geral da pilha Bluetooth foi preservada. Todo o tratamento de eventos é o tratamento original da pilha Bluetooth.

Logo no meio dos eventos também existe uma chamada à função que faz a medida (leitura do sensor) de temperatura. Essa função também fica localizada no arquivo main.c em outro trecho que detalhamos a seguir.

Aplicações LoRaWAN com Interfaces P2P

Em verde foi marcado o processamento da leitura do sensor, em azul o envio desta informação por Bluetooth e em vermelho, a parte que foi inserida para gerar o processamento LoRaWAN desta aplicação. Isso significa que optou-se por chamar o processamento LoRaWAN para cada leitura do sensor.

Cabe aqui uma pergunta importante: Em virtude desta decisão, o que precisamos observar com o máximo de cuidado? A resposta não é óbvia, mas essencial. Já que o protocolo LoRaWAN assume um tempo de handshake que inclui ambos os timers RX_DELAY_WINDOW1 e RX_DELAY_WINDOW2, a chamada à leitura dos sensores não pode ser mais frequente do que o maior destes timers. De fato, é necessário inclusive reservar tempo de sobra para permitir o processamento com alguma folga.

A última parte do código que vamos detalhar aqui é a chamada da construtora da classe LoRaWANClass dentro do arquivo LoRaWAN.cpp.
Veja que a definição da interface de rádio em uso acontece ali dentro, a partir da chamada do construtor de uma das classes SX126X_LoRaRadio ou SX1272_LoRaRadio. A seleção de qual construtor é chamado é feita de maneira bastante trivial com diretivas de pre compilação.

Aplicações LoRaWAN com Interfaces P2P

Existem diversos outros pontos no código onde é possível observar a integração e interação dos dois códigos, mas estes são os principais e que merecem destaque. Veja que é um trabalho relativamente simples, mas que exige um bom conhecimento de ambos os protocolos, os códigos disponíveis e principalmente um bom planejamento e debug durante os trabalhos.

Conclusão

Realizar projetos que resultem em produtos multiprotocolos é perfeitamente possível e muito útil para levar a economias significativas de custo bem como habilitar o projeto a complementar as funcionalidades de um protocolo com outro.

Apesar do exemplo simples apresentado realizar apenas o compartilhamento da mesma informação básico de temperatura e umidade, podem ser realizadas tarefas bem mais complexas, como por exemplo permitir a atualização de FW através de uma conexão local via Bluetooth utilizando-se um celular, por exemplo, enquanto que a interface LoRaWAN fica reservada para a operação diária em baixo consumo e com distâncias muito maiores de alcance.

Também discutimos aqui a possibilidade de utilização de protocolos rodando sobre a mesma interface de rádio.

Estas possibilidades elevam o valor de uma solução de IoT para o cliente final ao mesmo tempo em que dão recursos ao projetista para ampliar seu repertório ao resolver soluções de campo.

Faça download do manual complementar abaixo, que ensina como criar rapidamente uma solução com conectividade multiprotocolo Bluetooth e LoRaWAN utilizando-se placas de desenvolvimento da Silicon Labs e da Semtech interconectadas e combinadas com o recentemente lançado stack LoRaWAN.

Solução Bluetooth Comunicando com a Rede LoRaWAN

Preencha o formulário abaixo que enviaremos o manual para o seu e-mail:

IoT Labs - Colunistas do Blog - Pedro Balisteri - 1200 x 628

Como criar um rastreador LoRaWAN® com alta imunidade à jammers

Com o advento da Internet das Coisas, um segmento do mercado de eletrônicos e logística ficou ainda mais evidente: o rastreamento. Seja para acompanhar, em tempo real, onde um veículo de passeio se encontra ou para monitorar o transporte de cargas valiosas e muito visadas, o rastreamento é a solução que dá mais tranquilidade, agilidade e previsibilidade perante o trajeto para as empresas envolvidas no referido transporte.

Nesse quesito, o uso da tecnologia LoRaWAN® torna-se uma ótima opção no mercado, sobretudo dentro de áreas urbanas. Isso se deve ao fato de que, em comparação ao uso de rede celular (como é comumente feito), a LoRaWAN® é significativamente mais barata, consome menos energia e, ainda, tem uma grande vantagem de não ser afetada por jammers convencionais, uma vez que utiliza um rádio sub-GHz e de banda estreita.

Este artigo vai mostrar como desenvolver um rastreador simples, utilizando um módulo com ESP32 e GPS, utilizando conectividade LoRaWAN®.

Material necessário

Este projeto requer como hardware somente um módulo TTGO T-Beam, também conhecido no mercado como Módulo WiFi ESP32 com Suporte de Bateria, GPS e LoRa 915MHZ.

Este módulo já dispõe de toda circuitaria necessária para este projeto (e coisas além, como suporte a baterias Li-Ion 18650, por exemplo), não sendo preciso, portanto, nenhum componente adicional para a montagem do projeto deste artigo. Este módulo pode ser visto na figura 1.

Figura 1 - Módulo WiFi ESP32 com Suporte de Bateria, GPS e LoRa 915MHZ
Figura 1 – Módulo WiFi ESP32 com Suporte de Bateria, GPS e LoRa 915MHZ

O que é um rastreador?

Um rastreador é um dispositivo eletrônico capaz de:

  • Obter a localização geográfica (latitude e longitude) via sinal GPS;
  • Enviar, periodicamente, via algum canal de comunicação (Wi-Fi, LoRaWAN®, GPRS etc.), a sua localização geográfica para um servidor remoto ou plataforma IoT;
  • Em alguns casos, pode ainda obter e enviar outros dados, tais como: número de velocidade do rastreador, status de entradas e saídas, temperatura de baús refrigerados, status do botão de pânico etc.

Além disso, outros pontos importantes sobre rastreadores são:

  • A periodicidade do envio de localização para o servidor remoto está atrelada, principalmente, à tarifação das mensagens.
  • Por isso, é comum que o tempo entre os envios consecutivos de dados seja feito a cada dois minutos ou mais. Em casos extremos (cuja tarifação é muito alta ou o número máximo de mensagens / dia é baixo), esse tempo pode chegar a trinta minutos ou mais.

Overview do rastreador a ser desenvolvido

O projeto de um rastreador feito aqui utiliza conectividade LoRaWAN® (em modo ABP) para envio das localizações geográficas e data/hora (obtidas via GPS) para a nuvem. A periodicidade do envio de mensagens é de 1 hora. Como ambiente de desenvolvimento, visando maior facilidade, é usado o Arduino IDE. Para garantir um bom funcionamento e possibilidade de executar tarefas de forma paralela, o software desenvolvido para esse projeto faz uso do FreeRTOS. O ESP32 roda o FreeRTOS de forma nativa (seu SDK utiliza, por default, o FreeRTOS), facilitando o seu uso em projetos envolvendo este hardware.

Abaixo estão descritas as tarefas e suas funcionalidades no projeto:

  • task_leitura_gps: tarefa responsável por obter, de forma periódica (a cada hora), do módulo GPS as localizações geográficas e data/hora. Estes dados são armazenados numa fila, com posições (espaços) suficientes para suportar até 8 horas de rastreamento. O uso de uma fila para armazenar as posições garante que estas fiquem armazenadas de forma segura e que sejam enviadas via LoRaWAN® na exata ordem com que foram inseridas na fila. A ordem de leitura é algo muito importante se você desejar traçar a rota que o rastreador percorreu, funcionalidade bastante comum em sistemas que utilizam localização GPS.
  • task_lorawan: tarefa responsável por gerenciar a conectividade LoRaWAN® e fazer o envio da localização e data/hora para a nuvem via esta conectividade.

Dessa forma, as funcionalidades de obtenção de localização geográfica e gerenciamento de conectividade operam em paralelo, o que maximiza a performance do rastreador.

Nota do autor: o rastreador aqui desenvolvido tem teor de demonstração de uso da conectividade LoRaWAN® para rastreamento, logo não é adequado nem recomendado seu uso comercial da exata forma como é apresentado neste artigo.

Bibliotecas necessárias para o rastreador veicular com ESP32 e FreeRTOS

Conforme dito anteriormente, este projeto é desenvolvido na Arduino IDE. Desta forma, a bibliotecas utilizadas são:

1) MCCI LoRaWAN LMIC Library: Biblioteca para comunicação LoRaWAN® (stack LMIC). Este projeto faz uso da versão 2.3.2 desta biblioteca. Obtenha a versão 2.3.2 desta biblioteca no seu repositório Github oficial (https://github.com/mcci-catena/arduino-lmic) e a instale na Arduino IDE via Sketch > Include Library > Add .zip Library…

Importante: antes de compilar qualquer programa usando essa biblioteca, é preciso configurar o país e banda a ser utilizada, de forma a ser possível comunicar-se com os gateways da ATC. Para isso, deve-se deixar o arquivo lmic_project_config.h (contido dentro na pasta da biblioteca: project_config/lmic_project_config.h) com o conteúdo conforme mostrado abaixo:

// project-specific definitions
//#define CFG_eu868 1
//#define CFG_us915 1
#define CFG_au921 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS

2) TinyGPS++: Biblioteca para comunicação com módulo GPS da placa.

Obtenha esta biblioteca no seu repositório Github oficial (https://github.com/mikalhart/TinyGPSPlus) e a instale na Arduino IDE via Sketch > Include Library > Add .zip Library…

3) AXP20X: Biblioteca para comunicação chip de gerenciamento de energia do módulo, de modo a permitir liberar energia para ligar o módulo GPS da placa. Obtenha esta biblioteca no seu repositório Github oficial (https://github.com/lewisxhe/AXP202X_Library) e a instale na Arduino IDE via Sketch > Include Library > Add .zip Library…

Código-fonte do rastreador veicular com ESP32 e FreeRTOS

Antes de irmos de fato ao código-fonte do projeto, seguem algumas observações importantes:

  1. Leia atentamente os comentários contidos no código-fonte para total compreensão do mesmo.
  2. O tamanho da fila de localizações é automaticamente calculado para suportar 8 horas de localizações gravadas. Esse cálculo é feito em função do tempo entre o envio de localizações geográficas (definido em TEMPO_ENTRE_POSICOES_GPS)
  3. Para mudar o tempo entre o envio de localizações geográficas, altere o valor de TEMPO_ENTRE_POSICOES_GPS no código-fonte. Por default, este valor é de 3600 segundos (uma hora).
  4. Lembre-se que quanto menor o tempo de envio de dados via LoRaWAN®, mais posições a fila de localização terá. Ela é calculada automaticamente para sempre suportar 8 horas de aquisição de localizações. Portanto, tempos entre envios de dados muito curtos podem resultar na geração de uma fila muito grande e, consequentemente, ocupar muita memória RAM do ESP32. Dessa forma, modifique o valor de TEMPO_ENTRE_POSICOES_GPS com sabedoria.
  5. Este projeto faz uso de LoRaWAN® no modo ABP. Neste modo, o dispositivo precisará ter gravado em si as seguintes chaves: network session key e application session key. Ainda, o dispositivo terá que possuir o seu endereço na rede LoRaWAN® (device address). No código-fonte do projeto, estas informações precisam ser preenchidas nas seguintes constantes: NWKSKEY, APPSKEY e DEVADDR. Tais informações são obtidas junto ao seu distribuidor LoRaWAN®, sendo estas informações únicas por dispositivo (logo, não compartilhe com ninguém essas chaves!). Sendo assim, não se esqueça de colocar suas chaves no código, caso contrário não será possível utilizar a conectividade LoRaWAN®.

O código-fonte do projeto pode ser visto abaixo:

/* Projeto: rastreador com placa ESP32 TTGO T-Beam,
* usando conectividade LoRaWAN (ABP) e já configurado
* para usar os gateways da ATC.
* Autor: Pedro Bertoleti
*
* Bibliotecas utlizadas:
* – TinyGPS++: https://github.com/mikalhart/TinyGPSPlus
* – axp20x: https://github.com/lewisxhe/AXP202X_Library
* – MCCI LoRaWAN LMIC Library: https://github.com/mcci-catena/arduino-lmic (versão 2.3.2)
*/

#include <TinyGPS++.h>
#include <axp20x.h>
#include <lmic.h>
#include <SPI.h>
#include <hal/hal.h>
#include <esp_task_wdt.h>

/* Definição – tempo máximo sem alimentar o watchdog */
#define TEMPO_WATCHDOG_SEGUNDOS 60

/* Definições gerais */
/* o módulo GPS da placa está ligado na serial 1 do ESP32 */
#define SERIAL_GPS 1
#define BAUDRATE_SERIAL_GPS 9600
#define GPIO_RX_SERIAL_GPS 34
#define GPIO_TX_SERIAL_GPS 12
#define TEMPO_ENTRE_POSICOES_GPS 3600 //s
#define TEMPO_UM_DIA_DE_TRABALHO 28800 //s (28800s = 8h)
#define TAMANHO_FILA_POSICOES_GPS (28800/TEMPO_ENTRE_POSICOES_GPS)
#define TEMPO_LEITURA_SERIAL_GPS 1000 //ms

/* definições de temporização das tarefas */
#define TICKS_ESPERA_POSICAO_GPS ( TickType_t )1000
#define TICKS_ESPERA_ENVIO_POSICAO_GPS ( TickType_t )10000

/* Baudrate da serial usada para debug (serial monitor) */
#define BAUDRATE_SERIAL_DEBUG 115200

/* Definições – radio LoRa */
#define GANHO_LORA_DBM 20 //dBm
#define RADIO_RESET_PORT 14
#define RADIO_MOSI_PORT 27
#define RADIO_MISO_PORT 19
#define RADIO_SCLK_PORT 5
#define RADIO_NSS_PORT 18
#define RADIO_DIO_0_PORT 26
#define RADIO_DIO_1_PORT 33
#define RADIO_DIO_2_PORT 32

/* Constantes do LoraWAN */
/* – Chaves (network e application keys) */
static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //coloque aqui sua network session key (obtido no seu distribuidor LoRaWAN)
static const u1_t PROGMEM APPSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //coloque aqui sua application session key (obtido no seu distribuidor LoRaWAN)

/* – Device Address */
static const u4_t DEVADDR = 0x00000000; //coloque aqui o device address do seu dispositivo (obtido no seu distribuidor LoRaWAN)

/* Constantes do rádio LoRa: GPIOs utilizados para comunicação
com rádio SX1276 */
const lmic_pinmap lmic_pins = {
.nss = RADIO_NSS_PORT,
.rxtx = LMIC_UNUSED_PIN,
.rst = RADIO_RESET_PORT,
.dio = {RADIO_DIO_0_PORT, RADIO_DIO_1_PORT, LMIC_UNUSED_PIN}, //dio2 não é utilizado neste hardware (TTGO T-Beam)
};

/* Filas */
/* Fila para armazenar posições GPS */
QueueHandle_t xQueue_GPS;

/* Estrutura de dados de posição */
typedef struct
{
float latitude;
float longitude;
int horas;
int minutos;
int segundos;
}TPosicao_GPS;

#define TAMANHO_DADOS_LORAWAN sizeof(TPosicao_GPS)

/* Demais objetos e variáveis globais */
TinyGPSPlus gps;
HardwareSerial GPS(SERIAL_GPS);
AXP20X_Class axp;
static osjob_t sendjob;

/* Protótipos das funções das tarefas */
void task_leitura_gps( void *pvParameters );
void task_lorawan( void *pvParameters );

/* Protótipos de funções gerais */
void inicializa_lorawan(void);
bool do_send(osjob_t* j);

/*
* Implementações
*/

/* Callbacks para uso com OTAA apenas (por este projeto usar ABP, eles estão vazios) */
void os_getArtEui (u1_t* buf)
{
/* Não utilizado neste projeto */
}

void os_getDevEui (u1_t* buf)
{
/* Não utilizado neste projeto */
}

void os_getDevKey (u1_t* buf)
{
/* Não utilizado neste projeto */
}

/* Callback de evento: todo evento do LoRaAN irá chamar essa
callback, de forma que seja possível saber o status da
comunicação com o gateway LoRaWAN. */
void onEvent (ev_t ev)
{
switch(ev)
{
case EV_SCAN_TIMEOUT:
break;
case EV_BEACON_FOUND:
break;
case EV_BEACON_MISSED:
break;
case EV_BEACON_TRACKED:
break;
case EV_JOINING:
break;
case EV_JOINED:
break;
case EV_JOIN_FAILED:
break;
case EV_REJOIN_FAILED:
break;
case EV_TXCOMPLETE:
/* COntrole do semáforo serial obtido. Printa na serial as informações do evento. */
Serial.println (millis());
Serial.println(F(“EV_TXCOMPLETE (incluindo espera pelas janelas de recepção)”));

/* Verifica se ack foi recebido do gateway */
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F(“Ack recebido”));

/* Verifica se foram recebidos dados do gateway */
if (LMIC.dataLen > 0)
{
Serial.println(F(“[DOWNLINK LORAWAN] Recebidos “));
Serial.println(LMIC.dataLen);
Serial.println(F(” bytes (payload) do gateway”));

/* Como houve recepção de dados do gateway, os coloca
em um array para uso futuro. */
uint8_t dados_recebidos = LMIC.frame[LMIC.dataBeg + 0];
Serial.print(F(“Dados recebidos: “));
Serial.write(dados_recebidos);
}

break;

case EV_LOST_TSYNC:
break;
case EV_RESET:
break;
case EV_RXCOMPLETE:
break;
case EV_LINK_DEAD:
break;
case EV_LINK_ALIVE:
break;
case EV_TXSTART:
Serial.println(F(“EV_TXSTART”));
Serial.println (millis());
Serial.println(LMIC.freq);
break;
default:
break;
}
}

/* Função para envio de dados ao gateway LoRaWAN */
bool do_send(osjob_t* j, TPosicao_GPS posicao_gps)
{
bool envio_ok = false;
static uint8_t mydata[TAMANHO_DADOS_LORAWAN];

/* Monta buffer de envio de dados LoRaWAN */
memcpy(mydata, (uint8_t *)&posicao_gps, TAMANHO_DADOS_LORAWAN);

/* Verifica se já há um envio sendo feito.
Em caso positivo, o envio atual é suspenso. */
if (LMIC.opmode & OP_TXRXPEND)
{
Serial.println(F(“OP_TXRXPEND: ha um envio ja pendente, portanto o envio atual nao sera feito”));
envio_ok = false;
}
else
{
/* Aqui, o envio (sem confirmação) é feito. */
/* O pacote LoRaWAN é montado e o coloca na fila de envio. */
LMIC_setTxData2(4, mydata, sizeof(mydata), 0);
Serial.println(“Pacote LoRaWAN na fila de envio.”);
envio_ok = true;
}

return envio_ok;
}

/* Função: inicializa LoRaWAN
* Parametros: nenhum
* Retorno: nenhum
*/
void inicializa_lorawan(void)
{
int b;
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];

/* Inicializa comunicação SPI com rádio LoRa */
SPI.begin(RADIO_SCLK_PORT, RADIO_MISO_PORT, RADIO_MOSI_PORT);

/* Inicializa stack LoRaWAN */
os_init();
LMIC_reset();

/* Inicializa chaves usadas na comunicação ABP */
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x13, DEVADDR, nwkskey, appskey);

/* Faz inicializações de rádio pertinentes a região do
gateway LoRaWAN (ATC / Everynet Brasil) */
for (b=0; b<8; ++b)
LMIC_disableSubBand(b);

LMIC_enableChannel(0); // 915.2 MHz
LMIC_enableChannel(1); // 915.4 MHz
LMIC_enableChannel(2); // 915.6 MHz
LMIC_enableChannel(3); // 915.8 MHz
LMIC_enableChannel(4); // 916.0 MHz
LMIC_enableChannel(5); // 916.2 MHz
LMIC_enableChannel(6); // 916.4 MHz
LMIC_enableChannel(7); // 916.6 MHz

LMIC_setAdrMode(0);
LMIC_setLinkCheckMode(0);

/* Data rate para janela de recepção RX2 */
LMIC.dn2Dr = DR_SF12CR;

/* Configura data rate de transmissão e ganho do rádio
LoRa (dBm) na transmissão */
LMIC_setDrTxpow(DR_SF12, GANHO_LORA_DBM);
}

void setup()
{
/* Inicializa serial para debug */
Serial.begin(BAUDRATE_SERIAL_DEBUG);

/* Inicializa comunicação I²C com chip gerenciador de energia (AXP192) */
Wire.begin(21, 22);
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS))
Serial.println(“Sucesso ao inicializar comunicação com chip de energia (AXP192)”);
else
{
Serial.println(“Falha ao inicializar comunicação com chip de energia (AXP192). O ESP32 será reiniciado…”);
delay(2000);
ESP.restart();
}

/* Concifgura PMIC da placa para energiza módulos
GPS e LoRa (SX1276) */
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);

/* Inicializa serial para comunicar com GPS */
GPS.begin(BAUDRATE_SERIAL_GPS,
SERIAL_8N1,
GPIO_RX_SERIAL_GPS,
GPIO_TX_SERIAL_GPS);

/* Criação das filas */
xQueue_GPS = xQueueCreate(TAMANHO_FILA_POSICOES_GPS, sizeof(TPosicao_GPS));

if (xQueue_GPS == NULL)
{
Serial.println(“Falha ao inicializar filas. O programa nao pode prosseguir. O ESP32 sera reiniciado…”);
delay(2000);
ESP.restart();
}

/* Inicia o Task WDT */
esp_task_wdt_init(TEMPO_WATCHDOG_SEGUNDOS, true);

/* Configuração das tarefas */
xTaskCreate(
task_leitura_gps /* Funcao a qual esta implementado o que a tarefa deve fazer */
, “leitura_gps” /* Nome (para fins de debug, se necessário) */
, 4096 /* Tamanho da stack (em words) reservada para essa tarefa */
, NULL /* Parametros passados (nesse caso, não há) */
, 6 /* Prioridade */
, NULL ); /* Handle da tarefa, opcional (nesse caso, não há) */

xTaskCreate(
task_lorawan
, “lorawan”
, 8192
, NULL
, 5
, NULL );

/* O FreeRTOS está inicializado */
}

void loop()
{
/* todas as funcionalidades são feitas pelas tarefas
task_leitura_gps e task_wifi_mqtt */
}

/*
* Tarefas
*/

/* Esta task é responsável por:
* – Obter a localização (latitude e longitude) do módulo GPS
* – Enviar a localização obtida para outras tasks (usando uma fila)
*/
void task_leitura_gps( void *pvParameters )
{
TPosicao_GPS posicao_gps;
unsigned long timestamp_start = 0;
char str_horario[20] = {0};

/* Habilita o monitoramento do Task WDT nesta tarefa */
esp_task_wdt_add(NULL);

while(1)
{
/* Espera pelo tempo (definido em TEMPO_ENTRE_POSICOES_GPS) entre posições GPS */
esp_task_wdt_reset();
vTaskDelay( (TEMPO_ENTRE_POSICOES_GPS*1000) / portTICK_PERIOD_MS );

/* Faz a leitura de todos os dados do GPS (por alguns milissegundos) */
timestamp_start = millis();
do
{
while (GPS.available())
gps.encode(GPS.read());
esp_task_wdt_reset();
} while ( (millis() – timestamp_start) < TEMPO_LEITURA_SERIAL_GPS);

/* Obtem e envia posição / localização para outras tasks usando uma fila*/
posicao_gps.latitude = gps.location.lat();
posicao_gps.longitude = gps.location.lng();
posicao_gps.horas = gps.time.hour();
posicao_gps.minutos = gps.time.minute();
posicao_gps.segundos = gps.time.second();
xQueueSend(xQueue_GPS, ( void * ) &posicao_gps, TICKS_ESPERA_ENVIO_POSICAO_GPS);

Serial.println(“Localizacao GPS obtida:”);
Serial.print(“* Latitude: “);
Serial.println(posicao_gps.latitude);
Serial.print(“* Longitude: “);
Serial.println(posicao_gps.longitude);
sprintf(str_horario,”%02d:%02d:%02d”, posicao_gps.horas,
posicao_gps.minutos,
posicao_gps.segundos);
Serial.print(“Horario (GMT 0): “);
Serial.println(str_horario);
}
}

/* Esta task é responsável por:
* – Gerenciar conextividade LoRaWAN
* – Enviar, quando houver, as posições GPS da fila para a nuvem
* via LoRaWAN
*/
void task_lorawan( void *pvParameters )
{
TPosicao_GPS posicao_gps_recebida;

inicializa_lorawan();

while(1)
{
/* Se há ao menos uma posição GPS na fila para serem enviadas via LoRaWAN, faz o envio aqui */
if( xQueuePeek( xQueue_GPS, &( posicao_gps_recebida ), TICKS_ESPERA_POSICAO_GPS) == pdTRUE)
{
/* Se o envio for bem sucedido, consome de fato a posição da fila (com o xQueueReceive).
Caso contrário, a posição continua na fila para um envio posterior, uma vez que xQueuePeek
somente le um item da fila e nao o consome */
if ( do_send(&sendjob, posicao_gps_recebida) == true)
{
xQueueReceive( xQueue_GPS, &( posicao_gps_recebida ), TICKS_ESPERA_POSICAO_GPS );
}
}

/* Alimenta o watchdog e aguarda 1ms para reiniciar o ciclo */
esp_task_wdt_reset();
vTaskDelay( 1 / portTICK_PERIOD_MS );
}
}

Conclusão

Neste artigo, você aprendeu como desenvolver um rastreador simples, utilizando como forma de envio de dados à nuvem a conectividade LoRaWAN®. Este projeto pode ser facilmente expandido para o que desejar (leitura de sensores, entradas analógicas e digitais etc.), servindo, portanto, como uma base para muitos projetos de rastreador LoRaWAN® a serem desenvolvidos.

Compartilhe!

LoRaWAN

LoRaWAN e o Longo Alcance: teste prático supera 23km e 22 gateways

Muito se fala sobre redes LPWA para soluções de IoT e o grande atrativo, muitas vezes, passa pela promessa de cobertura de longo alcance, baixo consumo de bateria e preços agressivos. Mas o quanto isso é realidade?

A tecnologia LoRa, acrônimo em inglês para Long Range (Longo Alcance), vem se destacando entre redes LPWA, com mais de 100 operadoras utilizando o padrão de rede LoRaWAN®, segundo a LoRa Alliance. E os testes de campo realizados pela VAGON Eletrônica – The Electronics of Things – utilizando a Rede LoRaWAN® da American Tower mostram que o longo alcance prometido, de fato, pode ser realidade. 

Os testes foram realizados na região central da cidade de São Paulo e o dispositivo recentemente desenvolvido pela VAGON – um localizador com GPS com bateria e opção do uso de duas pilhas AA que oferece vida útil de até 8 dias em comunicação intermitente a cada 10 minutos – obteve resultados realmente impressionantes.

Transmitindo em padrão LoRaWAN® em frequência de 915Mhz, as mensagens foram entregues a Gateways da Rede ATC LoRaWAN® a mais de 23Km de distância do localizador. O resultado, que já seria impressionante pela distância, chama atenção também sobre a quantidade de Gateways que receberam a mesma mensagem: 22, no total, como mostrado pelos pins verdes na imagem.

A simplicidade da arquitetura de rede LoRaWAN® e as características físicas da tecnologia LoRa, tanto em termos da infraestrutura quanto dos dispositivos, são postas em xeque, muitas vezes, sob o argumento de que o uso do padrão ALOHA pode significar, em termos práticos, grande perda de pacotes por colisão. Entretanto, uma rede robusta e bem projetada, somada a um produto de qualidade e a análise correta do ambiente de testes podem facilmente provar que sim, LoRaWAN® é uma ótima escolha para a sua solução IoT.

Compartilhe!

bueiros inteligentes

IoT: Tecnologia LoRaWAN permite o lançamento de bueiros inteligentes e antidengue

Desenvolvida pela Net Sensors, a solução dá mais um passo para que prefeituras, empresas, concessionárias de limpeza pública e até empresas privadas interessadas em projetos sociais coloquem em prática a gestão inteligente dos bueiros de seus municípios.

De acordo com a matéria publicada no portal Terra, os cestos coletores com sensor IoT e larvicida serão capazes de gerar importantes benefícios sociais, ambientais e econômicos, possibilitando agir preventivamente na limpeza dos bueiros antes das chuvas. Além disso, a empresa lançará, nos bueiros por ela monitorados, um larvicida biológico homologado pela ANVISA, que reduzirá substancialmente a proliferação do Aedes Aegypti, uma vez que o local é um dos principais criadouros do mosquito.

A novidade traz, além dos atuais chips GPRS de telefonia móvel, conectividade por meio da tecnologia LoRa, com longe alcance (3 a 15 km), baixo consumo de bateria (até 10 anos), alta segurança, bidirecional (uplink e downlink), com padrão aberto e total mobilidade.

Os bueiros inteligentes já estão em ação em centenas de pontos nas cidades de São Paulo e Rio de Janeiro e em breve chegarão a Maricá, Niterói, Cuiabá, Brasília e Salvador, além de Miami, nos Estados Unidos, e Cascais, em Portugal.

Clique aqui para ler a matéria completa no portal Terra.

Workshop IoT Labs

Workshop IoT Labs: explorando a tecnologia LoRaWANTM

Ideal para empresas que buscam soluções que não dependem de um grande volume de informações para fazer monitoramentos, a rede ATC LoRaWANTM será tema de um workshop gratuito no dia 5 de março de 2020, em Manaus.

De acordo com site portalamazonia.com, o evento será promovido pelo INDT e o IoT Labs e será focado na apresentação prática de uma nova tecnologia de rede de rádio frequência com longo alcance e baixo consumo de bateria, presente em Manaus e em mais de 200 cidades no Brasil habilitadas pela infraestrutura de rede da empresa American Tower.

Até 2025, mais de 100 bilhões de dispositivos e objetos estarão interligados à Internet das Coisas (IoT), viabilizando a implementação de diversas soluções para cidades inteligentes.

CEO da LoRa Alliance

Brasil como referência: Rede LoRaWAN da American Tower é destaque global segundo CEO da LoRa Alliance

Donna Moore, CEO da LoRa Alliance, palestrou na The Things Conference, que aconteceu em 30 de janeiro em Amsterdã. Esse evento é a maior conferência de LoRaWAN do mundo e reúne especialistas e empresários para discutir o que há de mais atual na indústria.

De acordo com a matéria divulgada no site Enterprise IoT Insights, a palestrante indicou estratégias para tornar o mercado  LoRaWAN mais acessível a desenvolvedores, fabricantes de dispositivos e clientes corporativos. Para alcançar mais popularidade, a LoRa Alliance pretende focar em implementações de novas funcionalidades, avanços no uso do espectro e cases de sucesso.

Para exemplificar o crescimento da adesão à tecnologia LoRaWAN no mundo, Donna Moore mencionou o trabalho da American Tower do Brasil, que dobrou a cobertura da sua rede em 2019 e, atualmente, está presente em todos os estados do país, totalizando mais de 220 cidades e abrangendo mais de 100 milhões de pessoas.

Essa é uma notícia que reconhece o avanço e o protagonismo que a tecnologia LoRaWAN ganhou em 2019 no Brasil. E nada melhor do que uma boa notícia para estrearmos o nosso blog.

Leia a matéria completa no site Entreprise IoT Insights aqui.

Você pode também assistir à palestra completa: