En artículos anteriores se ha explicado el uso de un sensor de ultrasonidos con Arduino. En este artículo le daremos una utilidad a nuestro modulo para hacer un sonar que nos detecte la distancia a objetos sobre un área.
El módulo de ultrasonidos HY-SFR05 que usaremos en este tutorial es bastante directivo, y con ayuda de un servo, podremos hacer un barrido de 180° para explorar un área. Arduino se encargará de tomar las medidas y con un programa desarrollado en Processing podremos mostrar los datos en un PC. La comunicación Arduino-Processing la realizaremos mediante el puerto serie.
Esquema del circuito
Montaje del circuito
Como vemos en el esquema usaremos una alimentación externa de 5v. Esto se debe a que el servo consume más de lo que Arduino puede entregar. Es de vital importancia no conectar el servo al pin de 5v de Arduino, pues obtendremos medidas erróneas. Ya que usaremos una fuente externa, conectaremos a ella también el módulo de ultrasonido.
No debemos pasar por alto que al usar una fuente de alimentación externa debemos conectar la masa de Arduino con la de la fuente, de lo contrario el circuito no funcionará.
El código para este proyecto consta de dos partes, uno para Arduino y otro para Processing que veremos en otro tutorial. Arduino se encargará de tomar las medidas de distancia para cada posición del servo y mover este desde la posición de 0° a 180° y viceversa. Los datos obtenidos se enviaran por el puerto serie.
/* Arduino Ultrasonic Sonar v1.1 Autor: FjRamirez Fecha: 15/04/2013 Una modificación de luckylarry.co.uk Arduino SRF05 Sonar Sketch */ #include <Servo.h> // Añade la libreria Servo Servo leftRightServo; // Crea una variable servo int leftRightPos = 0; // Variable para la posición del servo (grados) int index = 0; // Contador para el número de lectura long total = 0; // Variable para calcular el pormedio int average = 0; // Variable para calcular el promedio long duration = 0; // Variable para calcular el tiempo de llegada de la señal int distance = 0; // Variable para calcular la distancia // CONFIGURACIÓN: int echoPin = 53; // SRF05's Echo pin int trigPin = 51; // SRF05's Trig pin int servoPin = 12; // Pin para el cable de señal del servo int servoMin = 700; // Anchura del pulso, en microsegundos, correspondiente al mínimo (0 grados) ángulo en del servo (por defecto 544) int servoMax = 2400; // Anchura del pulso, en microsegundos, correspondiente al máximo (180 grados) ángulo en del servo (por defecto 2400) const int numReadings = 2; // Número de lecturas en cada posición void setup() { leftRightServo.attach(servoPin,700,2400); // Pin de salida para el servo, recorrido minimo, recorrido maximo Serial.begin(9600); // Establece la velocidad de datos del puerto serie pinMode(trigPin, OUTPUT); // Establece pin como salida pinMode(echoPin, INPUT); // Establece pin como entrada digitalWrite(trigPin, LOW); // Pone el pin a un estado logico bajo } void loop() { for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) { // De izquierda a derecha. leftRightServo.write(leftRightPos); for (index = 0; index<numReadings; index++) { // Repite tantas veces como número de lecturas en cada posicion // Pulso de 10us para inicial el modulo digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH, 17400); // Devuelve la longitud del pulso del pin Echo en us (3metros maximo) if (!duration){ // Si la duracción es 0 duration = 17400; // La señal se a perdido. Se establece distancia maxima } distance = duration/58; // Calculamos distancia en centrimetros total = total + distance; // Almacenamos la distancia para calcular promedio delay(50); // Esperamos hasta la siguiente medida } average = total/numReadings; // Calcula el promedio total = 0; // Resetea variable // Envia datos por el puerto serie Serial.print("X"); // Identificador X para la posicion del servo Serial.print(leftRightPos); // Posición del servo Serial.print("V"); // Identificador V para el promedio de distancia Serial.println(average); // Promedio de distancia } for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) { // De derechas a izquierda leftRightServo.write(leftRightPos); for (index = 0; index<numReadings; index++) { // Pulso de 10us para inicial el modulo digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH, 17400); if (!duration){ duration = 17400; } distance = duration/58; total = total + distance; delay(50); } average = total/numReadings; total = 0; Serial.print("X"); Serial.print(leftRightPos); Serial.print("V"); Serial.println(average); } }
Descripción de configuración de variables
numReadings nos permite configurar cuantas medidas se tomaran en cada posición del servo. El valor en esta posición será un promedio de los valores obtenidos. Esto se usa para evitar posibles fallos en la medida. Cuanto más aumentemos este valor obtendremos una medida más exacta en puntos en los que puedan existir reflexiones o multitrayectos del sonido. El aumentar este valor implica un mayor tiempo empleado para rastrear una zona.
servoMin y servoMax permiten establecer la duración mínima y máxima del pulso de salida para el servo correspondiente a 0° y 180°. Es posible que dependiendo de nuestro servo tengamos que modificar estos valores haciendo unas pruebas previas. Si vemos que el servo no hace todo su recorrido o hace movimientos extraños, varía estos datos hasta conseguir su recorrido total.
Una vez cargado el código en Arduino podremos ver en el monitor serie algo parecido a esto.
Para interpretar los datos y mostrarlos de forma visual tendremos que seguir este tutorial: Sonar con Processing.