Realizar un radar con Arduino y Processing
| Actualizado:
Comentarios: 0

En este artículo explicaremos cómo montar un radar con Arduino y utilizaremos el programa processing para representar en la pantalla los datos. Un radar se basa en emitir un impulso de radio que se refleja en un objeto.
A partir de este «eco» se puede extraer gran cantidad de información como, por ejemplo, la distancia en la que se encuentra el objeto. Para este tutorial utilizaremos el sensor de ultrasonidos HC-SR05, aunque se puede utilizar perfectamente el HC-SR04, se diferencian en que el primero tiene 5 pines mientras que el módulo HC-SR04 posee 4 pines, el modo de funcionamiento es idéntico. Si no sabes cómo funciona puedes verlo en este enlace que te dejamos: funcionamiento del módulo HC-SR04 con Arduino.
Antes de comenzar con esta práctica, deberiais leer el artículo Arduino y Processing Comunicación básica por puerto serie.
Material necesario:
- Placa Arduino o compatible
- Sensor ultrasónico HC-SR05
- Soporte para el sensor ultrasónico.
- Micro servo SG90
- Protoboard
- Cables Dupont
Esquema de montaje con Arduino:
- Sensor ultrasónico: GND a tierra, trigr al pin 10 del arduino, echo al pin 11 de Arduino.
- Servo: el color marrón representa el cable de tierra, el rojo es el de alimentación y el naranja es el de señal, va conectado al pin 12 del arduino.

Código completo para Arduino:
#include "Servo.h"
const int trigPin = 10;
const int echoPin = 11;
long duracion;
int distanciaCM;
Servo radarServo;
void setup(){
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
radarServo.attach(12);
}
void loop(){
for(int i=0;i<=180;i++){
radarServo.write(i);
delay(50);
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duracion = pulseIn(echoPin, HIGH);
distanciaCM = duracion*0.034/2;
Serial.print(i);
Serial.print("*");
Serial.print(distanciaCM);
Serial.print("#");
}
for(int i=180;i>=0;i--){
radarServo.write(i);
delay(50);
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duracion = pulseIn(echoPin, HIGH);
distanciaCM = duracion*0.034/2;
Serial.print(i);
Serial.print("*");
Serial.print(distanciaCM);
Serial.print("#");
}
}
En el código anterior, lo primero que hacemos es incluir la librería servo y creamos dos constantes con los pines 10 y 11. El 10 recibe la señal del pin Trig del HC-SR05 y el 11 el pin con la señal Echo.
Lo siguente ahora es crear una variable que nos guarde la duración del pulso, es decir, el tiempo que tarda en volver la onda, y en la línea 7 tenemos la variable que nos guardará la distancia a la que esta el objeto.
En la función setup() indicamos el pin Trig como salida, el pin Echo como entrada, inicializamos el puerto serial y definimos a qué pin esta conectado el servo, en nuestro caso al 12.
Dentro de la función loop() tenemos 2 if que realmente hacen lo mismo, pero el primero nos hace un barrido de 0 a 180 grados, y el segundo de 180 a 0 grados. Dentro del if, primero movemos el servo un grado y seguidamente vamos a comprobar si tenemos un objeto delante:
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duracion = pulseIn(echoPin, HIGH);
distanciaCM = duracion*0.034/2;
En la línea 1 se comienza con un pulso LOW, durante 4 microsegundos, para generar un pulso limpio; seguidamente generamos un pulso HIGH durante 10 microsegundos, para activar el sensor, y procedemos a medir la duración entre pulsos que guardamos en la variable duracion.
Lo último, es medir la distancia en cm, conocemos la velocidad del sonido que es de 343 m/s y tenemos en cuenta que la onda ha ido hasta el objeto y a vuelto.
Lo siguente es mostrar los datos por el monitor serial:

El primer dato es el ángulo, separado por el simbolo * y el segundo es la distancia separado por el símbolo, #. Tened en cuenta esto, para luego en processing recolectar los datos.
Código para processing:
Primero vamos a intentar que nos pinte las rayas verdes del barrido del radar:
import processing.serial.*;
Serial puerto;
String serialAngulo;
String serialDistancia;
String serialDatos;
float objetoDistancia;
int radarAngulo, radarDistancia;
int index=0;
void setup(){
size (1280, 720);
String puertoUtilizado = "COM5";
puerto = new Serial(this, puertoUtilizado, 9600);
puerto.bufferUntil('#');
}
void draw(){
noStroke();
// Líneas del radar
pushMatrix();
strokeWeight(5);
stroke(10,255,10); // color verde
translate(640,666);
line(0,0,640*cos(radians(radarAngulo)),-640*sin(radians(radarAngulo)));
popMatrix();
}
void serialEvent (Serial puerto){
serialDatos = puerto.readStringUntil('#');
serialDatos = serialDatos.substring(0,serialDatos.length()-1);
index = serialDatos.indexOf("*");
serialAngulo= serialDatos.substring(0, index);
serialDistancia= serialDatos.substring(index+1, serialDatos.length());
radarAngulo = int(serialAngulo);
radarDistancia = int(serialDistancia);
}
En la línea 1 importamos la librería necesaria para la comunicación serial, seguidamente creamos las varibles que necesitamos para guardar los datos recibidos por Arduino.
En la funcion setup() indicamos el tamaño de nuestra ventana con la orden size(), comenzamos la comunicación indicando el puerto que estamos utilizando, en este caso COM5. En la línea 17, almacenamos en el buffer hasta el simbolo #, recordad que en el código de Arduino mandábamos primero el ángulo, seprado por un *, segundo la distancia y poníamos un símbolo # antes de comenzar a mandar los nuevos datos.
Para obtener los datos utilizamos la función serialEvent(), veréis que en la línea 33 del código indicamos que lea hasta el símbolo #, tenemos dos datos, el ángulo y la distancia, por lo que tenemos que separar por el símbolo *, extraemos ambos datos y guardamos en las variable radarAngulo y radarDistancia.
En la función draw(), es donde procedemos a dibujar las líneas, es el código comprendido entre las líneas 23 y 29.
Si probamos, comprobaremos que dibujamos la linea correspondiente a cada pulso:

El siguiente paso es dibujar la línea de color rojo si detecta un objeto dentro de su campo de acción, para eso añadimos el código siguiente justo después de la línea 29:
pushMatrix();
translate(640,666);
strokeWeight(5);
stroke(255,10,10); // color rojo
objetoDistancia = radarDistancia*15;
if(radarDistancia<40){ // si la distancia es menos de 40 cm
line(objetoDistancia*cos(radians(radarAngulo)),-objetoDistancia*sin(radians(radarAngulo)),633*cos(radians(radarAngulo)),-633*sin(radians(radarAngulo)));
}
popMatrix();
Comprobemos como funciona:

Nos detecta y representa los objetos en la pantalla, pero comprobaréis que no se desvanecen las líneas, para eso añadimos el siguente código dentro de la función draw() justo debajo de nostroke() y por encima del comentario líneas del radar
fill(0,4);
rect(0, 0, 1280, 720);
fill(10,255,10);
Ya solo nos falta que dibuje los arcos y las líneas de separación del radar, para ello añadimos el siguente código, también dentro de la función draw():
pushMatrix();
translate(640,666);
noFill();
strokeWeight(2);
stroke(10,255,10);
arc(0,0,1200,1200,PI,TWO_PI);
arc(0,0,934,934,PI,TWO_PI);
arc(0,0,666,666,PI,TWO_PI);
arc(0,0,400,400,PI,TWO_PI);
strokeWeight(4);
line(-640,0,640,0);
line(0,0,-554,-320);
line(0,0,-320,-554);
line(0,0,0,-640);
line(0,0,320,-554);
line(0,0,554,-320);
popMatrix();
Por fin nos parecerá un radar auténtico:

Código completo para processing:
import processing.serial.*;
Serial puerto;
String serialAngulo;
String serialDistancia;
String serialDatos;
float objetoDistancia;
int radarAngulo, radarDistancia;
int index=0;
void setup(){
size (1280, 720);
String puertoUtilizado = "COM5";
puerto = new Serial(this, puertoUtilizado, 9600);
puerto.bufferUntil('#');
}
void draw(){
noStroke();
fill(0,4);
rect(0, 0, 1280, 720);
fill(10,255,10);
//Radar Arcos y líneas
pushMatrix();
translate(640,666);
noFill();
strokeWeight(2);
stroke(10,255,10);
arc(0,0,1200,1200,PI,TWO_PI);
arc(0,0,934,934,PI,TWO_PI);
arc(0,0,666,666,PI,TWO_PI);
arc(0,0,400,400,PI,TWO_PI);
strokeWeight(4);
line(-640,0,640,0);
line(0,0,-554,-320);
line(0,0,-320,-554);
line(0,0,0,-640);
line(0,0,320,-554);
line(0,0,554,-320);
popMatrix();
// Líneas del radar
pushMatrix();
strokeWeight(5);
stroke(10,255,10); // color verde
translate(640,666);
line(0,0,640*cos(radians(radarAngulo)),-640*sin(radians(radarAngulo)));
popMatrix();
// Objeto detectado, líneas de color rojo
pushMatrix();
translate(640,666);
strokeWeight(5);
stroke(255,10,10); // color rojo
objetoDistancia = radarDistancia*15;
if(radarDistancia<40){ // si la distancia es menos de 40 cm
line(objetoDistancia*cos(radians(radarAngulo)),-objetoDistancia*sin(radians(radarAngulo)),633*cos(radians(radarAngulo)),-633*sin(radians(radarAngulo)));
}
popMatrix();
}
void serialEvent (Serial puerto){
serialDatos = puerto.readStringUntil('#');
serialDatos = serialDatos.substring(0,serialDatos.length()-1);
index = serialDatos.indexOf("*");
serialAngulo= serialDatos.substring(0, index);
serialDistancia= serialDatos.substring(index+1, serialDatos.length());
radarAngulo = int(serialAngulo);
radarDistancia = int(serialDistancia);
}