HC-SR04 Temperatura/Humedad

Hola,
No sé si es aquí donde he de exponer mis dudas.
Si no es correcto, me lo hacen saber y lo modifico.
Gracias.

Duda sobre sensor HC-SR04.
Contexto:
Esta cableado, funciona bien y he probado también opciones con la librería “NewPing.h”.
Al final, descarte la librería mencionada y seguí usando la que tenía en proyectos anteriores (Statistics.h).
No tengo ningún problema con las lecturas. He probado todo tipo de opciones, pulso de 5 o 10us, diferentes “delay” entre medidas.
Como realmente no me interesa saber la distancia en ninguna unidad (cm,mm,etc) he usado tanto el “TimePulse” total ida+vuelta, como digamos “eco” el anterior valor/2.
Todo perfecto. Con cualquiera de los dos valores lo escalo según mis necesidades y perfecto.
Ejemplo:

NivelEscalado = map(distancia2,50,2175,255,0);

Luego con la librería “Statistics.h” añado los valores que quiera y obtengo una media.
Hasta aquí todo ok.
Ahora quiero tener presente como afecta a ese valor la temperatura y la humedad.
He hecho multitud de pruebas con diferentes valores encontrados en la web y que al final incorporo en una variable como esta:

coeficienteTEMP = ((0.606 * TEMP_EXTER)+(0.0124*HUMEDAD));

Pongo esta, pero como digo, he probado aplicándola de múltiples formas.
En fin, esta es mi duda:
Estoy tomando medidas sin ninguna variación en la distancia, recibiendo valores después de hacer medias más o menos, parecidos.
No soy ingeniero ni matemático, pero obviamente si cualquiera de las variables anteriores cambia, también lo hace el resultado de la medida de tiempo o distancia resultante.
Por tanto, ¿Cómo se hace para que, si no hay variación en la distancia, me dé siempre el mismo valor independientemente (o dependiente pero con esas condiciones) de los cambios de temperatura y humedad?
En resumen, a mismo nivel, mismo valor tanto en invierno como en verano, por ejemplo.
No sé si es lógico o incongruente lo que planteo.
Es posible que sea obvio como hacerlo, pero no doy con ello.
Gracias a todos.
Un saludo
jmarenav

Moderador: dos lineas editadas usando

Muestre el enlace donde obtuvo esta fórmula. En mi opinión, ella está equivocada.

En cuanto a la pregunta, la razón es que los valores medidos por el sensor dependen muy poco de la temperatura y la presión, por lo que simplemente no nota estos cambios.

En realidad la formula era esta:
Velocidad Sonido = 331.4+(0.606Temperatura)+(0.0124Humedad)

Pero si me dices que afectan poco, mejor lo dejo como esta que con esa precisión me valdría.
Gracias por tu respuesta.

Esa formula afecta la velocidad de sonido en diferentes ambientes.
Tu haces mediciones y durante las mediciones que cambia? La temperatura no cambia, la humedad tampoco.

Veamos.
He resumido un en Excel posibles variaciones.

Velociad de sonido: 331.4+(0.606Temperatura)+(0.0124Humedad)
Temperatura Humedad Sonido Var %
331,4 35 30 352,98 106,51
331,4 30 30 349,95 105,60
331,4 25 30 346,92 104,68
331,4 20 30 343,89 103,77
331,4 15 30 340,86 102,86
331,4 10 30 337,83 101,94
331,4 5 30 334,80 101,03
331,4 0 30 331,77 100,11
331,4 -5 30 328,74 99,20
331,4 -10 30 325,71 98,28
331,4 25 80 347,54 104,87
331,4 25 70 347,42 104,83
331,4 25 60 347,29 104,80
331,4 25 50 347,17 104,76
331,4 25 40 347,05 104,72
331,4 25 30 346,92 104,68
331,4 25 20 346,80 104,65
331,4 25 10 346,67 104,61
331,4 25 0 346,55 104,57

En los casos mas extremos hay un 5% hacia arriba o hacia abajo en las lecturas.
O sea.. tus mediciones podrian ser corregidas a lo largo de los dias cuando las condiciones ambientales cambien y la lectura del sensor este afectada por dichos cambios.

Ahora dime, donde estas midiendo con el sensor ultrasónico como para prestarle atención a esto? Acaso tienes cambios de temperatura en tu casa debido a un aire acondicionado o humidificador?

EDITO 1:
Te completo la información con esta nota.

Encontré una tema similar al tuyo donde se muestra tu problema.

Resumiendo la nota se expresa que las posibles fallas se deben a que las lecturas que ese tema se hacen usan pulseIn y que claramente no es preciso.
Sugieren usar interrupciones con algun pin dedicado a un TIMER como el 1.

Edito 2: Encontré este tutorial de cómo mejorar las lecturas del sensor

Basadas precisamente en pulsein

digitalWrite(trigPin, LOW);//setting trigger pin in LOW state
  delayMicroseconds(5);      //for 5 microseconds
 
  digitalWrite(trigPin, HIGH);  //setting trigger pin in HIGH state
  delayMicroseconds(10);       //for 10 microsecond and emits 8pulses from the transmitter and bounces back onces hit by an object
  digitalWrite(trigPin, LOW);  //after recieving the signal,setting the trigger pin to LOW state
 
  duration = pulseIn(echoPin, HIGH); //duration is a variable that starts timing once echo pin is high by using  arduino  function pulseIn()
 
  float temperature = dht.readTemperature();// temperature is the variable use to store the value of current temperature which sensors detects
 
   speedofsound = 331.3+(0.606*temperature);// Calculate speed of sound by using the given formula in m/s:
   distance = duration*(speedofsound/10000)/2; // Calculate the distance 

Supongamos que la medida sea sobre supuestos 40 cm exactos.
Aca con el excel calculé los errores que tienes

image

Surbyte,
Ante todo, gracias por tu respuesta.
Después de leer los artículos que me mencionas, definitivamente me inclino por lo que creo que sea el motivo de las variaciones, en este proceso de pruebas, y es el usar el “pulseIn”.
Estoy casi seguro que se debe a esto, pues el código es largo en el también uso una librería “pt.h” para ejecutar procesos fuera del típico delay.
Te intento poner en contexto.
Todo lo estoy haciendo en mi mesa de trabajo.
Sensor de US fijo midiendo la distancia al suelo en el que interpongo un objeto plano para hacer pruebas.
A tu primera pregunta, los cambios son forzados tanto en temperatura y humedad.
Cita:
Ahora dime, donde estas midiendo con el sensor ultrasónico como para prestarle atención a esto? Acaso tienes cambios de temperatura en tu casa debido a un aire acondicionado o humidificador?
En este momento de pruebas en mi mesa, como digo, las variaciones las fuerzo yo.
El destino final del proyecto es medir el nivel de un tanque que esta a la intemperie y que le da el sol durante la mayoría de horas del día.
En mi ubicación la diferencia de temperaturas entre estaciones en grande.
Las distancias van +- entre 1300mm vacío y 50mm lleno.
Resumo.
Cuando uno se pone a realizar un proyecto quiere, probablemente sin ser necesario, rizar el rizo.
Gracias a vuestros comentarios me han puesto los pies en la tierra y definitivamente no necesito de una precisión milimétrica, mas cuando las variaciones son bajas en 24h.
Como expuse, el valor de la distancia en unidades longitudinales me da igual. Uso, por ejemplo, un “timepulse” lo escalo 0 a 100% y listo.
Probé como ya dije con “NewPing.h” pero al final me decante por “Statistics.h”. Por medio de una rutina capturo 10,20 o 30 valores, realizo la media y listo.
Agradezco enormemente el tiempo que te has dedicado a esta consulta.
En definitiva creo que lo que mas se va a apreciar es el uso de una interrupción que para nada se me había ocurrido.
Lo voy a probar y comento las diferencias.
Un saludo y muchísimas gracias por vuestro tiempo.
El articulo Edito2:NerdyElecc es muy interesante. Gracias
juanarenav

Articulo mencionado por jremington al que he llegado desde tu cita: HC-SR04 Value variations over time.
Verdaderamente interesante.
Para nada soy un experto.
Estudie fp electronica hace unos 30 años, ahi es nada. Soy autodidacta, y en algun momento lei sobre los timers integrados.

Con lo que tenia, de verdad que me servia, pero ya me has tocado la fibra.
Con la primera lectura ya me di cuenta que no hablamos de las entradas de interrupcion.
A por este tema. Ya comentare.
Gracias

De hecho ya uso algo sobre esto en mi código:

/////// RELOJ
ISR(TIMER1_COMPA_vect)          // interrupción por igualdade de comparación en TIMER1
{
  //digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN) ^ 1);   //invierte estado del LED
  LEER_EX1 = !LEER_EX1;
  LEER_EX2 = !LEER_EX2;

}

Setup

  TCCR1A = 0;                // El registro de control A queda todo en 0
  TCCR1B = 0;                //limpia registrador
  TCNT1  = 0;                //Inicializa el temporizador
  OCR1A = 0x3D08;            // carga el registrador de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08
  TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12);   // modo CTC, prescaler de 1024: CS12 = 1 e CS10 = 1  
  TIMSK1 |= (1 << OCIE1A);  // habilita interrupción por igualdade de comparación

Creo que confundes una rutina buena como NewPing con algo que realiza justamente calculos estadisticos.
NewPing mide con microsegundos y lo hace de mucho mejor forma que PulseIn.
Mira cómo lo hace

unsigned int NewPing::ping(unsigned int max_cm_distance) {
	if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.

	if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function.

#if URM37_ENABLED == true
	#if DO_BITWISE == true
		while (!(*_echoInput & _echoBit))             // Wait for the ping echo.
	#else
		while (!digitalRead(_echoPin))                // Wait for the ping echo.
	#endif
			if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#else
	#if DO_BITWISE == true
		while (*_echoInput & _echoBit)                // Wait for the ping echo.
	#else
		while (digitalRead(_echoPin))                 // Wait for the ping echo.
	#endif
			if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#endif

	return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead.
}

y por si acaso

// ---------------------------------------------------------------------------
// Standard and timer interrupt ping method support functions (not called directly)
// ---------------------------------------------------------------------------

boolean NewPing::ping_trigger() {

Usa interrupciones.

Y a los datos reunidos por NewPing bien podrias calcularle la media, mediana o lo que gustes.
He visto a mucha gente intentando mejorar un HC-SR04 y solo uno logró buenas mediciones, pero para eso alteró el circuito de disparo del HC-SR04 y agregó una rutina con Timer.
Para hacer todo eso es mas facil comprarse un sensor de 30 o 40€ (si mal recuerdo los precios) y listo como la linea PulStar de Massa
Estos tienen sensor de temperatura incorporado y son un termino medio antes de comprar un sensor industrial de otro valor.

Hola, Gracias por la aclaración.
Volveré a utilizar esa librería.
Con eso creo que me es más que suficiente.
Muchas gracias por tu ayuda y tu tiempo.
Un saludo.