IoT DevKit - 9. Recebimento de Dados por LoRaWAN




Introdução

No tutorial anterior aprendemos como nos conectar na rede e como enviar dados para a plataforma PROIoT. Entretanto, assim como diversos dispositivos de IoT, o LoRaWAN Bee é capaz de receber dados vindos da plataforma.

Neste tutorial iremos aprender como receber uma mensagem da plataforma e como utilizá-la para controlar o estado do LED do DevKit.

Lista de Materiais

Configuração da Plataforma

Para este tutorial vamos aproveitar toda a configuração que já fizemos anteriormente na plataforma. A única coisa que vamos ter que adicionar ao nosso projeto é um "Widget" ao painel. Para isso, acesse o seu painel, clique sobre o botão "+ Widget", e então selecione a opção "Requisição", como na imagem a seguir.

widget-requisicao
"Widget" Requisição

Após selecionar esta opção, será exibida uma janela de configuração do Widget, como na imagem abaixo.

configuracao-widget
Configuração do "Widget"

Com esta janela aberta, selecione corretamente a sua "Organização" e a sua "Aplicação" no campo lateral "Variáveis de Dispositivos". Em seguida dê um nome para o "Widget" no campo "Nome do Widget" e crie uma descrição para ele. Feito isso, altere a seleção do campo "Tipo de Requisição" de "HTTP", pré configurada pela plataforma, para "Downlink". Assim será exibido ao lado o "Device EUI" do seu dispositivo e a porta que será usada para enviar a mensagem. Mantenha a porta com a configuração "100", que é pré selecionada pela plataforma. Por fim, digite no campo "Payload" a mensagem "MA==" para que o seu dispositivo fique configurado como na próxima imagem.

widget-configurado
"Widget" Configurado

Feito isso, altere a cor do botão, se desejar, e pressione o botão de confirmação verde.

Você deve estar se perguntando por que a mensagem que será enviada é "MA==". O que isso significa? A plataforma requer que as mensagens sejam enviadas com codificação Base64, portanto precisamos converter os dados que queremos enviar antes de inseri-los no campo. Existem algumas ferramentas online, como esta, que nos ajudam a obter o código em Base64 da mensagem que enviaremos. Neste caso usaremos o caractere "0", que é equivalente a "MA==" em Base64.

Após a confirmação, o "Widget" é adicionado ao painel, logo abaixo do "Widget" criado no tutorial anterior, como na imagem a seguir.

widget-criado
"Widget" Criado

Vale lembrar que, além de alterar o tamanho do "Widget", também é possível movê-lo no painel, se desejar. Para isso, basta clicar na parte superior do "Widget", logo ao lado do seu nome, e então movê-lo enquanto o botão está pressionado.

Atenção: cada requisição enviada pela plataforma consome um "Downlink" do seu plano.

Código

Com a plataforma corretamente configurada, carregue o código a seguir para a sua placa. Lembre-se de alterar os valores "Application EUI" (APPEUI), "Application Key" (APPKEY) e "Alias" (ALIAS) de acordo com os valores configurados na plataforma.

Entendendo o Código

O código acima é basicamente igual ao que utilizamos para enviar mensagens no tutorial anterior, porém, nas declarações globais do código, nós declaramos as variáveis PINO_LED e estado, que são responsáveis por armazenar o pino em que o LED do IoT DevKit está conectado e o estado de acionamento do LED (alto - HIGH - ou baixo - LOW). Inicialmente a variável de estado é mantida como nível baixo, pois ela ainda não recebeu a mensagem configurada pela plataforma.

Na configuração do código, apenas declaramos o pino do LED como uma saída da placa através do comando pinMode(PINO_LED, OUTPUT).

A grande mudança deste código para o anterior é justamente na função event_handler, que além de verificar se o módulo se conectou à rede, também é responsável por verificar as mensagens recebidas. Nela, utilizamos a condição else if(type == Event::RECEIVED_X) para verificar se o módulo recebeu uma mensagem hexadecimal. Então, se uma mensagem foi recebida, nós criamos as variáveis porta, que irá armazenar a porta da rede em que a mensagem foi enviada, e leitura_buffer, que será usada para armazenar cada caractere da mensagem recebida, juntamente com a criação do objeto buffer, que possibilita o gerenciamento da mensagem recebida. Em seguida, nós armazenamos a mensagem no objeto buffer, juntamente com a porta da mensagem na variável porta, através do comando resposta = lorawan.readX(porta, buffer). Depois verificamos se a resposta do módulo (salva na variável resposta) é igual a "<OK>", por meio da condição if(resposta == CommandResponse::OK).

Caso esta condição seja verdadeira, ou seja, caso o módulo retorne um "<OK>", nós atribuímos cada caractere da mensagem recebida à variável leitura_buffer utilizando o comando leitura_buffer = buffer[i], que é repetido enquanto a variável i for menor que o tamanho total da mensagem recebida (for(uint8_t i=0 ; i < buffer.available() ; i++)). Ainda nesse laço, aproveitamos para imprimir cada caractere no monitor serial. Após a última iteração, temos o último caractere armazenado na variável leitura_buffer. Com isso, nós verificamos se ele é igual a "0" com a condição if(leitura_buffer == '0'). Se essa condição for verdadeira, invertemos a lógica da variável estado utilizando o comando estado = !estado e atualizamos o estado físico do LED. Ou seja, se ele estava apagado antes, agora ele estará aceso, e vice-versa.

Como a última passagem do código é complexa e pode gerar dúvidas, vamos ver um exemplo com uma mensagem mais simples, sendo ela "OLA". Quando esta mensagem é recebida pelo módulo, os seus caracteres são contabilizados ("OLA" possui 3 caracteres) e então são salvos um de cada vez na variável leitura_buffer. Em outras palavras, a variável leitura_buffer recebe 3 caracteres em sequência, sendo eles "O", "L" e "A", que são respectivamente impressos no monitor serial, formando a mensagem completa "OLA". Entretanto, somente o último caractere da mensagem ("A" no nosso exemplo) é verificado (condição if apresentada acima), pois ele fica salvo na variável após o laço de impressão de caracteres (função for no código).

O Que Deve Acontecer

Após carregar o código para a placa, aguarde até que o módulo se conecte à rede, e então pressione o botão do "Widget" criado anteriormente. Isso fará com que a mensagem seja agendada para envio, exibindo a mensagem da imagem a seguir.

mensagem-agendada
Mensagem Agendada

Feito isso, o módulo irá enviar para a plataforma novamente os valores de luminosidade ambiente, como no tutorial anterior, porém, após o envio da mensagem, ele irá receber a mensagem agendada na plataforma, como na próxima imagem.

resposta-obtida-monitor-serial
Resposta Obtida no Monitor Serial

O projeto funcionou corretamente, mas imaginamos que você está com algumas dúvidas. A primeira delas deve ser por que a mensagem só é recebida após o envio de uma mensagem. O módulo LoRaWAN Bee que estamos usando no DevKit está configurado com a classe de dispositivos "A", e você deve se lembrar dos conceitos apresentados no tutorial introdutório deste protocolo que, na classe "A", o dispositivo possui duas janelas de recepção de informações do servidor e elas só são abertas após o envio de uma mensagem.

Outra pergunta que você deve estar se fazendo é em relação à mensagem recebida: "se "MA==" em Base64 é equivalente a "0", por que recebemos a mensagem "30"?" A mensagem é recebida pelo módulo no formato hexadecimal, após a conversão através da tabela ASCII de sinais gráficos imprimíveis. Levando isso em conta, e procurando na tabela ASCII pelo caractere "0", temos que o seu valor hexadecimal é equivalente a "30", o valor que recebemos pelo módulo. Inclusive os caracteres de "0" a "9" são sequenciados na tabela ASCII de "30" a "39", como na imagem a seguir, portanto é simples replicar este projeto para ter mais botões e condições (por exemplo if(leitura_buffer == '1') se a plataforma for configurada para enviar a mensagem equivalente a "1").

tabela-ascii
Tabela ASCII
Fonte: ASC Ohio State

Juntamente com a resposta do monitor serial, é possível observar que o LED do DevKit acendeu, como na próxima imagem.

resultado-final
Resultado Final

Se após acender o LED você desejar apagá-lo, basta agendar novamente o envio da mensagem. Esta requisição da plataforma funciona basicamente como um botão virtual.

Conclusão

Neste tutorial vimos mais uma das funcionalidades do IoT DevKit, aprendendo a receber mensagens da PROIoT pelo módulo LoRaWAN Bee. Agora vamos avançar em nossos estudos e criar uma estação de monitoramento com todos os sensores do kit.

Solução de Problemas

Se mesmo seguindo as soluções propostas abaixo você não conseguir solucionar o seu problema, encaminhe um e-mail para suporte@robocore.net para que possamos te ajudar da melhor maneira possível.

Arduino IDE Retornou a Mensagem "#error Use this example with the ESP32"

Como vimos anteriormente, esta é uma mensagem personalizada que criamos no início do código para quando o modelo de placa selecionado não está corretamente configurado, portanto certifique-se que o modelo da placa nas "Ferramentas" da IDE está como "ESP32 Dev Module".

Mensagem foi Agendada pela Plataforma, mas Não foi Recebida pelo Módulo

Se a sua mensagem foi agendada pela plataforma, mas não foi recebida pelo módulo, verifique se as mensagens enviadas pelo módulo foram recebidas pela plataforma, pois lembre-se que a mensagem da plataforma só é enviada quando uma mensagem do módulo é recebida na plataforma. Além disso, certifique-se que os "Uplinks" e "Downlinks" estão ativados nas configurações do seu dispositivo, como na imagem a seguir.

uplink-downlink-ativados
"Uplinks" e "Downlinks" Ativados
Avatar