Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


Procurando pessoas perdidas com ESP32 e Drone

 

Queridos Alunos !

Eu assisti um vídeo que me deixou emocionado. Foi no canal do Lito Souza do Aviões e Músicas.
Então decidi tentar algo parecido usando meu Drone Phantom 4 e mais três ESP32 com rádio Lora.

Projetei um adaptador para meu drone de forma que transportasse com segurança o rádio com ESP32. Como sempre programei com Arduino IDE os ESPs e vou disponibilizar os códigos fontes aqui nesse post.

INTENÇÃO DESSA AULA


Apresentar uma técnica simples de utilização da intensidade de um sinal recebido de um rádio LoRa, para efetuar sua localização.

MATERIAIS UTILIZADOS




  • 3x DevKits Heltec WiFi LoRa 32.
  • 4x baterias de lítio 3,7V.
  • Suportes de baterias de lítio 3,7V.
  • 1x step-up.
  • 1x step-down
  • 1 Drone (opcional)

PRINCÍPIO DE FUNCIONAMENTO


    Nesta aplicação, vamos utilizar um modo intuitivo de localização simplesmente como um experimento. Existem técnicas mais precisas e mais eficientes. Mas esta requer uma quantidade pequena de recursos e pode ser aplicada em outras situações também. Para isso, vamos supor que temos um alvo a ser localizado, que chamaremos de LOST.

    Esse por sua vez, emite continuamente um sinal LoRa, com características conhecidas. Uma base para a operação de localização, que chamaremos de STATION, utilizará um receptor móvel para identificar a posição mais provável de LOST.

    Este receptor móvel será transportado , no nosso caso, por um drone, por isso vamos chama-lo DRONE. Mas seria possível realizar a mesma operação sem necessariamente um drone. Com o drone temos a possibilidade de reduzir o número de obstáculos e sua interferência.







PRINCIPIO DE FUNCIONAMENTO - MONTAGEM LOST


    Para a montagem do LOST, vamos utilizar um suporte de baterias para duas ou mais baterias de lítio. Apesar de sua tensão nominal ser de 3,7V, na prática podem atingir 4,2V. Com duas em série teremos uma tensão de 8,4V que deverá ser aplicada ao step-down. O módulo step-down ficará responsável por manter a tensão regulada em 5V. A tensão de 5V pode ser aplicada a entrada 5V do Heltec WiFi LoRa 32.


    Atenção para a versão do DevKit Heltec, atualmente é possível encontrar as versões 1.0, 2.0 e 2.1. Alguns de seu pinos não coincidem.

PRINCÍPIO DE FUNCIONAMENTO – Pinout WiFi LoRa 32

    Abaixo vemos algumas das diferenças nas versões dos devkits 1.0 e 2.x.



    Aqui, em detalhe as diferentes distribuições dos pinos para cada versão.

    As mudanças estão destacadas em quadros de mesma cor.

    Entre as versões 2.0 e 2.1 não há diferenças de pinos que interessem este experimento



PRINCIPIO DE FUNCIONAMENTO – Montagem DRONE

    Para a montagem do DRONE, vamos utilizar uma única bateria, ligada a um step-up, que elevará a tensão até os 5V necessários para a alimentação do devkit.



    Além disso, o conjunto será fixado em uma peça impressa em 3d para ser transportado.



PRINCIPIO DE FUNCIONAMENTO – Montagem STATION

    Já a STATION pode ser alimentada por um PC ou uma fonte, como as de celulares, já que ficará fixa.


PRINCÍPIO DE FUNCIONAMENTO

    A informação mais relevante obtida pelo DRONE para o processo de localização de LOST é na verdade o RSSI.

    Nosso utilizaremos para determinar o quão próximos estaremos de LOST.

    Mas para isso, devemos proceder de forma organizada para que o RSSI seja mais que uma simples informação de proximidade e nos permita inferir a posição possível de LOST.

    Vejamos a situação exposta no esquema a seguir . . .



    Não sabemos onde LOST está, então começamos escolhendo uma direção para iniciar a busca. Vamos escolher a direção NORTE-SUL inicialmente. 

    Ao mover, vamos observando o RSSI obtido pelo DRONE:

    Se o valor do RSSI diminui, estamos indo no sentido errado (estamos nos afastando).

    Se o valor do RSSI aumenta, estamos indo no sentido correto (estamos nos aproximando).

    Mantendo a direção e o sentido de aumento do RSSI, estaremos nos aproximando de LOST. Mas isso não ocorrerá indefinidamente, porque atingiremos uma distância mínima de LOST e começaremos a nos afastar. 

    A posição sobre esta reta de direção onde o RSSI é máximo, indicará o ponto em que estivemos mais próximos de LOST e é este ponto que interessa.

    Embora somente com este ponto não possamos localizar de fato LOST, ele fornecerá uma informação importante. A reta dos possíveis locais onde LOST pode estar.

    Observe na figura de exemplo:


    Acima podemos identificar um ponto na direção NORTE-SUL onde o RSSI atinge seu valor máximo .


    Isso significa que LOST deve estar em algum lugar sobre a reta indicada na figura já que a menor distância entre LOST e DRONE é uma reta entre eles.

    O passo seguinte é determinar em que ponto sobre esta reta LOST possivelmente estará.

    Para isso, trazemos DRONE de volta a STATION e repetimos o processo, mas desta vez, em uma direção perpendicular a anterior. No nosso exemplo, na direção LESTE-OESTE.


    No exemplo acima, temos um ponto sobre a direção LESTE-OESTE onde o valor de RSSI atinge um máximo. A posição provável de LOST deve ser algum ponto sobre a nova reta indicada.

    As duas retas mostram posições prováveis para LOST onde RSSI tem o maior valore e possivelmente está mais próximo de DRONE.

    Com as duas informações podemos estimar a provável posição de LOST.


    Podemos agora limitar a região de busca para as regiões mais prováveis (em verde).

Capturas
Sinais LoRa capturados com SDR.


    Abaixo vemos a captura dos sinais LoRa transmitidos por LOST, seguidos da transmissão de DRONE para STATION.


    A sequência de eventos pode ser observada com mais detalhes na figura ao lado. 

    Note que os eventos mais antigos estão mais abaixo, enquanto que os mais recentes estão mais acima.



Problemas com o processo


    É bastante claro que, o que foi exposto até aqui, é uma simplificação e deixa de lado vários fatores que podem comprometer a capacidade de localização de LOST;

    A altitude de DRONE e de LOST devem ser levadas em consideração;

  A possibilidade de obstáculos interferirem e/ou refletirem os sinais emitidos por LOST podem complicar a sua localização;

    O direcionamento relativo das antenas pode interferir no valor do RSSI obtido por DRONE.
Entre outros . . .

    Mas são problemas solucionáveis e a combinação com outras técnicas pode sim, tornar esta, uma habilidade interessante com rádios LoRa e/ou outros.

Códigos-fonte (LOST, DRONE e STATION)
LOST – Declarações e setup()

//COM15 #include <heltec.h> //Frequência #define BAND 433E6 //Contador de envios unsigned int count = 0; void setup() {   //Inicia os dispositivos   Heltec.begin(true /*Ativa o display*/, true /*Ativa lora*/, true /*Ativa informações pela serial*/, true /*Ativa PABOOST*/, BAND /*frequência*/);   //Ajusta o Spreading Factor   LoRa.setSpreadingFactor(12);   //Ajusta a largura de banda   LoRa.setSignalBandwidth(250E3);   //Inicializa o display   setupDisplay(); }

LOST – setupDisplay()

  
void setupDisplay()
{
  //Inicializa o display
  Heltec.display->init();
  //Limpa o display
  Heltec.display->clear();
  //Modifica direcionamento do texto
  Heltec.display->flipScreenVertically();
  //Alinha o texto à esquerda
  Heltec.display->setTextAlignment(TEXT_ALIGN_CENTER);
  //Altera a fonte
  Heltec.display->setFont(ArialMT_Plain_24);
  //Exibe no display
  Heltec.display->drawString(60, 0, "Display OK");
  Heltec.display->drawString(60, 30, "LOST");
  Heltec.display->display();
  delay(1000);
}
  

LOST – refreshDisplay() e sendLoRaPacket()

void refreshDisplay(String displayMessage)
{
  //Limpa o display
  Heltec.display->clear();
  //Exibe a mensagem
  Heltec.display->drawString(60, 0, "Enviados: ");
  Heltec.display->drawString(60, 30, displayMessage);
  Heltec.display->display();
}
 //Envia um pacote LoRa
void sendLoRaPacket(String str)
{
  //Inicializa o pacote
  LoRa.beginPacket();
  //Coloca a string no pacote
  LoRa.print(str);
  //Finaliza e envia o pacote
  LoRa.endPacket();
}

LOST – loop()

void loop()
{
  //Cria uma mensagem e aumenta o contador
  String message = String(count++);
  //Envia o pacote
  sendLoRaPacket(message);
  //Exibe a mensagem no display
  refreshDisplay(message);
  //Espera 1 segundo
  delay(1000);
}

DRONE
DRONE – Declarações e setup()

//COM4
#include <heltec.h>
//Frequência
#define BAND 433E6
//Simbolo de sinal de entrada
const String SINAL_ENTRADA = "  <<<"
//Contador de envios
unsigned int count = 0;
//Valor do RSSI
String RSSI_atual = "";
void setup()
{
  Heltec.begin(true /*Ativa o display*/, true /*Ativa lora*/, true /*Ativa informações pela serial*/, true /*Ativa PABOOST*/, BAND /*frequência*/);
  //Ajusta o Spreading Factor
  LoRa.setSpreadingFactor(12);
  //Ajusta a largura de banda
  LoRa.setSignalBandwidth(250E3);
  //Inicializa o display
  setupDisplay();
  //Ativa o recebimento de pacotes
  LoRa.receive();
}

DRONE – setupDisplay()

void setupDisplay()
{
  //Inicializa o display
  Heltec.display->init();
  //Limpa o display
  Heltec.display->clear();
  //Modifica direcionamento do texto
  Heltec.display->flipScreenVertically();
  //Alinha o texto à esquerda
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  //Altera a fonte
  Heltec.display->setFont(ArialMT_Plain_16);
  //Exibe no display
  Heltec.display->drawString(0, 0, "Display OK");
  Heltec.display->drawString(0, 16, "DRONE");
  Heltec.display->display();
  delay(1000);
}

DRONE – refreshDisplay() e sendLoRaPacket()

void refreshDisplay()
{
  //Limpa o display
  Heltec.display->clear();
  //Exibe a mensagem
  Heltec.display->drawString(0, 0,  "RSSI: " + RSSI_atual);
  Heltec.display->drawString(0, 16, "T. exec: " + String(millis() / 1000) + "s");
  Heltec.display->drawString(0, 32,  "Enviados: " + String(count));
  Heltec.display->display();
}
 //Envia um pacote LoRa
void sendLoRaPacket(String str)
{
  //Inicializa o pacote
  LoRa.beginPacket();
  //Coloca a string no pacote
  LoRa.print(str);
  //Finaliza e envia o pacote
  LoRa.endPacket();
  //atualiza contagem de mensagens
  count++;
}

DRONE – loop() e cbk()

void loop()
{
  int packetSize = LoRa.parsePacket(); //Obtém o tamanho do pacote
  if (packetSize) //se for diferente de 0, recebemos dados . . .
  {
    cbk(); //executa o callback de recebimento
    refreshDisplay(); //Atualiza o display com o novo RSSI
    RSSI_atual.replace(SINAL_ENTRADA, ""); //remove o simbolo de sinal de entrada
    delay(200); //aguarda um pouco
    sendLoRaPacket("d:" + RSSI_atual); //Envia o RSSI obtido para STATION
  }
  else //se nenhum dado foi recebido...
  {
    refreshDisplay();//somente atualiza o display
  }
}
void cbk()
{
  //Obtem o RSSI e inclui o sinal de entrada
  RSSI_atual = String(LoRa.packetRssi(), DEC) + SINAL_ENTRADA;
}

STATION
STATION – Declarações e setup()

//COM8
#include <heltec.h>
//Frequência
#define BAND 433E6
//Simbolo de sinal de entrada
const String SINAL_ENTRADA = "   <<<";
//Valor do RSSI enviado pelo DRONE
String mensagem = "";
//Contador de recebimentos
unsigned int count = 0;
void setup()
{
  Heltec.begin(true /*Ativa o display*/, true /*Ativa lora*/, true /*Ativa informações pela serial*/, true /*Ativa PABOOST*/, BAND /*frequência*/);
  //Ajusta o Spreading Factor
  LoRa.setSpreadingFactor(12);
  //Ajusta a largura de banda
  LoRa.setSignalBandwidth(250E3);
  //Inicializa o display
  setupDisplay();
  //Ativa o recebimento de pacotes
  LoRa.receive();
}

STATION – setupDisplay()

void setupDisplay()
{
  //Inicializa o display
  Heltec.display->init();
  //Limpa o display
  Heltec.display->clear();
  //Modifica direcionamento do texto
  Heltec.display->flipScreenVertically();
  //Alinha o texto à esquerda
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  //Altera a fonte
  Heltec.display->setFont(ArialMT_Plain_16);
  //Exibe no display
  Heltec.display->drawString(0, 0, "Display OK");
  Heltec.display->drawString(0, 16, "STATION");
  Heltec.display->display();
  delay(1000);
}

STATION – refreshDisplay()

void refreshDisplay()
{
  //Limpa o display
  Heltec.display->clear();
  //Exibe a mensagem
  Heltec.display->drawString(0, 0,  "RSSI: " + mensagem);
  Heltec.display->drawString(0, 16, "T. exec: " + String(millis() / 1000) + "s");
  Heltec.display->drawString(0, 32,  "Recebidos: " + String(count));
  Heltec.display->display();
}

STATION – cbk()

void cbk(int packetSize)
{
  mensagem = "";
  for (int i = 0; i < packetSize; i++)
  {
    mensagem += (char) LoRa.read();
  }
  //O drone está nos enviando mensagens assim: "from_drone: RSSI"
  //onde "RSSI" é o RSSI dos pacotes que ele está pegando
  if (mensagem.startsWith("d:"))
  {
    count++;
    //Remove "d:" de  "from_drone:" da string
    mensagem.replace("d:", "");
    //Remove eventuais espaços em branco nas extremidades da string
    mensagem.trim();
    //Exibe no Monitor Serial
    Serial.println(mensagem);
    //inclui o sinal de entrada
    mensagem = mensagem + SINAL_ENTRADA;
    //Exibe no display
    refreshDisplay();
  }
  else
  {
    //indica a detecção de um sinal do "LOST"
    mensagem = "LOST";
    //Exibe no display
    refreshDisplay();
  }
}

STATION – loop()

void loop()
{
  //verifica se há dados
  int packetSize = LoRa.parsePacket();
  //se há, inicia a leitura
  if (packetSize) {
    cbk(packetSize);
  }
}

DOWNLOAD DOS ARQUIVOS 





Postar um comentário

0 Comentários