SONAR

SONAR com Arduino



Este projeto trata-se de um monitoramento de detecção de obstáculos com ondas ultrassônicas que lembra muito um radar como aqueles vistos nos filmes. Tudo que precisaremos é  de um Sensor Ultrassônico HC-SR04 para a detecção dos objetos, de um Servo Motor e de um suporte para girar o sensor. 
Monte o circuito com os componentes conforme o esquema abaixo, observando que o suporte com o servo que faz girar o sensor ultrassônico, fica a critério de cada um fazer a fixação.


SONAR com Arduino

Após a montagem dos componentes, carregue as bibliotecas NewPingServo e insira o seguinte código no Arduino:


 1  #include <NewPing.h>
 2  #include <Servo.h>
 3 
 4  #define pinTrig  9   // Trigger
 5  #define pinEcho 10   // Echo
 6  #define distMax 200 // Máxima distância de ping(cm)
 7  #define pinServo 11 // Pino do servo
 8 
 9  int anguloInicio = 90;
10  int anguloPasso = 1;
11 
12  int anguloRotacao = 0;
13 
14  int dir = 1; // Direção inicial, quando -1 inverte
15 
16  Servo myservo;
17  NewPing sonar(pinTrig, pinEcho, distMax);
18 
19  unsigned long changeTime;
20 
21  void setup()
22  {
23      Serial.begin(9600);
24      myservo.attach(pinServo);
25  }
26 
27  void loop()
28  {
29      myservo.write(anguloRotacao + anguloInicio);
30 
31      enviarDistancia(anguloRotacao);
32 
33      if (anguloRotacao >= anguloInicio || anguloRotacao <= -anguloInicio) // Inverte a direção
34      {
35          dir = -dir;
36      }
37 
38      anguloRotacao += (dir * anguloPasso);
39 
40      delay(30);
41  }
42 
43  int enviarDistancia(int anguloRotacao)
44  {
45      int cm = sonar.ping_cm();
46      Serial.print(-anguloRotacao, DEC); // Esse sinal é somente para coincidir com o sentido do feixe no Processing.
47      Serial.print("#");
48      Serial.println(cm, DEC);
49 
50  }

Dando prosseguimento ao projeto, caso ainda não conheça o Processing, consulte nosso  outro artigo o qual faz uma apresentação mais detalhada. E se já conhece, então abra o Processing e copie o o seguinte código:


  1  import processing.serial.*;
  2 
  3  int compTela = 1200;
  4  int limiteAngulo = 90;
  5  int guardar = 10;
  6  int guardarPontos = 800;
  7  int intervaloMaximo = 50;
  8 
  9  int angulo;
 10  int distancia;
 11 
 12  int angRadiano;
 13  float x, y;
 14  float AngEsquerdoRad, AngDireitoRad;
 15 
 16  float[] guardarX, guardarY;
 17  Ponto[] pontos;
 18 
 19  int centroX, centroY;
 20 
 21  String dadoPortaString;
 22  Serial minhaPorta;
 23 
 24  void setup()
 25  {
 26 
 27      size(1200, 600, P2D);
 28      noStroke();
 29 
 30  // rectMode(CENTER);
 31 
 32      angRadiano = (compTela / 2)+30;
 33      centroX = (width / 2)+30;
 34      centroY = height+30;
 35      angulo = 0;
 36      AngEsquerdoRad = radians(-limiteAngulo) - HALF_PI;
 37      AngDireitoRad  = radians(limiteAngulo) - HALF_PI;
 38 
 39      guardarX = new float[guardar];
 40      guardarY = new float[guardar];
 41      pontos   = new Ponto[guardarPontos];
 42 
 43      minhaPorta = new Serial(this, "COM4", 9600);
 44      minhaPorta.bufferUntil('\n'); // Receber até a nova linha
 45  }
 46 
 47 
 48  void draw()
 49  {
 50      background(#000000); // Cor preta
 51      drawRadar();
 52      drawPlotarObjetos(angulo, distancia);
 53      drawLinhaRadar(angulo);
 54 
 55      /* Desenhar as linhas de grade no radar a cada 30 graus e escreva seus valores */
 56      for (int i = 0; i <= 6; i++)
 57      {
 58          strokeWeight(1); // Espessura
 59          stroke(#ffffff); // Cor branca
 60          line(angRadiano, angRadiano, angRadiano + cos(radians(180+(30*i)))*(compTela/2), angRadiano + sin(radians(180+(30*i)))*(compTela/2));
 61          fill(#ffffff); // Cor branca
 62          noStroke();
 63          text(Integer.toString(0+(30*i)), angRadiano + cos(radians(180+(30*i)))*(compTela/2+30), angRadiano + sin(radians(180+(30*i)))*(compTela/2+30), 25, 50);
 64      }
 65 
 66      /* Escrever informações. */
 67 
 68      //noStroke();
 69      //fill(0);
 70      int Angulo=0;
 71      Angulo = angulo+90;
 72 
 73      fill(#ffea00);
 74      text("Ângulo: "+Integer.toString(Angulo), 94, 100, 100, 50);   text("graus", 170, 100, 100, 50);  // Use Integet.toString para converter dados numéricos em string
 75      text("Distância: "+Integer.toString(distancia-intervaloMaximo), 80, 120, 100, 50);  text("mm", 175, 120, 100, 50); // text(string, x, y, largura, altura)
 76 
 77      text("0",      620, 600, 300, 50);
 78      text("100 mm", 613, 490, 250, 50);
 79 
 80      text("200 mm", 613, 370, 250, 50);
 81 
 82      text("300 mm", 613, 250, 250, 50);
 83 
 84      text("400 mm", 613, 130, 250, 50);
 85 
 86      text("500 mm", 613, 015, 250, 50);
 87 
 88  }
 89 
 90  void drawLinhaRadar(int angulo)
 91  {
 92      float radiano = radians(angulo);
 93      x = angRadiano * sin(radiano);
 94      y = angRadiano * cos(radiano);
 95 
 96      float px = centroX + x;
 97      float py = centroY - y;
 98 
 99      guardarX[0] = px;
100      guardarY[0] = py;
101 
102      fill(#f9f75f, 40);
103 
104      arc(centroX,centroY,compTela, compTela,radians(angulo-100)+0.098,radians(angulo-90)+0.098);
105 
106      shiftGuardarArray();
107  }
108 
109  void drawPlotarObjetos(int angle, int distancia)
110  {
111      if ((distancia > 0) && (distancia < 500))
112      {
113          float radiano = radians(angle);
114          x = distancia * sin(radiano);
115          y = distancia * cos(radiano);
116 
117          int px = (int)(centroX + x);
118          int py = (int)(centroY - y);
119 
120          pontos[0] = new Ponto(px, py);
121      }
122      else
123      {
124          pontos[0] = new Ponto(0, 0);
125      }
126      for (int i = 0; i < guardarPontos; i++)
127      {
128          Ponto ponto = pontos[i];
129 
130          if (ponto != null)
131          {
132 
133              int x = ponto.x;
134              int y = ponto.y;
135 
136              if (x==0 && y==0) continue;
137 
138              // map(value, start1, stop1, start2, stop2)
139              // value  ---> float --> o valor recebido a ser convertido
140              // start1 ---> float --> limite inferior
141              // Stop1  ---> float --> limite superior
142              // Start2 ---> float --> limite inferior do alvo
143              // Stop2  ---> float --> limite superior do alvo
144 
145              int colorAlfa = (int)map(i, 0, guardarPontos, 20, 0);
146              int size = (int)map(i, 0, guardarPontos, 40, 0);
147 
148              fill(#c60202, colorAlfa);
149              noStroke();
150              ellipse(x, y, size, size);
151          }
152 
153      }
154 
155      shiftPontosArray();
156 
157  }
158 
159  void drawRadar()
160  {
161      stroke(#ffffff);
162      noFill();
163      // Cria círculos a cada 50mm)
164      for (int i = 0; i <= (compTela / 120); i++)
165      {
166          arc(centroX, centroY, 120 * i, 120 * i, AngEsquerdoRad, AngDireitoRad);
167      }
168  }
169 
170  void shiftGuardarArray()
171  {
172      for (int i = guardar; i > 1; i--)
173      {
174 
175          guardarX[i-1] = guardarX[i-2];
176          guardarY[i-1] = guardarY[i-2];
177      }
178  }
179 
180  void shiftPontosArray()
181  {
182      for (int i = guardarPontos; i > 1; i--)
183      {
184          Ponto pontoAnterior = pontos[i-2];
185          if (pontoAnterior != null)
186          {
187 
188              Ponto ponto = new Ponto(pontoAnterior.x, pontoAnterior.y);
189              pontos[i-1] = ponto;
190          }
191      }
192  }
193 
194  void serialEvent(Serial minhaPorta)
195  {
196      dadoPortaString = minhaPorta.readStringUntil('\n');
197      if (dadoPortaString != null)
198      {
199          dadoPortaString=trim(dadoPortaString);
200          String[] values = split(dadoPortaString, '#');
201 
202          try
203          {
204              angulo = Integer.parseInt(values[0]);
205              distancia = int(map(Integer.parseInt(values[1]), 1, intervaloMaximo, 1, angRadiano));
206          }
207          catch (Exception e) {}
208      }
209  }
210 
211  class Ponto
212  {
213      int x, y;
214 
215      Ponto(int xPos, int yPos)
216      {
217          x = xPos;
218          y = yPos;
219      }
220 
221      int getX()
222      {
223          return x;
224      }
225 
226      int getY()
227      {
228          return y;
229      }
230  }

Feito isso, aperte o botão executar e logo aparecerá uma tela escura com grade e um feixe setorial de 10 graus girando de um lado a outro indicando a varredura do sensor com os alvos na cor vermelha e indicação de marcação relativa e distância em milímetros.
É incrível como um simples projeto ficou muito mais interessante com o uso dessa fabulosa ferramenta que é o Processing podendo ser utilizado em muitos outros pequenos projetos deixando-os com mais requinte.

Nenhum comentário:

Postar um comentário