Manual

do

Maker

.

com

AFSmartRadio com LoRA1276

AFSmartRadio com LoRA1276

Incrível alcance

Eu devia ter filmado, mas não o fiz. Na semana passada estive na casa do ilustríssimo criador das placas da AFEletronica, de onde voltei com o módulo RF LoRA1276 na AFSmartRadio. Ele quis me mostrar o alcance, na seguinte condição:

  • A casa dele é no meio de uma quadra
  • O laboratório dele é uma edícula na parte de trás, no quintal
  • Um rádio ficou sobre a bancada
  • Saímos para a rua com o outro rádio ligado em um pack de baterias

Imagine cruzar toda a casa e sair para a calçada, então caminha rua abaixo, na transversal em relação ao rádio da bancada. Andamos quase 300 metros com o a placa batendo relé quando recebia o comando a cada 2 segundos! O rádio deve ter passado por metros de parede (considerando que rádio frequência não faz curva), por todas as casas da rua até a estrada. Depois fomos para a rua paralela, e o rádio passou por uma "muralha" da casa de esquina! Entendeu o cenário? Sem visada, com essa anteninha que você vê no rádio.

Em um teste que ele fez, disse ter atingido 1km e não pôde ir além por falta de espaço. Em uma universidade que fez testes com o rádio, disseram ter chego a 10km com essa mesma antena, colocando os rádios no topo de prédios!

Em um artigo recente falei sobre a Talk2 Whisper Node, um módulo diminuto e de baixíssimo consumo com rádio RFM69. Coloquei um video no canal DobitAoByteBrasil no Youtube. Esperava um alcance maior, cheguei a 118m mas pode ser que eu tivesse muita interferência por aqui. Então dessa vez farei um video com a AFSmartRadio e colocarei um video do teste de alcance no YouTube outra vez. Agora  no YouTube você vê a apresentação dessa board. Em breve farei uma biblioteca pra facilitar ainda mais a utilização dos recursos que ela tem, mas por enquanto vou mostrar alguma interação com ela.

Primeira vez no AFSmartRadio com LoRA1276

Essa board já vem com um sketch de teste, fazendo comunicação e batendo o relé, Então, antes de subir qualquer código, faça o teste inicial para ver que está tudo ok com a board. Assim, se algo não funcionar durante a implementação, já saberá que se trata do sketch.

Para gravá-la, utilize um FTDI diretamente no Arduino, ligando apenas o GND, TX, RX e DTR. A board deverá estar alimentada, ligando de 9V a 15V no VIN e GND, que são os primeiros 2 pinos da borda da placa. Olhando por baixo dela, você verá um silk de correspondência da barra de pinos.

Esse video abaixo é apenas para mostrar o comportamento padrão da placa quando você a liga pela primeira vez:

https://youtu.be/UHGmJD3JNuU

Nesse outro artigo fiz uma boa introdução aos recursos da placa e instalação da biblioteca RadioHead para controlar o rádio. No outro artigo eu estava com um rádio RF4463Pro, agora vou compor um sketch para utilizar com o rádio que estou utilizando atualmente, o LoRA1276, que tem esse alcance incrível que citei.

Codificando no CodeBlocks

Escrevi esse outro artigo para que tenhamos a comodidade de utilizar uma IDE muito melhor que a IDE do Arduino; claro que tem outras, mas a CodeBlocks é leve, por isso a escolhi. Mas se você tentar compilar esse código, ainda que tenha as bibliotecas instaladas no Arduino, não vai funcionar. Solução?

Incluindo bibliotecas no CodeBlocks

Mais uma vez tenho que citar; só utilizo Linux, então adoto procedimentos diferentes e em alguns casos, que podem até dar razão para algumas pessoas "torcerem o nariz".

O que acontece é que o PlatformIO adiciona apenas as libs padrão quando você cria um projeto. Para adicionar à base de bibliotecas o diretório libraries do Arduino, antes de criar o projeto, adicione o caminho das bibliotecas com o comando:

platformio lib --storage-dir /home/djames/Arduino/libraries/ install

No Windows deve ter uma certa semelhança. Mas como eu já estava com o projeto criado, acredito que não tenha surtido efeito, ainda mais que estava com ele aberto. Para resolver o problema, utilizei um link simbólico para o diretório de bibliotecas do PlatformIO:

ln -s /home/djames/Arduino/libraries/* /home/djames/.platformio/lib/

Resolve o problema? Temporariamente sim, porque quando eu instalar uma nova biblioteca pela IDE do Arduino, ela não estará disponível no diretório .platformio/lib. Se for pra fazer uma gambiarra permanente, é só remover o diretório lib de dentro do diretório oculto .platformio e ao fazer o link simbólico, utilizar a seguinte sintaxe:

rm -rf ~/.platformio/lib
ln -s /home/djames/Arduino/libraries /home/djames/.platformio/lib/

Funcionará. Para criar previamente o projeto para o Pro Mini:

cd
mkdir AFSmartRadio
cd AFSmartRadio
platformio init --ide codeblocks --board pro8MHzatmega328

 

Sketch

Agora vamos discorrer a respeito de outras surpresas que esse rádio LoRA1276 oferece, junto à biblioteca RadioHead, utilizando a classe RH_RF95.

lastRSSI()

Como citei em outro artigo, o RSSI representa a quantidade relativa de um sinal recebido. Não existe um padrão para a implementação dessa medição de sinal, mas o limite pode ser de 0 á 255, daí cada um implementa a seu bel prazer. Quanto mais alto o sinal, significa que melhor está (parece óbvio, hum?). Quando medido em valores negativos a lógica é a mesma, mas atente-se que o valor é maior quando está mais próximo a 0. Uma diferença alta entre o nível de ruído e o RSSI indicam um sinal de melhor qualidade. Mas o RSSI talvez não seja a melhor forma de medição.

lastSNR()

Um dos recursos oferecidos é a relação sinal-ruído, conhecido pelo acrônimo SNR. Trata-se de um conceito de telecomunicações, usado em diversos campos da ciência e tecnologia para medir sinais ruidosos. Quanto mais alta for a relação sinal-ruído, menor o efeito do ruído sobre a medição do sinal. Não quero (e nem posso) entrar em detalhes profundos a respeito, mas um exemplo de uso do SNR é a anulação de ruído de fundo em áudio, ou em imagens de ressonãncia magnética. Daí posso dizer que utilizar a medição do SNR invés de RSSI pode ser muito mais preciso e confiável, considerando a matemática envolvida. Sério, eu acho até um pouco assustador:

snr.webp

Bem, utilizando a RadioHead com LoRA1276 você contará com um método lastSNR(), que retorna o SNR da última mensagem recebida, conforme medida pelo rádio. Esse recurso auxilia em diversos aspectos, como por exemplo, o tanto de interferência que você pode estar recebendo em diferentes direções, conforme os obstáculos, ou uma interferência de sinal em determinado horário do dia. Com isso, depurar um problema em uma estrutura de rádio de torna mais simples, porque você tem parâmetros para saber se a origem de um problema está vindo do rádio ou de outro periférico, ou até mesmo da controladora.

frequencyError()

Essa função não é absoluta; o erro de frequência é medido baseado no oscilador do receptor local, mas erros podem vir do transmissor, do receptor ou de ambos. De qualquer modo, é mais uma ferramenta para diagnóstico.

Características da classe

Ela oferece funções básicas para enviar e receber dados sem endereçamento e datagramas não confiáveis de tamanho arbitrário até 251 octetos por pacote. Com essa classe você estará implementando a funcionalidade do rádio e, caso deseje implementar camadas de segurança, endereçamento, mesh ou outros, basta utilizar uma classe de mais alto nível. Nos exemplos da biblioteca temos disponíveis alguns sketches com criptografia.

Nos exemplos da classe tem também um sketch que implementa endereçamento, implementando uma outra camada através da classe RHReliableDatagram. Utilizando-se dos sketches de exemplo, tanto faz qual será testado primeiro, mas no caso de uma implementação própria, pode ser uma boa ideia começar com uma estrutura básica sem endereçamento pra eliminar possíveis erros, então implementar essa camada posteriormente. Já digitei um bocado, agora vou implementar um sketch simples com informações em um display OLED.

Hello World

Esse é o meu "hello world" baseado nos exemplos. Comentários considerados pertinentes se encontram no código.

Client

#include <SPI.h>
#include <RH_RF95.h>

RH_RF95 rf95;
//RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W
//RH_RF95 rf95(8, 3); // Adafruit Feather M0 with RFM95

void setup(){
  Serial.begin(9600);
  while (!Serial);
  if (!rf95.init()){
    Serial.println("init failed");
  }
//  driver.setTxPower(23, false);
//  driver.setTxPower(14, true);
}

void loop()
{
  Serial.println("Enviando ao server...");
  // Send a message to rf95_server
  uint8_t data[] = "Manual do Maker";
  rf95.send(data, sizeof(data));

  rf95.waitPacketSent();//aguarda pelo envio...

  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  //...e aguarda pela resposta
  if (rf95.waitAvailableTimeout(3000)){
    if (rf95.recv(buf, &len)){
      Serial.print("Resposta: ");
      Serial.println((char*)buf);
//      Serial.print("RSSI: ");
//      Serial.println(rf95.lastRssi(), DEC);
    }
    else{
      Serial.println("Falha na recepção :-(");
    }
  }
  else{
    Serial.println("O server está rodando?");
  }
  delay(400);
}



E o server:

Server

#include <SPI.h>
#include <RH_RF95.h>

// Singleton instance of the radio driver
RH_RF95 rf95;
//RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W

long int interval  = 0;
long int last_time = 0;

void setup()
{
    Serial.begin(9600);
    while (!Serial);

    Serial.begin(9600);
    while (!Serial) ; // Wait for serial port to be available
    if (!rf95.init()){
        Serial.println("init failed");
    }

    last_time = millis();

//  driver.setTxPower(23, false);
//  driver.setTxPower(14, true);
}

void loop(){
    if (rf95.available()){
        uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
        uint8_t len = sizeof(buf);
        if (rf95.recv(buf, &len)){
            //      RH_RF95::printBuffer("request: ", buf, len);
            Serial.print("Mensagem recebida: ");
            Serial.println((char*)buf);

            Serial.print("SNR: ");
            Serial.println(rf95.lastSNR(), DEC);

            interval  = millis()-last_time;
            last_time = millis();

            char timeToDisplay[6];
            String val = String(interval);
            val        = val + "ms";
            val.toCharArray(timeToDisplay,6);
            Serial.println(timeToDisplay);


            Serial.print("RSSI: ");
            Serial.println(rf95.lastRssi(), DEC);

            //Respondendo
            uint8_t data[] = "www.manualdomaker.com";
            rf95.send(data, sizeof(data));
            rf95.waitPacketSent();
            Serial.println("Resposta enviada");
        }
        else{
            Serial.println("Falhou :-(");
            Serial.println("Falhou :-(");
        }
    }
}




Agora vou fazer o mesmo que com o Talk2, essa semana saio para a rua para gravar um video do alcance. Se você não viu o video do Talk2, dê uma passada no canal DobitAoByteBrasil, aproveite para se inscrever e deixar seu like!

A AFSmartRadio

Essa apaixonante board está à venda nesse link do site da AFEletrônica. Passei por lá semana passada e está tendo uma boa receptividade essa board; e não é pra menos.

Agora vou escrever uma biblioteca pra ela, pra deixar as coisas mais simples ainda!

O rádio

Se desejar apenas o módulo, agora temos um representante oficial no Brasil, que é a CurtoCircuito. Só clicar e conferir.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.