Concurso de fotografía AM

Temática: «Una panorámica de tu acuario».
Ya esta abierto el plazo para presentar fotografías.

Más info
image01

¿Aún no conoces AMA?

Hazte socio de Acuariofilia Madrid Asociación.
CERRADO EL PLAZO DE INSCRIPCIÓN

Más info
image01

Atlas de peces de AM

¡Hemos alcanzado las 800 fichas! Visita nuestro atlas de peces actualizado.

Más info
image01

Cardúmenes y sociabilidad

Nueva actualización de la tabla con una extensa relación de peces, donde podrás conocer qué entorno necesita cada especie, su sociabilidad y si convive o no en cardumen. ¡Pasa a descubrirla!

Mas info
image01
Calcular moda (sensor ultrasonidos HC-SR04)
Respuestas: 18    Visitas: 6312
#1
Hola!
Por seguridad y evitar un desbordamiento o un vaciado excesivo en caso de que se atasque la sonda de nivel por alguna hoja de una planta, puse un sistema de ultrasonidos que mide la altura del agua. El problema es que los sensores de ultrasonidos de vez en cuando dan datos absurdos y más en un acuario donde el sonido pude rebotar o cambia la forma de la superficie del agua constantemente. Es por eso, que había pensando en recoger los datos es un vector (con Array) y luego sacar la moda del conjunto de datos. He intentado escribir yo esa parte del codigo para calcular la moda y buscar codigos por la web pero no acabo de encontrar algo que funcione realmente bien. ¿Se os ocurre alguna forma?
Gracias
#2
No creo que tenga sentido usar la moda.
La moda sólo tiene sentido para un conjunto de números discretos, en números continuos no tiene sentido, tendrás que recurrir a la media o a la media móvil.

Más explicaciones:

Conjunto de datos discretos: [2 4 5 7 4 3 1 4 7 8 4]
Moda: 4.

Conjunto de datos contínuos: [7 7.1 6.9 6.8 6.7 6.5 2 6.3 6.2]
Moda: no existe, al ser continuos no hay dos números iguales.

Una media móvil sería, por ejemplo, tomar la media de los últimos 20 datos recogidos.
#3
De acuerdo con Dudo.

En un proyecto parecido usé la media y me fue bien.

Yo el ultrasonido lo usé con "sólido" y no era demasiado preciso, por lo que creo que con agua te va a costar mas...

Creo que para lo que quieres es mejor poner una segunda sonda de nivel
#4
Qué interesante. Os leo -good.gif
#5
En el caso que lo voy a aplicar, con que me de números enteros me vale pues no necesito una altura de agua concreta sino encender la alarma y apagar el sistema de llenado cuando el nivel varié considerablemente de lo normal. Por tanto con int() puedo pasar la matriz a números enteros. El problema es que el sensor suele dar un vector (suponiendo, por ejemplo, que la distancia real es de 8) de [8 8 7 8 9 21]. Si hago la media, con datos tan dispersos, el valor no tendrá sentido. También podría ir descartando datos si comparo una medición la anterior y las elimino en el caso de que difieran en, por ejemplo, 1cm; pero seguiría teniendo el 7 y el 9 como datos erróneos que sería poco recomendable incluir en la media porque ya se que el sensor me da el dato bueno de vez en cuando. Por tanto, el valor estadístico que yo creo que mejor puede funcionar es la moda.

Juanma, estoy de acuerdo contigo... Estos sensores aunque dicen que tienen un error de +/-3mm, en condiciones donde el sonido puede rebotar de distinta forma o tener interferencias, puede dejar que desear. Pero bueno, como medida preventiva espero poder usarlo.
#6
Busca código en c en general, no hace falta que lo busques exclusivo para arduino.
#7
(05-06-2017, 01:31 PM)albertoespinosa escribió: En el caso que lo voy a aplicar, con que me de números enteros me vale pues no necesito una altura de agua concreta sino encender la alarma y apagar el sistema de llenado cuando el nivel varié considerablemente de lo normal. Por tanto con int() puedo pasar la matriz a números enteros. El problema es que el sensor suele dar un vector (suponiendo, por ejemplo, que la distancia real es de 8) de [8 8 7 8 9 21]. Si hago la media, con datos tan dispersos, el valor no tendrá sentido. También podría ir descartando datos si comparo una medición la anterior y las elimino en el caso de que difieran en, por ejemplo, 1cm; pero seguiría teniendo el 7 y el 9 como datos erróneos que sería poco recomendable incluir en la media porque ya se que el sensor me da el dato bueno de vez en cuando. Por tanto, el valor estadístico que yo creo que mejor puede funcionar es la moda.

Juanma, estoy de acuerdo contigo... Estos sensores aunque dicen que tienen un error de +/-3mm, en condiciones donde el sonido puede rebotar de distinta forma o tener interferencias, puede dejar que desear. Pero bueno, como medida preventiva espero poder usarlo.

Pero ten cuidado porque una mala lectura o rotura del sensor te puede jugar una mala pasada y provocar precisamente lo que quieres evitar.

Lo que creo que es más fiable es que hagas una tirada de lecturas y te quedes con la menor para evitar el desbordamiento.

Pero como te digo, por mi experiencia no pondría un sensor de este tipo a "cuidar" algo tan delicado
#8
Yo creo que el parámetro estadístico que mejor te puede servir es la Mediana, este valor será el valor central en el conjunto de datos recopilados. La mediana no se ve afectada por la dispersión de los datos y la media como bien has dicho sí, sin embargo, cuando la dispersión es baja o nula suelen coincidir. Otro aspecto que creo que deberías tener en cuenta es que con int vas a meter un valor entero, para pasar la matriz a enteros realmente lo que tienes que buscar es un comando que te devuelva la parte entera de cada coeficiente de la matriz, no se cual es pero creo recordar que hay uno.
#9
Estoy de acuerdo con Dudo si tienes una moda muy irregular te puede dar fallo
por ejemplo en 10,4,5,18,4,10,4, la moda (4) no tiene nada que ver con lo que buscas, si tuvieras los niveles mas o menos iguales o con un rango muy próximo podría valerte pero yo no me arriesgaría.
#10
A nivel industrial, no he encontrado sondas de ultrasonidos ni laser que funcionen bien con agua, microondas guiadas si pero son caras, y de lo que he usado capacitivas para valores analogicos y conductivas para digitales son las que mejor van,
#11
El sensor proporciona mayor numero de mediciones correctas que incorrectas por lo que en un principio supongo que la moda no puede fallar. En el caso de que como decís, lleguen a producirse valores de moda igual a la del valor correcto, se podría llegar incluso a hacer la moda de la moda de las matrices. Con la mediana puede que también funcione pero siempre será mejor desechar los valores incorrectos directamente (aunque probaré tambien a buscar codigo y a ver que sale). Iré publicando aquí los avances que vaya haciendo.

(05-06-2017, 08:00 PM)JIgnacio escribió: A nivel industrial, no he encontrado sondas de ultrasonidos ni laser que funcionen bien con agua, microondas guiadas si pero son caras, y de lo que he usado capacitivas para valores analogicos y conductivas para digitales son las que mejor van,

Sabes de alguna capacitiva de buen precio y fiable? Gracias
#12
Fiables 100% pero caras, por encima de 100€, algunas muy muy por encima, ya dije que a nivel industrial, IFM electrónic, vega, Endres Hauser.

Es un tema de la tecnología usada en la medición, el agua no rebota de manera lineal ni las ondas ni la luz,

Seguro que hay sondas económicas capacitivas, y más aún conductivas. Pero no sabría recomendarte alguna en concreto.
#13
Finalmente lo he conseguido:

Cita:#include <Average.h>


const int trigger=51;
const int echo=53;
float distance;
int num;
// Reservamos espacio para 10 entradas.
Average<float> ave(10);


void setup() {
Serial.begin(9600);
//definimos los pines del sensor de ultrasonidos
pinMode(trigger,OUTPUT);
pinMode(echo,INPUT);
//Esperamos a que se establezca conexión.
delay(500);
}

void loop() {
// Variables para almacenar valores maximos y minimos
int minat = 0;
int maxat = 0;

// establecemos un bucle para llenar la matriz de datos de ave (10 datos). PONGO 15 PORQUE ME SALÍA UN 0 ENTRE CADA MEDICION
for (int i = 0; i < 15; i++) {
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 medirá
// el tiempo que transcurre hasta que sea LOW
int num= distance/58;//58uS/cm al objeto si consideramos el tiempo de la onda entre la ida y la vuelta. Los datos se almacenan en el buffer
if (num>0) {ave.push(num);//DESCARTAMOS LOS VALORES QUE SON 0
Serial.print(num);
Serial.print(" ");}
}
Serial.println();

// Mostramos los datos estadísticos
Serial.print("Media: "); Serial.println(ave.mean());
Serial.print("Moda: "); Serial.println(ave.mode());
Serial.print("Max: "); Serial.println(ave.maximum(&maxat));
Serial.print(" at: "); Serial.println(maxat);//indice del valor máximo
Serial.print("Min: "); Serial.println(ave.minimum(&minat));
Serial.print(" at: "); Serial.println(minat);//indice del valor mínimo
Serial.print("Desv.estan: "); Serial.println(ave.stddev());
//repetimos cada 10 segundos el proceso
delay(1000);
}

La libreria usada es esta: https://github.com/MajenkoLibraries/Average Una librería muy interesante para sacar parámetros estadísticos pero de la que hay muy poca información

Nota: El programa mide la distancia en número enteros.

Aquí un ejemplo del Monitor Serial con el sketch funcionando:

[Imagen: 8wmux1.png]

Vemos que la moda da un valor constante
#14
¿Son los valores reales o son ejemplos?
#15
Son los reales

Usuarios navegando en este tema: 5 invitado(s)


Salto de foro: