Wednesday, November 2, 2016

Moving Average Arduino

Estoy trabajando en un robot móvil controlado a través de un enlace inalámbrico de 2,4 GHz. El receptor está conectado al Arduino Uno que sirve a bordo como el controlador principal. El canal de entrada más crítico (y principal) procedente del receptor produce una señal muy ruidosa, lo que conduce a muchos cambios menores en la salida de los actuadores, aunque éstos no son necesarios. Estoy buscando bibliotecas que pueden realizar suavizado eficiente. Hay alguna señal de suavizado de las bibliotecas disponibles para el Arduino (Uno) preguntó Feb 16 14 a las 13:57 Creo que veo un montón de picos de ruido de una sola muestra en su señal ruidosa. El filtro mediano hace mejor en deshacerse de picos de ruido de una sola muestra que cualquier filtro lineal. (Es mejor que cualquier filtro de paso bajo, promedio móvil, promedio móvil ponderado, etc., en términos de su tiempo de respuesta y su capacidad para ignorar tales valores extremos de picos de ruido de una sola muestra). De hecho, hay muchas bibliotecas de suavizado de señal para el Arduino, muchas de las cuales incluyen un filtro mediano. Bibliotecas de suavizado de señales en arduino. cc: bibliotecas de suavización de señales en github: Funcionaría algo así en tu robot (La mediana de 3 requiere muy poca potencia de CPU, y por lo tanto rápida): Podrías filtrar esto digitalmente usando un valor bajo Filtro de paso: Cambie el 0.99 para cambiar la frecuencia de corte (más cerca de 1.0 es la frecuencia más baja). La expresión real para ese valor es exp (-2pif / fs) donde f es la frecuencia de corte que desea y fs es la frecuencia en la que se muestrea la información. Otro tipo de filtro digital es un filtro de eventos. Funciona bien en datos que tienen valores extremos, p. 9,9,8,10,9,25,9. Un filtro de eventos devuelve el valor más frecuente. Estadísticamente este es el modo. Los promedios estadísticos como Media, Modo etc. se pueden calcular utilizando la Biblioteca media de Arduino. Un ejemplo tomado de la página de la biblioteca de Arduino referido a: Actualmente estoy desarrollando un sistema gráfico del LCD para exhibir temperaturas, flujos, tensiones, energía y energía en un sistema de bomba de calor. El uso de un LCD gráfico significa que la mitad de mi SRAM y 75 de mi flash se han utilizado por un buffer de pantalla y cadenas. Actualmente estoy mostrando valores mínimos / máximos / promedio de energía A medianoche, cuando se restablece la figura diaria, el sistema comprueba si el consumo del día está por encima o por debajo del mínimo o máximo anterior y almacena el valor. El promedio se calcula dividiendo el consumo acumulado de energía por el número de días. Me gustaría mostrar el promedio diario durante la última semana y el mes (4 semanas por simplicidad), es decir, un promedio móvil. En la actualidad, esto implica mantener una matriz de valores para los últimos 28 días y calcular un promedio en toda la matriz de mensual y los últimos 7 días para la semana. Al principio estaba haciendo esto usando una matriz de flotadores (como la energía está en la forma 12.12kWh), pero esto estaba usando 28 4 bytes 112 bytes (5.4 de SRAM). No me importa tener un solo punto decimal de resolución, así que cambié a usar uint16t y multiplicar la cifra por 100. Esto significa que 12.12 está representado como 1212, y divido por 100 para fines de visualización. El tamaño de la matriz es ahora de 56 bytes (mucho mejor). No hay manera trivial de reducir la figura a una uint8t que puedo ver. Podría tolerar la pérdida de un lugar decimal (12.1kWh en lugar de 12.12kWh), pero el consumo es frecuentemente superior a 25.5kWh (255 es el valor más alto representado por un entero sin signo de 8 bits). El consumo nunca ha estado por debajo de 10.0kWh o por encima de 35.0kWh, así que concebiblemente podría restar 10 de las cifras almacenadas, pero sé que un día superaremos estos límites. A continuación, probé el código para empaquetar valores de 9 bits en una matriz. Esto da un rango de 0-51.2kWh y usa 32 bytes en total. Sin embargo, acceder a una matriz como ésta es bastante lento, especialmente cuando tiene que iterar sobre todos los valores para calcular un promedio. Así que mi pregunta es - hay una forma más eficiente de calcular una media móvil con tres ventanas - vida útil, 28 días y 7 días Eficiencia significa menor en términos de uso SRAM, pero sin la pena de código enorme. Puedo evitar el almacenamiento de todos los valores que se me ha preguntado 7 de marzo a las 8:32 He estado pensando y tienes razón. Así que técnicamente hace mi respuesta incorrecta. I39m invertir más tiempo y paciencia en él. Tal vez algo fuera de la caja. Le haré saber si encuentro algo. Hacemos algo como esto mucho en mi lugar de trabajo. Déjame preguntar por ahí. Perdón por la confusión. Ndash Aditya Somani Mar 8 14 at 17:15 hay una manera más eficiente de calcular una media móvil con. 28 días y 7 días. Necesitando recordar 27 días de historia. En otras palabras, en lugar de almacenar todos los detalles de cada día durante los últimos 27 días, (a) almacenar 7 o más valores de información diaria detallada para el pasado 7 o así días, y también (b) almacenar 4 o así resumieron los valores de la información total o media para cada uno de los últimos 4 semanas o más. Esta es una colección de rutinas para realizar el análisis matemático de matrices de números. Soporte de funciones actuales: Todas las funciones están completamente sobrecargadas para admitir los siguientes tipos de datos: Con la excepción de stddev (), todos devuelven el mismo tipo de datos que el array. Una matriz de valores int devuelve un solo int. Stddev () devuelve siempre un flotador. Todas las funciones excepto rollingAverage () toman dos argumentos. La primera es la matriz para trabajar. El segundo es el número de entradas en la matriz. RollingAverage () toma un tercer argumento - la nueva entrada para agregar a la matriz. Rolling average Formato: average rollingAverage (historyarray, slicecount, value) Añade valor a la matriz historyarray desplazando todos los valores en un lugar. Luego se devuelve el promedio. Formato medio: promedio medio (array, slicecount) Calcula la media de los valores en array. Slicecount es el número de entradas en la matriz. Modo Formato: modo medio (array, slicecount) Encuentra el número más común en la matriz. Máximo formato: max máximo (array, slicecount) Encuentra el valor más grande en la matriz. Formato mínimo: min mínimo (array, slicecount) Encuentra el valor más pequeño en el array. Desviación estándar Formato: desviación stddev (array, slicecount) La desviación estándar es la raíz cuadrada de la media de la suma de los cuadrados de la diferencia entre cada punto de datos y la media media de la matriz. Esta es la única función que no devuelve el mismo tipo de datos que la matriz. La desviación estándar siempre se devuelve como un flotador. Ejemplo: ShareIntro Una de las principales aplicaciones de la placa Arduino es la lectura y registro de datos de sensores. Por ejemplo uno monitorea la presión cada segundo del día. Como frecuencias de muestreo altas a menudo generan picos en los gráficos, también se quiere tener un promedio de las mediciones. Como las mediciones no son estáticas en el tiempo lo que a menudo se necesita es un promedio de funcionamiento. Éste es el promedio de un cierto período y muy valioso al hacer análisis de la tendencia. La forma más simple de un promedio de ejecución se puede hacer por el código que se basa en el promedio anterior de ejecución: Si uno no quiere utilizar matemáticas punto flotante - como esto ocupa la memoria y disminuye la velocidad - uno puede hacer lo mismo completamente en el dominio entero. La división por 256 en el código de ejemplo es un desplazamiento a la derecha 8, que es más rápido que decir división por ejemplo. 100. Esto es cierto para cada potencia de 2 como divisor y sólo uno debe tener cuidado la suma de los pesos es igual a la potencia de 2. Y por supuesto uno debe tener cuidado no hay desbordamiento intermedio (considere el uso de unsigned largo) Si necesita Un promedio de ejecución más preciso, in concreto de las últimas 10 mediciones, se necesita una matriz (o lista vinculada) para mantenerlos. Esta matriz actúa como un amortiguador circular y con cada nueva medida se elimina la más antigua. El promedio de ejecución se calcula como la suma de todos los elementos divididos por el número de elementos de la matriz. El código para el promedio de ejecución será algo como esto: Desventaja de este código es que la matriz para contener todos los valores puede llegar a ser bastante grande. Si usted tiene una medición por segundo y desea un promedio de ejecución por minuto que necesita una matriz de 60 un promedio por hora necesitaría una matriz de 3600. Eso no podría hacerse de esta manera en un Arduino, ya que sólo tiene 2 K de RAM. Sin embargo, mediante la construcción de un promedio de 2 etapas se puede abordar bastante bien (renuncia: no para todas las mediciones). En el código psuedo: Como una nueva matriz estática interna es necesaria para cada función runningAverage, esto grita para ser implementado como una clase. Biblioteca RunningAverage La biblioteca runningAverage crea una clase de la función anterior para que pueda usarse varias veces en un boceto. Desacopla la función add () y avg () para que sea un poco más flexible, p. Uno puede llamar al promedio varias veces sin agregar nada. Tenga en cuenta que cada instancia de la clase añade su propia matriz para realizar mediciones, y que esto se suma al uso de la memoria. La interfaz de la clase se mantiene lo más pequeña posible. Nota: con la versión 0.2 los nombres de los métodos se hacen más descriptivos. Uso Un pequeño bosquejo muestra cómo se puede utilizar. Un generador aleatorio se utiliza para imitar un sensor. En setup () el myRA se borra para que podamos empezar a agregar nuevos datos. En loop () primero se genera un número aleatorio y se convierte en un flotador que se agregará a myRA. A continuación, el valor de ejecución se imprime en el puerto serie. También se puede mostrar en algunos LCD o enviar a través de Ethernet, etc Cuando se añaden 300 elementos myRA se borra para empezar de nuevo. Notas Para utilizar la biblioteca, cree una carpeta en su SKETCHBOOKPATHlibaries con el nombre RunningAverage y coloque allí. h y. cpp. Opcionalmente, haga un subdirectorio de ejemplos para colocar la aplicación de ejemplo. Historia 2011-01-30: inicial versión 2011-02-28: fijo desaparecido destructor en archivo. h 2011-02-28: eliminado por defecto constructor 2012--. Añadido fillValue () refactorizado para la publicación 2014-07-03: agregó código de protección de la memoria - si la matriz interna no se puede asignar tamaño Se convierte en 0. Esto es para solucionar el problema descrito aquí - forum. arduino. cc/indextopic50473.msg1790086msg1790086 - Todo Pruebe extensivamente. Clase de la plantilla RunningAverage. h RunningAverage. cppRecently mi vecino me pagó para construir un sistema de entrada menos clave para su dormitorio. Decidí ir a la ruta económica y utilizar un botón / potenciómetro que se sienta fuera de la puerta y un Arduino en el interior que controla un servo conectado a la cerradura. Para mi habitación, pensé que sería interesante utilizar un Ping))) sensor de distancia ultrasónica en lugar del potenciómetro y perder el botón. El Ping))) sensor siguió tomando lecturas mientras mi mano se movía. Para solucionar esto decidí utilizar un filtro de media móvil, luego calcular la desviación estándar de los valores actualmente incluidos en el filtro M. A. Cuando mi mano está todavía, la desviación estándar será muy pequeña. M. A.y S. D. (Pdf) - 8220storeValue (variable) 8221 es la forma de introducir datos en la matriz, luego llamar a M. A. y S. D. No mucho de un circuito requerido Arduino039s regulador también poderes Ping))). El servo tiene su propio regulador 5v. Necesita condensadores pingDoorLocker (pdf) 8211 Como puede ver, este programa explotó un poco8230 Traté de hacer la M. A. y S. D. Código muy fácil de seguir. Algunas cosas podrían haber sido combinadas en el S. D. Y el método de la varianza, pero al principiante lo que escribí arriba es probablemente más fácil de entender puesto que sigue las ecuaciones. En cuanto al pingDoorLocker 8211 que lanzó ese código juntos muy rápidamente. Seguimiento de notas: Que probablemente fue la peor manera de hacer este proyecto8230 Pensé en algunas maneras de cómo escribir el programa que cortaría el código WAY abajo, pero este es un ejemplo sobre el uso de M. A. y S. D. Bastante mal uso de un M. A. filtro si usted me pregunta Su puerta unlocker. Puesto que puse algunas horas en la construcción de mi abrelatas de la puerta del vecino, aquí una imagen de él él didn8217t desea números en el dial del potenciómetro, así que hice el flash del LED el número que está entrando actualmente. Código para su abridor de puertas (pdf) 8211 deja un comentario si quieres esquemas / código en la parte rápida desde que el pdf pierde las pestañas.


No comments:

Post a Comment