Radar con Arduino
Proyecto fácil y sencillo de Radar usando Arduino y Processing.
Ejemplo del proyecto una vez acabado
Este artículo está basado en uno ya publicado pero añadiéndole ligeros cambios. Explicaremos cómo montar un radar usando Arduino y Processing, ambos programas gratuitos. Ahora comentaremos los materiales necesarios para realizar este proyecto.
Los materiales necesarios:
- Placa Arduino UNO R3
- Sensor ultrasónico HC-SR04
- Micro servo SG90
- Protoboard
- Cables Dupont
Lo siguiente será mostrar el esquema de montaje, teniendo en cuenta que usaremos los puertos 10, 11 y 12 de la placa (señal), su GND (tierra) y los 5V (alimentación).
El servomotor consta de 3 pines, uno de tierra, otro de alimentación y otro de señal (va a un puerto de la placa). El sensor ultrasónico consta de 4 pines, uno va a alimentación, otro a tierra, el pin de trigger y el de echo van a puertos de la placa.
Esquema del cableado
Ahora le comentaremos el código empleado en Arduino. Usamos los puertos 10, 11 y 12. Usamos la librería Servo.h, declaramos las variables a usar. Configuramos el trigger como salida y el echo como entrada. El algoritmo constará de un bucle que realizará un paneo gracias al motor y el sensor pegado a el nos indicará si hay un objeto cerca y cómo de cerca. Para esto utilizaremos una función llamada calculateDistance.
El código completo que usaremos en Arduino es el siguiente:
Este código controla un servo y un sensor ultrasónico para medir distancias. El servo se mueve de 15° a 165° y luego regresa, mientras en cada posición se mide la distancia a un objeto. La distancia se calcula usando la duración del eco del sensor ultrasónico y se imprime junto con el ángulo del servo en el monitor serie. La función CalculateDistance() gestiona el envío del pulso ultrasónico y calcula la distancia basándose en el tiempo de retorno del eco.
Para completar el proyecto, descargaremos el programa Processing de forma gratuita: https://processing.org/download
Una vez descargado será hora de crear la interfaz que nos dirá dónde está el objeto identificado y a cuanta distancia. Para ello usaremos el siguiente código, no te olvides de modificar en la línea 11 del código el puerto utilizado por el que estés usando tú. Lo puedes saber mirando en el programa Arduino, en Tools, Port: COM.
Antes de darle a Run al código de Processing, cierra el programa de Arduino, sino el puerto COM estará ocupado.
import processing.serial.*; // Importar librería para establecer la comunicación import java.awt.event.KeyEvent; // Importar librería para leer datos del puerto import java.io.IOException; Serial myPort; // Definir el Objeto // Definimos variables String angle=""; String distance=""; String data=""; String noObject; float pixsDistance; int iAngle, iDistance; int index1=0; int index2=0; PFont orcFont; void setup() { size (1200, 700); // ***CAMBIAR PARA LA RESOLUCIÓN DE TU PANTALLA*** smooth(); myPort = new Serial(this,"COM5", 9600); // COMENZAR COMUNICACIÓN myPort.bufferUntil('.'); // LEER DATOS DESDE EL CARÁCTER '.'. Así que leerá: Angulo, Distancia } void draw() { fill(98,245,31); // // Simulación y un suave fade de la línea noStroke(); fill(0,4); rect(0, 0, width, height-height*0.065); fill(98,245,31); // VERDE // Función para dibujar el radar drawRadar(); drawLine(); drawObject(); drawText(); } void serialEvent (Serial myPort) { // Comenzar lectura de datos del puerto // Leemos los datos del puerto después del carácter '.' y los añadimos al string "data". data = myPort.readStringUntil('.'); data = data.substring(0,data.length()-1); index1 = data.indexOf(","); // Encontramos el carácter',' y lo añadimos a la variable "index1" angle= data.substring(0, index1); // Leemos los datos de la posición "0" a la posición de la variable "index1" y ese es el valor de ángulo enviado desde el puertp distance= data.substring(index1+1, data.length()); // Leemos los datos de la variable "index1" y este es el valor de la distancia // Convertimos al string en interg iAngle = int(angle); iDistance = int(distance); } void drawRadar() { pushMatrix(); translate(width/2,height-height*0.074); // Movemos las coordenadas iniciales a la nueva ubicación noFill(); strokeWeight(2); stroke(98,245,31); // Dibujamos el arco arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI); arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI); arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI); arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI); // draws the angle lines line(-width/2,0,width/2,0); line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30))); line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60))); line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90))); line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120))); line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150))); line((-width/2)*cos(radians(30)),0,width/2,0); popMatrix(); } void drawObject() { pushMatrix(); translate(width/2,height-height*0.074); // Movemos las coordenadas iniciales a la nueva ubicación strokeWeight(9); stroke(255,10,10); // ROJO pixsDistance = iDistance*((height-height*0.1666)*0.025); // Pasamos la distancia cubierta por el sensor de cm a píxeles // Limitamos en rango a 40cm if(iDistance<40){ // Dibujar objeto acorde al ángulo y distancia line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle))); } popMatrix(); } void drawLine() { pushMatrix(); strokeWeight(9); stroke(30,250,60); translate(width/2,height-height*0.074); // Mover coordenadas iniciales a la nueva ubicación line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // Dibujar línea acorde al ángulo popMatrix(); } void drawText() { // Escribir texto en la pantalla pushMatrix(); if(iDistance>40) { noObject = "Out of Range"; } else { noObject = "In Range"; } fill(0,0,0); noStroke(); rect(0, height-height*0.0648, width, height); fill(98,245,31); textSize(25); text("10cm",width-width*0.3854,height-height*0.0833); text("20cm",width-width*0.281,height-height*0.0833); text("30cm",width-width*0.177,height-height*0.0833); text("40cm",width-width*0.0729,height-height*0.0833); textSize(40); text("EL ESCOBIN ", width-width*0.875, height-height*0.0277); text("Ángulo: " + iAngle +" °", width-width*0.48, height-height*0.0277); text("Dist:", width-width*0.26, height-height*0.0277); if(iDistance<40) { text(" " + iDistance +" cm", width-width*0.225, height-height*0.0277); } textSize(25); fill(98,245,60); translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30))); rotate(-radians(-60)); text("30°",0,0); resetMatrix(); translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60))); rotate(-radians(-30)); text("60°",0,0); resetMatrix(); translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90))); rotate(radians(0)); text("90°",0,0); resetMatrix(); translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120))); rotate(radians(-30)); text("120°",0,0); resetMatrix(); translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150))); rotate(radians(-60)); text("150°",0,0); popMatrix(); }
El proyecto acabado quedará de está manera, adjuntamos video con el resultado.
Esperamos que os haya servido de ayuda para completar vuestro proyecto o al menos para aprender algo que desconocíais.