2024-10-05
Sensor ultrasónico HC-SR04
El sensor HC-SR04 es un medidor de distancias por ultrasonidos de bajo costo, veremos su funcionamiento y como programarlo en Arduino.
Entre sus características encontraremos las siguientes:
- Voltaje de 5V con un consumo de menos de 2mA.
- Detección desde 2cm hasta 450cm.
- Ángulo de detección de no mas de 15°.
- Precisión de hasta 3mm.(*)
Funcionamiento
El sensor dispone de un pin llamado trigger (disparo) y otro llamado echo (eco), además de los normales de alimentación (VCC y GND).
Al dar un pulso en valor alto (HIGH) de al menos 10uS en el pin trigger, el hc-sr04 emite una señal de 40KHz que al encontrar una superficie rebotará y volverá al sensor. El hc-sr04 mide el tiempo que tarda la señal en contestar y nos devuelve un pulso de la misma duración en el pin echo.
De esta forma conocemos el tiempo que ha tardado en recorrer la distancia a medir y como conocemos la velocidad del sonido tan solo hemos de multiplicar la velocidad por el tiempo para obtener la distancia.
Tan solo hay que tener un detalle en cuenta, que el tiempo que nos devuelve es el de ida y vuelta de la señal, con lo que el resultado habrá que dividirlo por dos para obtener la distancia real.
Sobre la velocidad del viento.
La velocidad no es un valor exacto y depende de parámetros como la humedad o la temperatura, siendo este un factor muy importante. Generalmente, se dice que la velocidad del sonido es de unos 343.2 m/s, pero esto es a una temperatura de 20°C y una humedad del 50%.
El valor exacto de la velocidad, es cambiado muchas veces en distintos programas siendo de 342m/s en algunos casos o incluso 340m/s.
Si estamos en interior donde la temperatura se puede considerar casi constante podemos el valor anterior, pero en exteriores la temperatura cambia, así que conviene tener una corrección de temperatura. Para ello podemos usar la siguiente fórmula:
c = 330.0 + 0.6T
Donde T es la temperatura en grados centígrados.
El uso de una fórmula u otra depende del uso que le vayamos a dar al sensor.
En muchos programas de Arduino nos encontraremos que lo que se hace es dividir el tiempo por 29.2. Este valor en realidad es el tiempo en microsegundos para 1cm.
Esquemático
El hc-sr04 se basa en un microcontrolador STC11 que se encarga de genera la señal de 40khz que envía al transductor mediante un adaptador de nivel MAX232.
Igualmente se encarga de recoger la señal que previamente se ha adaptado mediante un amplificador operacional TL074.
Pinout
Leer la distancia con Arduino
El primer paso es generar un pulso de 10uS en el pin trigger y esto lo podemos hacer simplemente usando delayMicroseconds.
El siguiente paso es leer el pulso y podemos hacerlo con la función pulseIn. Dicha función tiene dos parámetros: el pin sobre el cual escuchar el pulso y el valor que tiene que esperar (alto o bajo).
También acepta un tercer parámetro que es un tiempo de timeout, durante el cual espera que la señal cambie, y si no lo hace retorna. Por defecto este tiempo es de un segundo.
Esta función espera a que el pin cambie al valor indicado y mide cuanto tiempo está en ese valor, devolviendo el tiempo en microsegundos. Si no se detecta un pulso el valor devuelto será 0.
El código puede quedar de la siguiente manera:
// EJEMPLO DE LA LECTURA DE UN SENSOR HC-SR04 const int EchoPin = 7; const int TriggerPin = 6; void setup() { Serial.begin(9600); pinMode(TriggerPin, OUTPUT); pinMode(EchoPin, INPUT); } void loop() { Serial.print("Distancia: "); Serial.print(ping()); Serial.println("cm"); delay(1000); } float ping() { unsigned long duration; digitalWrite(TriggerPin, HIGH); //generamos Trigger (disparo) de 10us delayMicroseconds(10); digitalWrite(TriggerPin, LOW); duration = pulseIn(EchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos duration = duration >> 1; // Dividimos por 2. float distance = (duration)*0.0343; // Calculamos la distancia. return distance; }
En este código he creado una clase ping que simplifica el uso del sensor, tan solo hay que declarar el objeto ping pasando los parámetros del pin trigger y echo y luego leerlo con la función read. Además read acepta un parámetro que es la temperatura para realizar la corrección por temperatura.
// EJEMPLO DE LA LECTURA DE UN SENSOR HC-SR04 USANDO UNA CLASE const int EchoPin = 7; const int TriggerPin = 6; class ping { private: uint8_t trigger; uint8_t echo; public: ping(uint8_t t, uint8_t e) { trigger = t; echo = e; pinMode(trigger, OUTPUT); digitalWrite(trigger, LOW); pinMode(echo, INPUT); } float read(float temp=20) { unsigned long duration; digitalWrite(trigger, HIGH); //generamos Trigger (disparo) de 10us delayMicroseconds(10); digitalWrite(trigger, LOW); duration = pulseIn(echo, HIGH); //medimos el tiempo entre pulsos, en microsegundos duration = duration >> 1; // Dividimos por 2. return duration*(((330+0.6*temp)*100.0)/1000000.0); //return (duration)*0.0343; // Calculamos la distancia. } }; ping sensor(TriggerPin, EchoPin); void setup() { Serial.begin(9600); } void loop() { Serial.print("Distancia: "); Serial.print(sensor.read()); Serial.println("cm"); delay(1000); }
También se pueden usar librerías externas como NewPing la cual es bastante buena e incluso nos permite realizar la misma operación tan solo usando un pin.
Algunas observaciones.
Aunque según las características dice que la precisión es de 3mm, realmente lograremos que tenga precisión de 1cm o mas. ¿Por qué? Tenemos que tener en cuenta los factores de la humedad y temperatura, incluso la precisión con Arduino.
También hemos de tener cuidado con los ángulos de detección, los objetos a detectar y otros factores que pueden hacer que las medidas no sean reales.
Otra observación es el hecho de usar la función pulseIn, esta función es bloqueante, es decir, bloquea el código a la espera del pulso, lo cual en algunas aplicaciones puede ser importante ya que si no hay un objeto cerca el código se detendrá al menos un segundo.
Referencias
LuisLlamas - Medir distancia con Arduino y sensor de ultrasonidos HC-SR04