Projetos

Radar/Sonar Ultrassônico para seus Projetos

Eletrogate 19 de maio de 2022

Introdução

Neste projeto, iremos construir um Radar (‘Radio Detection And Ranging’) ultrassônico com a Arduino e o software Processing. Iremos usar o conhecimento em programação com o sensor ultrassônico no Arduino obtido no post “Sensor Ultrassônico HC-SR04 com Arduino“.

Os primeiros sistemas de radar foram desenvolvidos para detectar e alcançar aeronaves inimigas que se aproximam usando ondas de rádio. Normalmente, os sistemas de radar usam uma ferramenta de visualização chamada indicador de posição do plano (PPI), que coloca pontos em uma configuração polar para representar objetos que ocupam espaço na faixa do detector. Neste tutorial, um sensor ultrassónico (HC-SR04) será usado no lugar de um emissor de rádio e um indicador de posição de plano será construído em Java, registrando os movimentos angulares de um servo motor. O Arduino irá registrar os dados de alcance do sensor ultrassónico ao mesmo tempo em que controla e gera a posição angular do servo motor. Isso permitirá a criação de um PPI para visualizar a posição de vários objetos ao redor do sistema de radar. Esse projeto pode ser adaptado para robôs, drones, carrosbraços robóticos.


Como Funciona?

Como já vimos, o sensor ultrassónico mede a distância dos obstáculos usando ondas ultrassónicas. Nele, o emissor emite uma onda ultrassónica e o receptor recebe a onda refletida pelo obstáculo. Com isso, o sensor mede a distância até o obstáculo calculando o tempo entre a emissão e a recepção. Ao detectar um objeto e calcular a distancia, o Arduino envia os dados para o software Processing, que irá plotar as informações no gráfico.


Montando Hardware e Software

Materiais necessários para o projeto Radar/Sonar Ultrassônico

Para desenvolver o radar, foram utilizados os seguintes componentes:

cta_cart

Esquemático

Observação: Caso o servo motor não funcione adequadamente, é necessário uma alimentação externa de 5 V para todo o circuito.

Código do Arduino

/**
 * @file Radar_ultrasonico.ino
 * @author Saulo Aislan
 * @brief Firmware responsável por movimentar o servo motor entre 15º e 165º e calcular a
 * distância entre o sensor ultrassônico e o obstáculo, em seguida enviar os dados via serial.
 * @version 0.1
 * 
 * @copyright Copyright (c) 2022
 * 
*/
 
/* Inclusão de bibliotecas */
#include <Servo.h> 

/* Prototipo da funcao */
int calcDistancia();

/* Pinos utilizados */
const int trigPin = 11;
const int echoPin = 10;
 
uint32_t tempo;
int distancia;
 
Servo servo; 

/**
 * @brief Setup
 */
void setup(void)
{
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 
  Serial.begin(9600);
  servo.attach(12);
}

/**
 * @brief Loop
 */
void loop(void)
{ 
  for(int i=15;i<=165;i++)
  {  
    servo.write(i);
    delay(30);
    distancia = calcDistancia();
    
    Serial.print(i); 
    Serial.print(","); 
    Serial.print(distancia); 
    Serial.print("."); 
  }
   
  for(int i=165;i>15;i--)
  {  
    servo.write(i);
    delay(30);
    distancia = calcDistancia();
    
    Serial.print(i);
    Serial.print(",");
    Serial.print(distancia);
    Serial.print(".");
  }
}

/**
 * @brief Emite um sinal sonoro e calcular a distancia
 * @return int distancia
 */
int calcDistancia()
{ 
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  tempo = pulseIn(echoPin, HIGH); 
  
  distancia= tempo*0.034/2;
  return distancia;
}

Código do Processing

Esse código irá ler os dados enviados pelo Arduino via serial e os plotar no gráfico, em que as barras verdes significam que não há obstáculos e as vermelhas, que há.

import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
 
Serial myPort; 
 
String angle="";
String distance="";
String data="";
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
 
void setup() {
 
  size (1366, 700);
  smooth(); // Define que todos os desenhos tenham bordas suaves
  myPort = new Serial(this, "COM5", 9600); // Habilita a porta COM8 na velocidade 9600
  myPort.bufferUntil('.'); // Buffering ate o .
}

/**
 * @brief Inicia o desenho do radar e chama as outras funções
 */
void draw() {
 
  fill(98, 245, 31); // Define a cor verde usada para desenhar o radar
 
  noStroke(); // Sem desenho na tela.
  fill(0, 4); // Define a cor preto
  rect(0, 0, width, 1010);  // Desenha um retângulo na tela
 
  fill(98, 245, 31); // Define a cor verde claro usada para desenhar o radar
 
  drawRadar(); 
  drawLine();
  drawObject();
  drawText();
}

/**
 * @brief Ler os dados vindo da serial
 */
void serialEvent (Serial myPort) { 
 
  data = myPort.readStringUntil('.'); // Ler os dados como String até o . e armazena em data
  data = data.substring(0, data.length()-1); // Quebra em substring
 
  index1 = data.indexOf(","); // Separa por ,
  angle= data.substring(0, index1); // Atribui o valor ao ângulo
  distance= data.substring(index1+1, data.length()); // Atribui o valor a distância 
 
  iAngle = int(angle); // Converte o valor em inteiro
  iDistance = int(distance); // Converte o valor em inteiro
}

/**
 * @brief Desenha o gráfico base do radar
 */
void drawRadar() {
  pushMatrix(); // Push a matriz na pilha de matrizes
  translate(683, 700); // Deslocar o radar
  noFill(); // Define sem cor
  strokeWeight(2); // Define a largura do traçado usado nas linhas
  stroke(98, 245, 31); // Define a cor verde usada para desenhar linhas
  
  // Desenha as linhas do arco
  arc(0, 0, 1300, 1300, PI, TWO_PI);
  arc(0, 0, 1000, 1000, PI, TWO_PI);
  arc(0, 0, 700, 700, PI, TWO_PI);
  arc(0, 0, 400, 400, PI, TWO_PI);
  
  // Desenha as linhas dos ângulos
  line(-700, 0, 700, 0);
  line(0, 0, -700*cos(radians(30)), -700*sin(radians(30)));
  line(0, 0, -700*cos(radians(60)), -700*sin(radians(60)));
  line(0, 0, -700*cos(radians(90)), -700*sin(radians(90)));
  line(0, 0, -700*cos(radians(120)), -700*sin(radians(120)));
  line(0, 0, -700*cos(radians(150)), -700*sin(radians(150)));
  line(-700*cos(radians(30)), 0, 700, 0);
  
  popMatrix(); // Pop a matriz na pilha de matrizes
}
 
/**
 * @brief Desenha o objeto quando detectado
 */
void drawObject() {
  pushMatrix(); // Push a matriz na pilha de matrizes
  translate(683, 700); // Deslocar o objeto
  strokeWeight(9); // Define a largura do traçado usado nas linhas
  stroke(255, 10, 10); // Define a cor vermelho usada para desenhar linhas
  pixsDistance = iDistance*22.5; 
  // Verifica se o objeto está dentro dos 40 cm, se sim desenha as linhas vermelhas
  if (iDistance<40) {
     line(pixsDistance*cos(radians(iAngle)), -pixsDistance*sin(radians(iAngle)), 700*cos(radians(iAngle)), -700*sin(radians(iAngle)));
  }
  popMatrix(); // Pop a matriz na pilha de matrizes
}

/**
 * @brief Desenha as linhas no radar
 */
void drawLine() {
  pushMatrix(); // Push a matriz na pilha de matrizes
  strokeWeight(9); // Define a largura do traçado usado nas linhas
  stroke(30, 250, 60); // Define a cor verde usada para desenhar linhas
  translate(683, 700); // Deslocar a linhas
  line(0, 0, 700*cos(radians(iAngle)), -700*sin(radians(iAngle))); // Deslocar a linhas através do arco
  popMatrix(); // Pop a matriz na pilha de matrizes
}

 /**
 * @brief Desenha os textos no radar
 */
void drawText() { 
 
  pushMatrix(); // Push a matriz na pilha de matrizes
  if (iDistance>40) {
    noObject = "Out of Range"; // Se o objeto estiver fora dos 40cm seta "Out of Range"
  } else {
    noObject = "In Range"; // Caso o contrário seta "In Range"
  }
  fill(0, 0, 0); // Define a cor preto
  noStroke(); // Sem desenho na tela.
  rect(0, 1010, width, 1080); // Desenha um retângulo na tela
  fill(98, 245, 31); // Define a cor preto
  textSize(25); // Define a tamanho do texto
  text("10cm", 800, 690);  // Imprime o texto 10cm
  text("20cm", 950, 690);  // Imprime o texto 20cm
  text("30cm", 1100, 690); // Imprime o texto 30cm
  text("40cm", 1250, 690); // Imprime o texto 40cm
  textSize(40); // Define a tamanho do texto
  text("Object: " + noObject, 240, 1050); // Impime o texto Object: ...
  text("Angle: " + iAngle +" °", 1050, 1050); // Impime o texto Angle: ...
  text("Distance: ", 1380, 1050); // Impime o texto Distance: ...
  if (iDistance<40) {
    text("        " + iDistance +" cm", 1400, 1050); // Se o objeto estiver dentro dos 40cm imprime a distância do objeto em cm
  }
  textSize(25); // Define a tamanho do texto
  fill(98, 245, 60); // Define a cor verde
  translate(390+960*cos(radians(30)), 780-960*sin(radians(30))); // Deslocar o objeto
  rotate(-radians(-60)); // Rotaciona o objeto
  text("30°", 0, 0); // Imprime 30°
  resetMatrix();  // Reseta a matriz na pilha de matrizes
  translate(490+960*cos(radians(60)), 920-960*sin(radians(60))); // Deslocar o objeto
  rotate(-radians(-30)); // Rotaciona o objeto
  text("60°", 0, 0); // Imprime 60°
  resetMatrix();  // Reseta a matriz na pilha de matrizes
  translate(630+960*cos(radians(90)), 990-960*sin(radians(90))); // Deslocar o objeto
  rotate(radians(0)); // Rotaciona o objeto
  text("90°", 0, 0); // Imprime 90°
  resetMatrix();  // Reseta a matriz na pilha de matrizes
  translate(760+960*cos(radians(120)), 1000-960*sin(radians(120))); // Deslocar o objeto
  rotate(radians(-38)); // Rotaciona o objeto
  text("120°", 0, 0); // Imprime 120°
  resetMatrix();  // Reseta a matriz na pilha de matrizes
  translate(840+900*cos(radians(150)), 920-960*sin(radians(150))); // Deslocar o objeto
  rotate(radians(-60)); // Rotaciona o objeto
  text("150°", 0, 0); // Imprime 1500°
  popMatrix(); // Pop a matriz na pilha de matrizes
}

Para plotar o gráfico do radar, é necessário utilizar o software Processing (Download), faça o download e instale.

Conectando a IDE Processing com a IDE Arduino

Agora, precisamos comunicar o Arduino com o programa no Processing:

1. Na Arduino IDE, verifique qual porta serial (no caso do Windows, “COM”) o Arduino está conectado. Para isso, com o Arduino conectado ao computador, vá em Ferramentas > Porta.

2. Na IDE do Processing, cole o código para gerar o gráfico e altere a linha abaixo para a porta serial em que o Arduino está conectado.

myPort = new Serial(this, "COM4", 9600);

3. Certifique que a tela do Monitor Serial do Arduino está fechada.

4. Na IDE do Processing, click no botão “PLAY” conforme figura abaixo, para executar o código.


Conclusão

Nesse tutorial, aprendemos mais sobre o sensor ultrassônico HC-SR04 e as ondas sonoras, como também sobre radares. Outro ponto que foi apresentado, e que pode ser explorado mais a fundo, é a integração do Arduino com outro softwares como o Processing. Esse projeto pode ser aplicado em diversos contextos, desde robótica ao monitoramento de área. Para mais materiais como esse, continue acompanhando as postagens semanais do blog e não deixe de visitar nossa loja. Lá, você encontra todos os componentes necessários para desenvolver esse e muitos outros projetos! Que a força estejam com vocês e até mais!


Sobre o Autor


Saulo Aislan

Graduando em Tecnologia em Telemática pelo IFPB – Campus de Campina Grande – PB. Tenho experiência com os microcontroladores da família Arduino, ESP8266, ESP32, STM32 e microprocessador Raspberry Pi. Tenho projetos na áreas de IoTs voltada para a indústria 4.0, agroindústria e indústria aeroespacial civil utilizando LoRa, Bluetooth, ZigBee e Wi-Fi. Atualmente estudando e desenvolvendo em FreeRTOS para sistemas em tempo real com ESP32 e LoRaWan para Smart City e compartilhando alguns projetos no blog da Eletrogate.


Eletrogate

19 de maio de 2022

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!