El sensor HC-SR04 utiliza el principio de medición de tiempo de eco para determinar la distancia a un objeto. Consiste en un emisor de ultrasonidos y un receptor.
Cuando el emisor de ultrasonidos es activado, envía un pulso de sonido de alta frecuencia. Este pulso se refleja en un objeto cercano y vuelve al receptor. El sensor mide el tiempo transcurrido desde que se envió el pulso hasta que se recibió el eco y utiliza esta información para calcular la distancia del objeto.
La distancia se calcula utilizando la fórmula: d = (t * v) / 2 donde t es el tiempo transcurrido desde el envío del pulso hasta la recepción del eco, y v es la velocidad del sonido (en cm por microsegundo). El 2 es porque el sonido tiene que recorrer la distancia 2 veces, una para ir y otra para volver al sensor.
El sensor HC-SR04 tiene dos pines, TRIG (disparador) y ECHO (eco), que se utilizan para enviar y recibir el pulso de sonido, respectivamente. El Arduino se comunica con el sensor mediante estos pines para activar el emisor, medir el tiempo de eco y calcular la distancia.
En nuestro ejemplo conectamos el pin TRIG del sensor al pin 9 del Arduino, el pin ECHO al pin 8, el pin Vcc al pin 5V y el pin GND al pin GND.
En el bucle principal loop(), se envía un pulso de 10 microsegundos al pin TRIG para iniciar la medición de distancia. Luego, se mide el tiempo que tarda el pulso en volver al pin ECHO utilizando la función pulseIn().
A continuación, se calcula la distancia en cm utilizando la fórmula antes vista.
const int TRIGGER_PIN = 8;
const int ECHO_PIN = 9;
const double VEL_SOUND = 34000.0 / 1000000.0;
void setup() {
Serial.begin(9600);
pinMode(ECHO_PIN, INPUT);
pinMode(TRIGGER_PIN, OUTPUT);
}
void loop() {
// Envía un pulso de 10 microsegundos al TRIGGER_PIN
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
// Detiene el pulso
digitalWrite(TRIGGER_PIN, LOW);
// Lee el tiempo que tarda el pulso en volver al ECHO_PIN
long duration = pulseIn(ECHO_PIN, HIGH);
// Convierte el tiempo en distancia (en cm)
double distance = (duration * VEL_SOUND ) / 2.0;
Serial.print("Duracion: ");
Serial.print(duration);
Serial.print(" Distancia: ");
Serial.println(distance);
delay(100);
}
Los sensores ultrasonidos son una forma barata de medir distancias. Por otro lado para distancias muy cercanas o muy lejanas el sensor puede no funcionar. Tampoco da buenos resultados para objetos en movimiento, o de según que materiales o formas.
Es un sensor expuesto a ruidos. Las mayores fuentes de ruido son los ruidos sonoros ambiente en la misma frecuencia y los ecos.
Para reducirlo vamos a usar un filtro de mediana tomando 3 muestras de cada medida. A mayor número de muestras más seguro estaremos pero más tiempo tardaremos en tener una medida lo cual reducirá la frecuencia de muestreo (no confundir con la frecuencia del sonido enviado)
Vamos a ver el código para implementar un filtro de mediana de en el ejemplo anterior:
const int TRIGGER_PIN = 8;
const int ECHO_PIN = 9;
const double VEL_SOUND = 34000.0 / 1000000.0;
void setup() {
Serial.begin(9600);
pinMode(ECHO_PIN, INPUT);
pinMode(TRIGGER_PIN, OUTPUT);
}
void loop() {
// Convierte el tiempo en distancia (en cm)
long duration = readDuration();
double distance = (duration * VEL_SOUND) / 2.0;
Serial.print("Duracion: ");
Serial.print(duration);
Serial.print(" Distancia: ");
Serial.println(distance);
}
long readDuration(){
long a,b,c;
a = readSensor();
delay(50);
b = readSensor();
delay(50);
c = readSensor();
delay(50);
return medianFilter(a,b,c);
}
long readSensor(){
// Envía un pulso de 10 microsegundos al TRIGGER_PIN
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
// Detiene el pulso
digitalWrite(TRIGGER_PIN, LOW);
// Lee el tiempo que tarda el pulso en volver al ECHO_PIN
long duration = pulseIn(ECHO_PIN, HIGH);
}
long medianFilter(long a, long b, long c) {
long temp;
if (a > b) { // Ordenar a, b
temp = a;
a = b;
b = temp;
}
if (b > c) { // Ordenar b, c
temp = b;
b = c;
c = temp;
}
if (a > b) { // Ordenar a, b de nuevo
temp = a;
a = b;
b = temp;
}
return b; // El valor medio es el segundo de los tres números ordenados
}