TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: gauchosuizo en 01 de Febrero de 2005, 07:11:00
-
hola amigos
me gustaria saber como puedo hacer para que mi Pic (18f252) me integre los datos del ADC, que recibo cada 0,5 segundos, de 0 a 60 segundos? He pensado en utilizar el metodo del trapecio (es una aproximacion de la integral), pero tengo dificultades de aplicarlo al pic. Si alguien tiene alguna idea, sera bienvenida.
Gracias
-
Hola
....
Regla del trapecio? y los decimales y todo eso, no se si vale la pena. Tanpoco se que necesitas
como para decir si vale la pena o no
.
Yo aplicaria la definicion, la suma infinita de las areas F(x) por Ax, la aproximacion la das con el Ax mas chico que puedas tomar y listo.
Es interesante el tema, haver quien hizo algo mejor.
-
Primero que nada gauchosuizo, qué lenguaje pensas usar?
Un procedimiento muy común utilizado es el siguiente:
Suponiendo que las muestras se llaman A0,A1,A2 .....AX
valor integrado= [(A0*t)+(|A1-A0| / 2)] + [(A1*t)+(|A2-A1| / 2)] + y asi con todos...
donde t es tu "delta" o tiempo de muestreo, en tu caso 0,5 seg.
Cómo implementarlo dependera de varias cosas: tiene que ser en tiempo real? o guardas las muestras y despues integras? lo haces en C o en ensamblador?
En C no es más que escribir el calculo cuidando de haber definido correctamente cada variable, en ensamblador es un poco más complicado, pero en tu caso se puede simplificar un poco: fijate que la multiplicación Ax*t es Ax*0,5 o lo que es igual Ax/2 o rotar una posición a la derecha el registro, lo mismo con el resultado de |A1-A0|/2, pero recordando que se necesita el modulo de la resta, por lo que tendras que verificar si el resultado es negativo y complementar el registro si es necesario. El resultado seguramente sea una variable de más de un byte, por lo que tendras que erreglarte tambien con eso en ensamblador.
-
hola gente
al tema este lo voy a solucionar de la siguiente manera:
int16 avg(int16 oldVal, int16 newVal, int8 sampleNo)
{
return = oldVal + (newVal-oldVal)/sampleNo;
}
Asi se inicializan las variables:
oldVal = 0;
oldVal = avg(oldVal, 100, 1);
oldVal = avg(oldVal, 120, 2);
oldVal = avg(oldVal, 140, 3);
Integrieren no es lo que yo realmente queria hacer, sino mas bien una especie de filtro que me de la media.
Aloha
-
Si solo quieres la media suma todo y divide por el numero de muestras, si lo haces muestra a muestra suma la siguiente a la media actual y divide por dos.
Si realmente quieres integrar utiliza un metodo numerico de integracion,
por ejemplo un Newton-cotes cerrado que para eso esta.



-
Escrito originalmente por telekitor
si lo haces muestra a muestra suma la siguiente a la media actual y divide por dos.
Hola amigos!!
simplemente quería matizar esta respuesta, porque creo que no es correcta (salvo que yo no haya entendido bien) . Para obtener la media, conocida la media anterior al añadirle una nueva muestra, debes llevar un contador de muestras, y entonces, efectuar:
Mn=media actual;
Ma=media anterior;
Cm=contador de muestras;
Nm=nueva muestra;
y la media actual se calculará:
Mn = [Ma*Cm + Nm]/(Cm +1)
De hacerlo como propone telekeitor, se le estaría dando a la nueva muestra el mismo peso que a la media anterior, que puede ser resultado de un número muy grande de muestras, y por lo tanto debe tener más peso. Esto provocaría fallos en el caso de que encontremos con una muestra errónea o de valor fuera de rango, que provocaría que su influencia fuese tan fuerte como la de todo el conjunto de muestras que llevamos analizadas.
Sólo quería contar éso. Espero haberme expresado correctamente. Un saludo.
-
Efectivamente, akydes, con el método de Telekitor, la ponderación no es la misma para todas las muestras.
La forma correcta es la que tú pones, aunque lo más cómodo es sumar todas las muestras y al final dividir por el número de muestras.
-
Escrito originalmente por nocturno66
aunque lo más cómodo es sumar todas las muestras y al final dividir por el número de muestras.
tienes razón, nocturno, pero ten en cuenta que, cuando se desea ir calculando la media "en tiempo real", ésta es la forma más sencilla, puesto que la de sumar todas las muestras implica tener que esperar a obtenerlas todas, con el tiempo que ello supone, además implica la necesidad de conocer sus valores, con lo cual tendrías que declarar arrays que podrían ser muy largos, consumiendo de tal forma una cantidad de RAM de la que puedes no disponer.
Haciéndolo así, puedes hacerlo de forma contínua manteniendo una "memoria" tan sólo del número de muestras (contador de muestras) y media anterior; 2 variables frente a todo el vector que supondría hacerlo en atacadas de N muestras.
El valor medio definitivo resulta el mismo, y los pesos de las muestras vienen a ser también los mismos.
Un saludo a todos!!
-
Yo coincido con lo que dice Akydes_, lo mejor es ir haciendo la media en tiempo real, yo construí una estación meteorológica y sacaba la media diaria de todas las mediciones y lo hacía con esa fórmula (tomaba medidas dos veces cada segundo), imaginaros si hay que esperar y sumar todas las muestras (a lo largo de 24h!!), el pic no tiene tanta memoria.
Corroboro que de esta forma se obtiene una media muy precisa, tengo el cacharro funcionando desde hace ya algún tiempo y va realmente bien, es bastante fiable.
Un saludo.
-
Sí claro, si la necesidad es ir sacando media en tiempo real, no es válido esperar hasta el final para hacer los cálculos. En ese caso el otro procedimiento que has descrito sería el más adecuado.
De todas formas, nunca dije que hubiera que guardar en un array todas las muestras. Es suficiente con guardar en una variable el valor acumulado de su suma y en otra variable el contador de muestras.
Aunque, ahora que lo dices, el guardar las muestras en un array permitiría hacer un cálculo de media móvil. Imagina que necesitas leer siempre el valor medio de 20 muestras, pero quieres que las muestras antiguas vayan siendo renovadas por muestras nuevas a medida que va pasando el tiempo. Si vas haciendo esos cambios en los valores del array, conseguirás la media móvil sobre 20 muestras.