Sensor ultrasonido HC-SR04

Hola:

Ver imagen.

Usando el sensor HC-SR04 que me costó menos de 5 €. Iba a comprar el SFR05 por 15 € pero me lo pensé mejor por el precio.

Usando el código de abajo, por lo que veo, no es muy preciso, es decir, si dejo el sensor HC-SR04 activado y en un lugar fijo, como el de la foto arriba, el suelo fijo apuntando el techo. Lo analiza cada refresco 1 segundo.

En la variación varía entre 2 centímetros, a veces 4. Si hubiera un terremoto entiendo la variación. ¿Quiero saber por qué varía?

No se si es cuestión del código, o simplemente el sensor HC-SR04 no es muy preciso comparado con otros como Ping ))), SFR05, SFR08 y algunos más.

El código que he probado es este:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
     
    const int trigger=10;
    const int echo=13;
     
    float distance;
    const String nivel_agua = "Nivel de agua:";
     
    void setup(){
      lcd.begin(16,2);
      Serial.begin(9600);
      pinMode(trigger,OUTPUT);
      pinMode(echo,INPUT);
    }
     
    void loop(){
    //Inicializamos el sensor
      digitalWrite(trigger,LOW);
      delayMicroseconds(5);
    // Comenzamos las mediciones
    // Enviamos una señal activando la salida trigger durante 10 microsegundos
      digitalWrite(trigger,HIGH);
      delayMicroseconds(10);
      digitalWrite(trigger,LOW);
    // Adquirimos los datos y convertimos la medida a metros
     distance=pulseIn(echo,HIGH); // Medimos el ancho del pulso
                                  // (Cuando la lectura del pin sea HIGH medira
                                  // el tiempo que transcurre hasta que sea LOW
     distance=distance*0.0001657;
    // Enviamos los datos medidos a traves del puerto serie y al display LCD
      Serial.println("Nivel de agua:");
      Serial.print(distance);
      Serial.println(" Metros.");
      
      lcd.setCursor(0,1);
      lcd.print(distance);
      lcd.print(" Metros.");
      lcd.setCursor(0,0);
      lcd.print(nivel_agua);
      delay(1000);
    }

Seguro que se puede hacer muchísimo mejor.

Un saludo.

Hola Metaconta.

A mi me pasa lo mismo.
en principio el problema del error de medida está aqui:

distance=distance*0.0001657;

Para la optención del "0,0001657" utiliza el valor de la velocidad del sonido en el aire seco que es 331,4 m/s en vez de los 343,0,16 m/s a 20ºC.

Pero a pesar de sustituir el "0,0001657" Por su valor real " 0,0001715" en medidas de mas de 1 metro llega a tener un error de mas de 10 centímetros. Y eso es UN MUCHISSIIIIMO!!!.

¿Alguien ha solucionado esto?

Tengo el mismo sensor y de momento me funciona si problema alguno, estoy utilizando esta librería, que viene limitada a una distancia de 51 cm pero es facilmente editable para ampliar o reducir esta distancia(al reducirla puedes actualizarla mas veces por segundo

página del autor donde además de explicar como usarla, pone ejemplos:
http://www.ardublog.com/library-for-arduino-ultrasonic-ranging-hc-sr04/

Gracias Daklon.

Por medio de tu sujerencia, he incluido al programa que expone Metaconta tu librería.
Lo adjunto por si quereis saber como ha quedado:

#include <LiquidCrystal.h>
#include <Ultrasonic.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // 12-Rs, 11-Enable, 5-D4, 4-D5, 3-D6, 2-D7
Ultrasonic ultrasonic (10 , 13, 11600);

const int LED = 9;
const int potAlarma=0;

float distancia;
int val;
float lim;

void setup ()
{
Serial.begin (9600);
lcd.begin(16,2);
pinMode( LED, OUTPUT);

}

void loop ()
{
//leemos el valor del potenciometro que nos indica el limite de la alrma
val = analogRead (potAlarma);
lim = val * 0.00293; // 3 metros de máximo que mide el sensero dividido entre 1024. Valor max del potenciometro
distancia = (ultrasonic.Ranging (CM)*0.01);

//Alarma
if (distancia < lim) {
digitalWrite (LED , HIGH);
}
else { digitalWrite (LED, LOW);}

//Enviamos los datos medidos a través del puerto serie al LCD
lcd.clear ();
lcd.setCursor (0,0);
lcd.print (“Distancia:”);
lcd.setCursor (11,0);
lcd.print (ultrasonic.Ranging (CM)*0.01); // CM o INC
lcd.setCursor (15,0);
lcd.print (“m”);
lcd.setCursor (0,1);
lcd.print (“Limite:”);
lcd.setCursor (8,1);
lcd.print (lim);
lcd.setCursor (12,1);
lcd.print (“m”);
delay (1000);
}

Ahora tengo un problema.
He introducido el sensor para medir la columna de agua en un tubo de PVC de aprox 2.70 de altura.
A partir de 1.60 metros empeizan los problemas.
La lectura no es estable.

¿Alguna idea para solucionar esto?
¿Será mas fiable leer distancias con el sensor laser FZ0173?
No estoy muy enterada de como va el sensor. Supongo que por sólo comprar el FZ0173 no se podrá empezar a leer distancias.

Este sensor funciona mandando ecos y esperando a que estos reboten en los objetos, en un tubo pueden rebotar de muchas formas dando lecturas erroneas por lo que no es un buen sistema de medición, yo que tu optaría por otro.

No se si el laser te servirá porque nunca lo he usado, lo siento

Lo voy a probar, muchas gracias.

Hola de nuevo.

He estado trasteando con el HC-SR04 y he sacado las siguientes conclusiones:
1.- En un tubo de 110 mm de diametro y 2,50 metros de longitud en posición vertical, lo puse en la parte superior y el tubo lo llené de agua.
A medida que lo iba vaciando, el ultrasonidos mide.
Empecé a tener problemas de medida a partir de 1,40 metros. Los rebotes de las ondas en las paredes del tubo daban medidas erroneas del tipo 0,40 metros cuando habia 1,40.
Ya a partir de 1,60 no mide mas. Por mucho que baja el nivel de agua el ultrasonidos se estanca en 1,60.

2.- Lo he puesto a medir en un tanque cilindrico horizontal.
Las medidas cuando el líquido esta de la mitad para arriba aún se pueden dar por válidas, pero cuando va de la mitad para abajo, la onda tropieza en las paredes y la medida es muy mala.
En vez de medir la altura del liquido, da la distancia del ultrasonidos a al pared del tanque.

3.- Me queda ponerlo a medir dentro de un tanque cuadrado o rectangular, que seguramente es donde lo tendreis funcionando casi todos.

La conclusión que saque es que el ancho de onda es demasiado grande y crea muchos ecos dentro de los tanques.
Casi necesita 25 cn de diametro libres a cualquier pared para que funcione con cierta claridad.
Desconozco si para el Arduino existen otro tipo de ultrasonidos que tenga menos angulo de emisión de onda.

Un saludo

Buenas,

Creo te será útil tener en cuenta la siguiente información:

http://www.micropik.com/PDF/HCSR04.pdf

Ahí puedes ver que en el mejor de los casos tendrás un error de 3mm en la medición.

Además, dispositivo no realiza la medida hacia una dirección concreta sino que tiene una apertura de 15º, es decir, que el diámetro libre que necesitarías depende, en principio, de la distancia a la que estés midiendo. Si por ejemplo usas un tubo de 110mm de diámetro y colocas el sensor centrado, el primer rebote se produciría a “L = radio/tan(mitad del ángulo de apertura)” (espero no estar metiendo la pata que soy el típico que se equivoca con las matemáticas más simples XD).

Eso quiere decir que el primer rebote se estaría produciendo a 20.3mm del sensor, aunque por el ángulo de incidencia ese rebote no vuelve al sensor directamente (por eso tu sensor da medidas más allá de esa distancia) pero sí que a partir de esas longitudes pueden interferir unas ondas con otras.

El sensor emite 8 ondas distintas dentro de ese rango de 15º y se queda con la primera que reciba, que generalmente será la que vaya centrada pues recorre menos distancia en tu proyecto (no tendría por qué ser así si hicieses un rada, por ejemplo), pero según aumenta la distancia el número de rebotes se incrementa también y de ahí puede venir el fallo.

Por otro lado hay que tener en cuenta el material del tubo, pues “la fuerza” de los rebotes dependen de “la cantidad” de onda que atraviesa el tubo en cada choque y la cantidad de onda que rebota (igual que pasa con el líquido sobre el que rebota…). Si por ejemplo el cubo es metálico (PEC) rebotaría toda la onda o si tuviera un grueso el material que fuese múltiplo de la mitad de la longitud de onda que emite el sensor lo atravesaría entero (ése es el criterio que se usa para pintar las antenas y se conoce como radomo).

Supongo que no soluciono tu problema en absoluto XD pero soy de los que piensa que a uno se le ocurren soluciones solamente cuando conoce bien el problema que está analizando. Si esto te ayuda a ver cuáles pueden estar siendo los fallos, quizás se te ocurra cómo solucionarlos.

Mi consejo es que no utilices este tipo de sistemas en cavidades porque no creo que pudiera ser lo suficientemente fiable. Yo buscaría algún tipo de solución con láser (piensa además cómo miden la distancia los aparejadores… si esa gente que son profesionales utilizan ese método del láser, no parece una locura pensar que pueda ser una buena solución :slight_smile: ).

Hola Enryke.

Muchas gracias por tu contestación.
Leeré con calma el pdf que adjuntas. Ya lo había leido justo antesde de perdir el ultrasonidos, pero igual repasandolo ahora que sabemos como funciona me aclaro algo mejor.

De todas formas intentaré incluir un filtro modal al código que puse mas arriba, de forma que indique en el display la media de nueve medidas que realice.
Si te apetece, te invito a que me ayudes en esto y así dejamos trillado el medidor de ultrasonidos.

El tema del Laser lo he pensado, pero ¿No tendrá problemas a la hora de medir sobre un líquido en el que su superficie no es totalmente estanco?
A parte, no busque mucho, pero no encontré laser para medir distancias en Arduino.
Tomaré en cuenta tus ideas.

Un millon de gracias.
Acuerdate de la invitación.
Realmente no se como empezar con el filtro modal. Pero me niego a desestimar el ultrasonidos hasta no estar completamente convencida de su funcionamiento.

Para comenzar, tengo esto, que pertenece a un MaxSonar EZ1
A ver como lo encajo en el código de arriba, :blush:

//El uso del módulo de sonda MaxSonar EZ1 en modo analógico con arduino
//Filtro de mediana de cinco lecturas consecutivas para eliminar los picos

// Toma 5 lecturas y las guardar en un RangeValue array
// Uso de un “tipo de insercción ascendente”. Reorganizar los valores de la matriz en orden ascendente
// Selecciona el elemento central de la matriz, que será, por definición, la mediana del conjunto de valores
//
// El pin analógico 1 para la lectura de la tensión analógica del dispositivo MaxSonar.

int anPin = 13;

//variables necesarias para almacenar los valores
int arraysize = 5; // Cantidad de valores que va a tomar para tomar la media.
// Tiene que ser un número impar.

/Declara una matriz para almacenar las muestras. No es necesario poner ceros
a los valoresde la matriza aquí, esto solamente aclara el código
/

int rangevalue = {0, 0, 0, 0, 0};
//*********************************************************************************************
void setup()
{

//Abrimos conexión serie
Serial.begin(9600);
printArray(rangevalue, arraysize);
delay(5000); //Esperamos a que se abra la ventana del monitor serie.

}
//********************************************************************************
void loop()
{

pinMode(anPin, INPUT);

for(int i = 0; i < arraysize; i++)
{ //array pointers go from 0 to 4

// Se usa para leer en la salida de tensión analógica que está siendo enviada por el dispositivo MaxSonar.
// El factor de escala es MaxSonar (Vcc/512) por pulgada. Un rendimiento de alimentación de 5V ~ 9.8mV/in
// El Arduino asignará voltajes de entrada entre 0 y 5 voltios en valores enteros entre 0 y 1023.
// Esto produce una resolución entre las lecturas de: 5 voltios / 1024 unidades o, 0.0049 voltios (4.9 mV) por unidad.
// Por lo tanto, una unidad de ADC del arduino representa 0,5 pulgadas

rangevalue* = analogRead(anPin);*
_ Serial.print("i, valor “);_
_ Serial.print(i);_
_ Serial.print(” , ");_
_ Serial.print(rangevalue*);_
_ Serial.println();_
_
delay(10); //tiempo de espera entre muestras*_
* } *
_ Serial.print("Sin clasificar ");
* printArray(rangevalue, arraysize);*
Serial.println();
* isort(rangevalue, arraysize);*
Serial.print("Clasificadas ");
* printArray(rangevalue, arraysize);*
Serial.println();_

* // Ahora mostramos la media *
* int midpoint = arraysize/2; //El punto medio de la matriz es el valor medio*
* //Tener en cuenta que para una matriz de 5, el punto medio es 2 y el primer punto es el elemento 0.*
_ Serial.print("Valor medio del rango ");
Serial.print(rangevalue[midpoint]);
Serial.println();
Serial.println(); _

* delay(3000); //Esperar un tiempo para que pueda leer los valores en el monitor serie*
} //fin del loop
/*--------------------------------------------------------------------
* FUNCIÓN DE CLASIFICACIÓN*
-----------------------------------------------------------------------*/
void isort(int *a, int n)
// “*a” es un punto del comando de la funcion

{
* for (int i = 1; i < n; ++i)*
* {*
_ int j = a*;
int k;
for (k = i - 1; (k >= 0) && (j < a[k]); k–)
{
a[k + 1] = a[k];
}
a[k + 1] = j;
}
}
/-----------------------------------------------------------

* La función imprime los valores de la matriz*
------------------------------------------------------------/
void printArray(int *a, int n)
{*_

* for (int i = 0; i < n; i++)*
* {*
_ Serial.print(a*, DEC);
Serial.print(’ ');
}*_

_ Serial.println();
}
[/size][/size]
[/quote]
:stuck_out_tongue:_

Buenas de nuevo,

Con respecto al láser que mida distancias esta sería una opción:

Aunque el rango de distancias deja bastante que desear y su utilidad dependería del rango en el que vayas a trabajar.

Por otra parte, sí que la incidencia de la señal en el agua puede ser un problema (como lo puede ser también con el HC-SR04). Honestamente... nunca he trabajado con eso, pero al existir un cambio de medio (aire-agua) parte de la onda se reflejaría y parte se refractaría, esto es, pasaría a estar dentro del agua, generalmente con un cambio de ángulo, y rebotaría en el fondo (o no, en función del ángulo) y tendría que considerarse si esa parte de la señal llega de nuevo al receptor (lo que sería un problema XD ). Además habría que ver si la potencia con la que llega la señal reflejada es suficiente.

Por tanto puede ser que el láser no sea la mejor opción.

Se me ocurre que si lo que quieres medir es una distancia al agua y conoces el volumen del recipiente es posible que se pueda colocar algún sensor que mida la presión (los hay para la presión atmosférica, aunque desconozco si existen también para medios acuaticos... al menos a un precio económico XD) o el peso del agua y con eso y un poco de matemáticas podrías sacar la distancia.

Si tu solución sigue siendo utilizar el HC-SR04, la verdad es que yo soy el primero que está desencantado con sus resultados XD he hecho un par de proyectos con él y sí que hay que tener cuidado con los valores extraños! lo que he hecho yo normalmente es parecido a lo que se te ha ocurrido a ti (y seguro que si te comes un poco la cabeza se te ocurren ideas muchísimo mejores XD ). He hecho un bucle en el que tomo varias medidas, las paso por un "if" con una condición amplia, es decir, si vas a medir algo que sabes que está entre 60cm y 90cm descartas de primeras todos los valores que estén fuera de ese rango, así la media de valores que hagas después será más cercana al valor real (a mí me han llegado a salir distancias negativas :frowning: imagínate si haces la media y uno de los valores es -50cm, se descuadra todo) y luego los valores (las distancias) que sí cumplen la condición del "if" las sumaba en una variable y dividía por el número de valores tomados. Esto es simple y te acercará bastante más al valor real, pero siempre depende todo de la precisión que necesites.

Otro pequeño detalle es si se están almacenando los datos variables tipo int o float.

En cuanto al código que tú tienes (el que te pertenece a ti) no lo he analizado en profundidad (y además nunca he usado la librería de esa pantalla XD ), pero creo que estás envíando información tanto al ordenador como a la pantalla y probablemente sea innecesario que envíes información al ordenador (el Serial.begin (9600)).

Tampoco he usado nunca la librería del módulo de ultrasonido (no sabía ni que existía XD ) y siempre lo he programado yo (aunque te digo desde ya que si hay una librería seguramente eso sea mucho más fiable y eficiente que lo que yo haya podido hacer XD ).

El código que pones del "MaxSonar" utiliza no la media de los valores, sino la mediana (por eso tiene que ordenar los valores y tal). Estadísticamente hablando te vas a acercar al valor real más veces usando la mediana que la media porque la mediana es una mejor medida de la tendencia central, del valor que generalmente esté más cerca del correcto, para distribuciones asimétricas que la media. Yo no lo suelo usar porque no me he movido entre un rango de valores lo suficientemente amplio normalmente (porque ajustaba bastante las condiciones del "if") para que se apreciase la diferencia y he preferido ahorrar tiempo y código XD, pero si necesitas más precisión ése es mejor método :slight_smile:

Si te digo la verdad, lo que pretendo es probar este código con el sensor HC-SR04.
Todos los filtros que encuentro son para otros sonar.

El problema que me estoy encontrando es que toma un valor de medida y lo reproduce tantas veces como filas tenga la matriz.
Si la matriz es de 5 filas y el sonar solo mide una vez y reproduce esa medida 5 veces.
Adjunto imagen del monitor serial.

Desordenados: 131 131 131 131 131 131 131 131 131
Ordenados: 131 131 131 131 131 131 131 131 131
La media es: 131
Desordenados: 134 134 134 134 134 134 134 134 134
Ordenados: 134 134 134 134 134 134 134 134 134
La media es: 134
Desordenados: 130 130 130 130 130 130 130 130 130
Ordenados: 130 130 130 130 130 130 130 130 130
La media es: 130
Desordenados: 129 129 129 129 129 129 129 129 129
Ordenados: 129 129 129 129 129 129 129 129 129
La media es: 129
Desordenados: 131 131 131 131 131 131 131 131 131
Ordenados: 131 131 131 131 131 131 131 131 131
La media es: 131
Desordenados: 135 135 135 135 135 135 135 135 135
Ordenados: 135 135 135 135 135 135 135 135 135
La media es: 135

La idea del código es buena, pero el funcionamiento es absurdo.
Hace la mediana de un solo valor.

¿Donde está el fallo?

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int trigger=10;
const int echo=13;
float distance;

int arraysize = 9; //cantidad de valores para encontrar la media (tamaño de la muestra). Tiene que ser un número impar

//declarar una matriz para almacenar las muestras. No es necesario poner a cero los valores de la matriz aquí, esto solamente aclara el código
int rangevalue = {0, 0, 0, 0, 0, 0, 0, 0, 0};
long pulse;
int modE;

void setup()
{

//Abrimos la conexion serie
Serial.begin(9600);
pinMode(trigger,OUTPUT);
pinMode(echo,INPUT);
//Esperamos a que se establezca conexión.
delay(500);
lcd.begin(16,2);

}
//Loop donde se desarrolla la acción.
void loop()
{

digitalWrite(trigger,LOW);
delayMicroseconds(5);
// Comenzamos las mediciones
// Enviamos una señal activando la salida trigger durante 10 microsegundos
digitalWrite(trigger,HIGH);
delayMicroseconds(10);
digitalWrite(trigger,LOW);
// Adquirimos los datos y convertimos la medida a metros
distance=pulseIn(echo,HIGH); // Medimos el ancho del pulso
// (Cuando la lectura del pin sea HIGH medira
// el tiempo que transcurre hasta que sea LOW
distance=distance*0.0001657;

// pinMode(pwPin, INPUT);

for(int i = 0; i < arraysize; i++)
{

//pulse = pulseIn(pwPin, HIGH);
rangevalue_ = distance*100; _

  • delay(10);*
  • }*

_ Serial.print("Desordenados: ");_

  • printArray(rangevalue,arraysize);*

  • isort(rangevalue,arraysize);*
    _ Serial.print("Ordenados: ");_

  • printArray(rangevalue,arraysize);*

  • modE = mode(rangevalue,arraysize);*
    _ Serial.print("La media es: ");_
    _ Serial.print(modE);_
    _ Serial.println();_

  • delay(1000);*

  • lcd.setCursor(0,0);*

  • lcd.print(distance);*
    }

/-----------Funciones------------/
//Función para imprimir las Array
void printArray(int *a, int n)
{

  • for (int i = 0; i < n; i++)*
  • {*
    _ Serial.print(a*, DEC);_
    _ Serial.print(’ ');_
    _
    }*_

_ Serial.println();_
}

//Función de clasifiación
void isort(int *a, int n)
// *a es un Array pointer function
{
_ for (int i = 1; i < n; ++i) { int j = a*; int k; for (k = i - 1; (k >= 0) && (j < a[k]); k–)
{
a[k + 1] = a[k];
}
a[k + 1] = j;
}
}*_

//Función de modo, devolviendo el modo o valor medo.
int mode(int *x,int n){
* int i = 0;*
* int count = 0;*
* int maxCount = 0;*
* int mode = 0;*
* int bimodal;*
* int prevCount = 0;*

* while(i&prevCount&count>maxCount){*
_ mode=x*;
maxCount=count;
bimodal=0;
}
if(count==0){
i++;
}
if(count==maxCount){//Si el conjunto de datos tiene 2 o mas modos*

* bimodal=1;
}
if(mode==0||bimodal==1){//Volver al valor medio si no hay modo*

* mode=x[(n/2)];
}
return mode;
}
[/size][/size][/quote]*_

Buenas!

El fallo reside en el loop. Estás tomando valores una vez y replicándolos 9. Fíjate cómo la toma de medidas está fuera del bucle for, cuando lo que debes hacer es tomar una medida y guardarla en la matriz y así sucesivamente (no tomar una medida y guardarla en 9 posiciones).

void loop()
{

digitalWrite(trigger,LOW);
delayMicroseconds(5);
// Comenzamos las mediciones
// Enviamos una señal activando la salida trigger durante 10 microsegundos
digitalWrite(trigger,HIGH);
delayMicroseconds(10);
digitalWrite(trigger,LOW);
// Adquirimos los datos y convertimos la medida a metros
distance=pulseIn(echo,HIGH); // Medimos el ancho del pulso
// (Cuando la lectura del pin sea HIGH medira
// el tiempo que transcurre hasta que sea LOW
distance=distance*0.0001657;

// pinMode(pwPin, INPUT);

for(int i = 0; i < arraysize; i++)
{

//pulse = pulseIn(pwPin, HIGH);
rangevalue = distance*100;
delay(10);
}

Sin prestarle mucha atención al programa (lo digo por si me equivoco XD) esto es lo que deberías hacer:

void loop () {

for(int i = 0; i < arraysize; i++) {

digitalWrite(trigger,LOW); //ESTO YO LO PONDRÍA EN EL SETUP. NO ES LA CAUSA DEL ERROR, PERO LAS VARIABLES SE SUELEN INICIALIZAR EN EL SETUP
delayMicroseconds(5);

// Comenzamos las mediciones
// Enviamos una señal activando la salida trigger durante 10 microsegundos

digitalWrite(trigger,HIGH);
delayMicroseconds(10);
digitalWrite(trigger,LOW);

// Adquirimos los datos y convertimos la medida a metros
distance=pulseIn(echo,HIGH); // Medimos el ancho del pulso
// (Cuando la lectura del pin sea HIGH medirá
// el tiempo que transcurre hasta que sea LOW
rangevalue _ = distance*0.0001657; //OBSERVA CÓMO CADA VALOR DE DISTANCIA SE ALMACENA DIRECTAMENTE EN UNA CELDA DEL VECTOR_

  • delay(10);*
  • }*
    //RESTO DEL CÓDIGO
    [/quote]
    PD: Soy un poco inútil con esto de citar texto XD pero espero que se entienda :slight_smile:

Impresionante Enryke!!
Acabas de darle luz a mi vida.

Por mucho que esté el fallo delante de mis narices, por mucho que me empeñe a veces no lo veo.
Gracias, gracias.
Lo he cambiado, tal como indicas y ahora calcula la mediana perfectamente.

Estos días, he estado buscando modelos de medidores ultrasónicos, y desechando los que hay en la web de RS que valen 500€, ¿Cual puede haber que tenga mayor fiabilidad que el HC-SR04?
Estoy buscando uno que tenga menos angulo de onda y que por su puesto sea mejor.

Me hablaron que había uno que era muy bueno, cuesta sobre 80€ y funciona con I2C.
Encontre el SRF08, pero no crea que se refiriesen a ese. Ya que todos los manuales dicen que es una evolución del HC-SR04 que a parte mide intensidad de la luz.

Supongo que la direfencia está en que mide la intensidad de la luz y a parte le da la medida de la distancia al Arduino, sin tener que realizar fórmulas en el cálculo.

¿Que opinas?

Hola de nuevo :):

A pesar de que parece que este post ya lo damos por zanjado, yo, por mi parte sigo a ello sin descanso.
Me explico:

Con el sensor HC-SR04, tengo problemas en las medidas. Es un sensor que oscila mucho.
Tanto marca 1,42 como al segundo 1,43. Digo 1,42 como puede ser otra medida cualquiera
Después de incluir el filtro modal en el código, este problema se solucionó pero aún asi no esta todo lo estable que quisiera.

He seguido mirando y buscando tipos de sensores de ultrasonidos y he pedido el SRF-05. Que dicen es la evolución del HC-SR04.
En definitiva parece bastante más estable.
Mide constantemente 1,42 metros.
En este punto tengo dos problemas:

1.- El sensor os dije que media una distancia a la pared e indicaba una medida de 1,42 metros. Pero la real son 1,47 metros.
2.- Si verifico la medida por la mañana indica 1,42 metros y a última hora de la tarde cuando hace más calor en la habitación hay una diferencia de 5 centímetros.

He pedido un sesor de temperatura, de forma que pueda calcular la velocidad del sonido en función de la temperatura ambiente, ya que casi tengo una diferencia de 15º en la habitación.

De esta forma no multiplico el pulso del sensor por la constante 0.0001657, sino que calculo directamente la velocidad por medio de la fórmula que se indica en esta web:

Ya os ire contando.
Espero que por lo menos no tenga oscilaciones en la medida dependiendo de la temperatura ambiente.
Lo que no se es como solucionar ese error de 5 centimetros en la medida.

Se admiten sujerencias.

Encontré la respuesta a tu problema
:
http://forum.arduino.cc/index.php/topic,115077.msg866360.html#msg866360

Te lo resumo
Si la librería que usas es la rev.2, ésta introduje un timeout de 3ms que limita la distancia a 51 cm, por que? para limitar el tiempo de ejecucion de la función pulsein() de 1000ms a 3ms y hacer programas más eficientes.

Si tienes las rev.3 introduje algunos cambios, uno incluido que no digo nada es que puedes establecer el timeout en microsegundos, aun esta en pruebas por eso no tiene ejemplo ni informacion en la web.

Con esta revisión podrás medir bien a mayores distancias.
Descarga la rev.3 y sustituye esta linea:

Ultrasonic ultrasonic(9,8); // (Trig PIN,Echo PIN)

Por esta:

Ultrasonic ultrasonic(9,8,3000); // (Trig PIN,Echo PIN, Max.TimeOut in µsec )

Luego sustituye los 3000 microsegundos con el tiempo máximo de timeout que tu necesites.

La formula a utilizar es: centímetros * 58 = Max.TimeOut

Muchas gracias Surbyte.

Todo lo que me dices, fué de las primeras modificaciones que hice cuando vi que el HC-SR04 tan sólo media 51 centimetros.
Ahora lo tengo ajustado para que mida hasta 3 metros. Si lees el post completo lo verás tu mismo.
Lo pùse para 3 metros, para poder cambiar el sensor HC-SR04 por el SFR05, ya que son exactamente iguales y las conexiones no varían.
Así puedo comparar las diferencias entre ellas.

Lo úico que busco ahora es que mida la distancia real:

Cuando lo pones a medir una distancia de 50 cn, indica 48 cn.
En distancias de 1,47 metros, indica 1,42.
Lógicamente cuanta mas distancia mayor es su error de medida. Ni que decir tiene que las pruebas las estoy haciendo contra un muro limpio de bloque sin ningún obstaculo en un radio de 2 metros.

He realizado las pruebas tanto con la librería

Ultrasonic ultrasonic(9,8,3000); // (Trig PIN,Echo PIN, Max.TimeOut in µsec )

como con la fórmula

distance=pulseIn(echo,HIGH);
distance=distance*0.0001657;

La última incorporación fué cargarme el "0.0001657" e incluir un sensor de temperatura para poder calcular la velocidad del sonido en función de la tempertura, ya que los resultados de las pruebas variaban en función de la temperatura que tuviera la habitación en ese momento.

Lo que estoy sacando en conclusión es que son sensores para pasar el rato, y lo que busco es algo más profesional.

Gracias de todas formas.
Seguiré en ello

Ahora entiendo. Para algo profesional busca un sensor ultrasónico profesional y entonces serán otros valores.
Yo he usado industrialmente uno que esta en el orden de 60 a 200 USS según sus características.
Luego lo busco y edito este post.

Luego lo busco y edito este post.

Me parece Genial!!!!
De ese modo nos das la oportunidad de probarlo.

Muy Interesante

Mira estos, son digamos accesibles por debajo de 100 USS

se podría intentar promediar los valores, o eliminar la variación de valores, aunque realmente las lecturas del sensor no van a ser nunca exactas y entre mas distancia menos exactas van a ser por la interferencia generada por los objetos en el medio y por el rebote de la misma onda.