Necesito asignar un ADC de 10 bits, es decir, [0-1023] a un rango [1-100]. La fórmula de mapeo en sí es la directa "y=(xa)/(ba)*(dc)+c" para mapear x en [ab] a y en [cd].
La entrada x se calcula como el promedio de, por ejemplo, 1000 lecturas de ADC.
Mi problema es este. La entrada a ADC es un potenciómetro y necesito calcular x SOLAMENTE cuando el potenciómetro está estacionario. ¿Cómo detectas esto? La forma en que lo estoy haciendo actualmente es leer conjuntos de 1000 valores ADC (en un temporizador), calcular su promedio y comparar el "promedio actual" con el "promedio anterior". Si "promedio actual - promedio anterior" es algo "+-delta", asumo que el potenciómetro está estacionario y hago el cálculo.
¿Hay una mejor manera de hacer esto?
Editar: para proporcionar más datos;
Esto es 'prueba de hipótesis en presencia de ruido'.
Cuando estamos probando hipótesis, definimos un par de condiciones entre las que queremos discriminar, luego definimos una prueba para hacerlo mejor.
Ha definido una condición 'es estacionario' y una prueba |(current_avg - before_avg)| <delta. Implícito en esa definición hay otras dos condiciones, subir y bajar.
Si bien la definición de 'es estacionario' no está bien definida, si aplicamos ingeniería inversa a la prueba que ideó para averiguar qué significa realmente, el cambio en la posición promedio entre los primeros 1000 y los siguientes 1000 de una muestra larga de 2000 de posiciones, encontramos que es algo bastante razonable de hacer.
El promedio de 1000 muestras es la mejor manera de calcular una posición promedio, si asumimos que el ruido en cada muestra es independiente. También es rápido, usa pocos recursos, es fácil de entender y usa poca memoria (no necesita almacenar todas las entradas).
La diferencia entre el primer y el segundo set te da la mejor estimación de la velocidad media del bote durante ese tiempo.
Ahora considere este caso de prueba. Para las primeras 1000 muestras, el bote sube rápidamente, para las siguientes 1000 baja rápidamente. El movimiento medio durante ese período, calculado por su estimador, será cero.
¿Está contento de que esta condición se detecte como estacionaria? Si no, entonces tenemos que cambiar nuestra definición de estacionario. Según tu comentario, no estás contento con algo. ¿Pero que?
Como puede ver, el problema no está en la prueba en sí, sino en (a) su pobre definición de lo que significa 'estacionario' y (b) su pobre definición de lo que encuentra insatisfactorio sobre el desempeño de la presente prueba.
La prueba que ha definido es la prueba más razonable que existe para detectar la velocidad promedio en presencia de ruido. Si esto funciona bien con la física del mundo real y el comportamiento del usuario es otra cuestión.
Si encuentra que realmente necesita detectar la aceleración, para mejorarla en su caso, entonces es bastante fácil tomar tres muestras promediadas sucesivas, calcular ambos deltas y luego calcular el delta-delta.
Si encuentra que un cambio de tamaño promedio, para cambiar la velocidad a la que puede detectar cambios, funciona mejor, entonces hágalo.
Existen otras alternativas que ponen a prueba diferentes hipótesis. El primero sería calcular dos medias de ejecución con diferentes constantes de tiempo. Este es un filtro común para usar como detector de bordes en el procesamiento de imágenes, pero también detectará "bordes" en datos unidimensionales. Como los filtros son recursivos, esto es bastante barato de implementar. Sin embargo, tendría que ajustar las dos constantes de tiempo a su situación, entonces, ¿cómo podría ajustarlas mejor que la única constante de tiempo de su probador actual?
El segundo es hacer una FFT de sus muestras. Luego puede comparar la energía en el contenedor de CC (cantidad de estacionario) con la energía en los contenedores de baja frecuencia (cantidad de movimiento, aceleración, cambio de aceleración...) mientras descarta la energía en los contenedores de alta frecuencia (ruido de lectura) . Pero eso necesita una cantidad significativa de memoria y poder de procesamiento, y parece una exageración.
Un tercero, basado en su comentario acerca de que la latencia es el problema, sería estimar simultáneamente la posición yla pendiente de la línea por regresión lineal. Hay una fórmula recursiva para esto, por lo que es relativamente eficiente calcular en tiempo real sin más memoria. Esto le permitiría 'corregir' el retraso en la recopilación de datos extrapolando ambas estimaciones para obtener la posición promediada 'ahora'. Tenga en cuenta que la regresión lineal puede tener problemas de rango dinámico si se realiza para grandes conjuntos de datos, y como está utilizando aritmética de enteros, debe pensar detenidamente sobre la implementación. Una forma de mejorar las cosas sería diezmar y ejecutar la regresión lineal a una frecuencia de muestreo mucho más baja, más consistente con la velocidad a la que se mueve el bote del mundo real y el tiempo de respuesta que desea que tenga el programa.
Promediar hace algunas cosas; y hay mejores maneras.
Actúa como un primer filtro de paso bajo, donde un filtro ponderado puede tener el mismo ancho de banda de ruido con faldas más pronunciadas y un retraso de grupo más bajo (latencia) al igual que los filtros activos.
Puede causar errores de aliasing si las señales exceden la frecuencia de Nyquist antes de promediar, por lo que se necesita un poco de filtrado, pero un filtro de pared de ladrillo de >=5to orden es mejor para una latencia baja, que es esencialmente valores de ponderación para promediar.
Si espera a que esté inactivo y el potenciómetro tiene un ruido de oscilación debido a la vibración, agregará una latencia excesiva.
Si diseña un promedio ponderado continuo diferente, puede optimizar el retraso de grupo y el error de movimiento utilizando parámetros como un filtro de Kalman. Esto se utiliza en GPS y otros sensores de posición de movimiento, velocidad y aceleración.
6b. ... como @Neil_UK sugirió que puede hacer una FFT en los valores (o exportar y analizar), entonces podría usar un filtro coincidente en la señal fundamental (tasa de respuesta 10 ~ 90% = tR = 0.35 / f-3dB) en orden para rechazar el ruido usando valores de ponderación en promedios itinerantes.
Dejo el algoritmo de diezmado para que otros lo describan, que es álgebra básica.
PD: usaría un codificador de cuadratura incremental con retenes en lugar de un potenciómetro, para esta aplicación como se usa en los sistemas modernos.
tubo
RamanathanR
0___________