En esta sesión vamos a trabajar con un sencillo sensor que nos va a permitir medir distancias en nuestros montajes, de tal forma que podamos decidir qué acciones a realizar en función de los límites de proximidad que decidamos.
Estos sensores se llaman de ultrasonidos, puesto que su modo de funcionamiento es enviar un ultrasonido (no perceptible para el oído humano) a través de uno de los dos cilindros que lleva incorporado, y queda en espera a que rebote contra un objeto, y su vuelta sea captada por el otro cilindro.
Hay que aclarar que debido al coste de este tipo de sensores (3-4€) no podemos esperar un gran rendimiento, pero en distancias de hasta 3 metros, sí que podremos encontrar buenos resultados con una precisión de 3mm.
El montaje en placa es sencillo. El sensor lleva incorporados de 4 pines:
- «VCC» conectado a 5V
- «Trig» conectado al pin digital que enviará el pulso ultrasónico
- «Echo» al pin de entrada digital que recibirá el rebote
- «GND» a tierra
Una vez realizado el montaje, cargamos el código que podemos ver a continuación para comprobar si hemos realizado bien dicho montaje:
const int EchoPin = 3;
const int TriggerPin = 4;
void setup() {
Serial.begin(9600);
pinMode(TriggerPin, OUTPUT);
pinMode(EchoPin, INPUT);
}
void loop() {
long duration, distanceCm;
digitalWrite(TriggerPin, LOW); //para generar un pulso limpio ponemos a LOW 4us
delayMicroseconds(4);
digitalWrite(TriggerPin, HIGH); //generamos Trigger (disparo) de 10us
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
duration = pulseIn(EchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos
distanceCm = duration * 10 / 292/ 2; //convertimos a distancia, en cm
Serial.print("Distancia: ");
Serial.println(distanceCm);
delay(1000);
}
Cabe destacar las siguientes funciones del código anterior:
- digitalWrite(TriggerPin, LOW); // generamos un pulso limpio poniendo a LOW el trigger
- digitalWrite(TriggerPin, HIGH); // generamos el disparo
- digitalWrite(TriggerPin, LOW); // apagamos el trigger
- pulseIn(EchoPin, HIGH); // función utilizar para medir el tiempo entre pulsos en microsegundos
- distanceCm = duration * 10 / 292/ 2; // fórmula utilizada para convertir a cm
Para ver el resultado tenemos que abrir el monitor serie y si utilizamos nuestra mano delante del sensor podremos ver como la distancia va variando.
A partir de aquí, las posibilidades de este sensor son múltiples. Seguramente lo habéis visto utilizamos como ojos en diferentes robots, donde su misión principal será detectar obstáculos y variar su rumbo en función de si la distancia superar un umbral determinado (por ejemplo, 30 cm).
Nosotros os proponemos un reto más sencillo: montar una serie de 6 leds y un buzzer, de tal forma que cuando la distancia por ejemplo sea inferior a 30cm, se vayan encendiendo cada vez más leds, a medida que la distancia del obstáculo se acerco a 0. De la misma forma el buzzer reproducirá diferentes sonidos de alarma en función de la distancia. El montaje sería como el siguiente:
El código a utilizar una vez hecho el montaje sería el siguiente:
//declaramos todos las constantes que vamos a necesitar para usar leds, el buzzer y los dos pines del ultrasonidos
#define trigPin 4
#define echoPin 3
#define led 13
#define led2 12
#define led3 11
#define led4 10
#define led5 9
#define led6 8
#define buzzer 5
//variable que utilizamos para reproducir sonidos en el buzzer
int sound = 250;
void setup() {
Serial.begin (9600);
//inicializamos los dos pines del ultrasonidos
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
//inicializamos todos los leds
pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(buzzer, OUTPUT);
}
void loop() {
long duration, distance;
//limpiamos de ruido el pin que realizo el disparo del ultrasonido y lo lanzamos
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//recibimos el ultrasonido de vuelta
duration = pulseIn(3, HIGH);
// calculamos la distancia en cm
distance = duration * 10 / 292/ 2; //convertimos a distancia, en cm
//preguntamos si la distancia que tenemos con el objeto es menor o igual a 50.
//en tal caso encendemos el primero de los leds y reproducimos un sonido, el 250
//en caso contrario apagamos led
//lo mismo con el resto de leds, en función de si el objeto se acerca vamos encendiendo leds y reproducienco sonidos
if (distance <= 50) {
digitalWrite(led, HIGH);
sound = 250;
}
else {
digitalWrite(led,LOW);
}
if (distance < 40) {
digitalWrite(led2, HIGH);
sound = 260;
}
else {
digitalWrite(led2, LOW);
}
if (distance < 30) {
digitalWrite(led3, HIGH);
sound = 270;
}
else {
digitalWrite(led3, LOW);
}
if (distance < 20) {
digitalWrite(led4, HIGH);
sound = 280;
}
else {
digitalWrite(led4,LOW);
}
if (distance < 15) {
digitalWrite(led5, HIGH);
sound = 290;
}
else {
digitalWrite(led5,LOW);
}
if (distance < 10) {
digitalWrite(led6, HIGH);
sound = 300;
}
else {
digitalWrite(led6,LOW);
}
// por úlitmo si la distancia está por encima de nuestro mínimo (50cm) o debajo de 0 sacamos mensaje y apagamos buzzer
if (distance > 50 || distance <= 0){
Serial.println("Out of range");
noTone(buzzer);
}
// si entramos al else es que estamos encendiendo leds y reprodciendo sonidos así que sacamos valores en monitor serie y reproducimos sonido
// en los IF anteriores le habremos dado un valor a la variable sound en función de la cercanía del objeto, aquí la reproducimos
else {
Serial.print(distance);
Serial.println(" cm");
tone(buzzer, sound);
}
delay(500);
}
Para finalizar, Javier Lucia nos cuenta en un video los montajes de ambos circuitos y sus respectivos códigos.