Tabla de contenido:

Promedio de ejecución para sus proyectos de microcontroladores: 6 pasos
Promedio de ejecución para sus proyectos de microcontroladores: 6 pasos

Video: Promedio de ejecución para sus proyectos de microcontroladores: 6 pasos

Video: Promedio de ejecución para sus proyectos de microcontroladores: 6 pasos
Video: analisis de libro Proyectos practicos con PSoC5LP microcontroladores avanzados 2024, Noviembre
Anonim
Promedio de ejecución para sus proyectos de microcontroladores
Promedio de ejecución para sus proyectos de microcontroladores

En este instructivo, explicaré qué es un promedio móvil y por qué debería preocuparse por él, así como también le mostraré cómo debe implementarse para obtener la máxima eficiencia computacional (no se preocupe por la complejidad, es muy simple de entender y lo haré proporcione una biblioteca fácil de usar para sus proyectos arduino también:)

La media móvil, también conocida como media móvil, media móvil o media móvil, es un término que se utiliza para describir el valor medio de los últimos N valores en series de datos. Puede calcularse como promedio normal o puede usar un truco para que tenga un impacto mínimo en el rendimiento de su código.

Paso 1: Caso de uso: Suavizar las medidas de ADC

Caso de uso: suavizar las medidas de ADC
Caso de uso: suavizar las medidas de ADC

Arduino tiene un ADC decente de 10 bits con muy poco ruido. Cuando se mide un valor en un sensor como un potenciómetro, fotorresistor u otros componentes de alto ruido, es difícil confiar en que la medición sea correcta.

Una solución es tomar varias medidas cada vez que desee leer su sensor y promediarlas. En algunos casos, esta es una solución viable, pero no siempre. Si quisiera leer ADC 1000 veces por segundo, tendría que hacer 10 000 si tomara un promedio de 10 mediciones. Una gran pérdida de tiempo de cálculo.

Mi solución propuesta es tomar medidas 1000 veces por segundo, actualizar el promedio móvil cada vez y usarlo como valor actual. Este método introduce algo de latencia pero reduce la complejidad computacional de su aplicación, lo que le brinda mucho más tiempo para el procesamiento adicional.

En la imagen de arriba utilicé el promedio móvil de las últimas 32 mediciones. Verá que este método no es 100% a prueba de fallas, pero mejora la precisión significativamente (no es peor que promediar 32 muestras cada vez). Si quisiera calcular un promedio de 32 mediciones cada vez, ¡eso tomaría más de 0.25 ms en Arduino UNO solo para las mediciones!

Paso 2: Caso de uso: medición del componente de CC de la señal del micrófono

Caso de uso: medición del componente CC de la señal del micrófono
Caso de uso: medición del componente CC de la señal del micrófono
Caso de uso: medición del componente CC de la señal del micrófono
Caso de uso: medición del componente CC de la señal del micrófono
Caso de uso: medición del componente CC de la señal del micrófono
Caso de uso: medición del componente CC de la señal del micrófono

Arduino puede medir voltajes entre 0 y Vcc (normalmente 5 V). La señal de audio es completamente AC y si desea medirla en un microcontrolador, debe desviarla alrededor de 1/2 Vcc. En un proyecto de Arduino UNO, eso significaría aproximadamente 2,5 V (CC) + señal de audio (CA). Cuando se usa un ADC de 10 bits y una fuente de alimentación de 5 V, la polarización de 2.5 V debería ser igual a la medida de 512. Entonces, para obtener un valor de CA de la señal, se debe restar 512 de la medición del ADC y eso es todo, ¿verdad?

En un mundo ideal, eso sería cierto. Desafortunadamente, la vida real es más complicada y nuestro sesgo de señal tiende a desviarse. Es muy común el ruido de 50 Hz (60 Hz si vive en EE. UU.) De la red eléctrica. Por lo general, no es demasiado problemático, pero es bueno saber que existe. Más problemático es la deriva lineal del calentamiento de componentes. Establece cuidadosamente la corrección de compensación de CC al inicio y se aleja lentamente a medida que se ejecuta la aplicación.

Ilustraré este problema con un detector de ritmos (de música). Configura la eliminación de sesgos y los ritmos son claros (imagen 2). Después de un tiempo, los movimientos de polarización de CC y los latidos son apenas perceptibles para el microcontrolador (imagen 3). El algoritmo de detección de latidos se explorará en profundidad en un futuro instructable, ya que excede el alcance de este artículo.

Afortunadamente, existe una manera de seguir calculando constantemente la compensación de CC del audio. No sorprenderá que el promedio corriente, tema de este instructable, proporcione una solución.

Sabemos que el valor promedio de cualquier señal de CA es 0. Con este conocimiento podemos deducir que el valor promedio de la señal de CA + CC es su sesgo de CC. Para eliminarlo, podemos tomar un promedio móvil de los últimos valores y restarlo de la lectura actual de ADC. Tenga en cuenta que debe utilizar un promedio móvil lo suficientemente largo. Para el audio, una décima de segundo (el número de muestras depende de su frecuencia de muestreo) debería ser suficiente, pero sepa que los promedios más largos funcionan mejor. En la primera imagen, puede ver un ejemplo de cálculo de sesgo de CC real con un promedio de 64 elementos a una frecuencia de muestreo de 1 kHz (menos de lo que recomendé, pero aún funciona).

Paso 3: cálculo

Cálculo
Cálculo

Puede imaginarse el promedio de ejecución como el peso promedio de las personas en la sala de espera del médico. El doctor termina de examinar a un paciente y simultáneamente uno nuevo entra en la sala de espera.

Para averiguar el peso promedio de todos los pacientes en espera en la sala de espera, la enfermera podría preguntarle a cada paciente sobre su peso, sumar esos números y dividir por el número de pacientes. Cada vez que el médico acepta un nuevo paciente, la enfermera repite todo el proceso.

Es posible que esté pensando: "Esto no suena demasiado eficiente … Debe haber una mejor manera de hacer esto". Y estarías en lo cierto.

Para optimizar este proceso, la enfermera podría mantener un registro del peso total del grupo actual de pacientes. Una vez que el médico llama al nuevo paciente, la enfermera le pregunta sobre su peso, lo resta del total del grupo y lo deja ir. Luego, la enfermera le preguntaba al paciente que acababa de entrar a la sala de espera sobre su peso y lo sumaba al total. El peso promedio de los pacientes después de cada turno sería la suma de pesos dividida por el número de pacientes (sí, igual que antes, pero ahora la enfermera solo preguntó a dos personas sobre su peso en lugar de a todos). Me doy cuenta de que este párrafo puede haber sido un poco confuso, así que consulte la ilustración anterior para obtener más claridad (o haga preguntas en los comentarios).

Pero incluso si no encuentra confuso el último párrafo, es posible que tenga preguntas como qué debería estar en el acumulador al principio, ¿cómo coloco lo que acabo de leer en un código C real? Eso se abordará en el siguiente paso, donde también obtendrá mi código fuente.

Paso 4: el código

El código
El código

Para calcular el promedio móvil, primero necesita una forma de almacenar los últimos N valores. podría tener una matriz con N elementos y mover todo el contenido un lugar cada vez que agregue un elemento (no haga esto), o podría sobrescribir un elemento antiguo y ajustar el puntero al siguiente elemento para descartarlo (haga esto:)

El acumulador debe comenzar inicializado a 0, lo mismo ocurre con todos los elementos en la línea de retardo. En otro caso, su promedio móvil siempre será incorrecto. Verá que delayLine_init se encarga de inicializar la línea de delay, usted debe ocuparse del acumulador.

agregar un elemento a la línea de retardo es tan fácil como disminuir el índice del elemento más nuevo en 1, asegurándose de que no señale el lado de la matriz de líneas de retardo. después de disminuir el índice cuando es 0, se repetirá hasta 255 (porque es un entero sin signo de 8 bits). El operador de módulo (%) con el tamaño de la matriz de líneas de retardo asegurará que el índice apunte a un elemento válido.

Calcular un promedio móvil debería ser fácil de entender si siguió mi analogía en el paso anterior. Reste el elemento más antiguo del acumulador, agregue el valor más nuevo al acumulador, empuje el valor más nuevo a la línea de retardo, devuelva el acumulador dividido por el número de elementos.

Fácil, ¿verdad?

No dude en experimentar con el código adjunto para comprender mejor cómo funciona todo esto. Tal como está actualmente, arduino lee el valor analógico en el pin analógico A0 e imprime "[valor ADC], [promedio corriente]" en el puerto serie a una velocidad de 115200 baudios. Si abre el trazador serial de arduino con la velocidad de transmisión correcta, verá dos líneas: valor ADC (azul) y valor suavizado (rojo).

Paso 5: Extras

Extras
Extras

Hay algunas cosas que no necesariamente necesita saber para usar el promedio móvil en su proyecto, pero no estará de más saberlo.

retraso: empezaré hablando de la ilustración de este paso. Notará que el promedio de ejecución de más elementos introduce un mayor retraso. Si su tiempo de respuesta al cambio de valor es crítico, es posible que desee utilizar un promedio móvil más corto o aumentar la frecuencia de muestreo (medir con más frecuencia).

Hacia adelante.

inicialización: cuando hablé sobre la inicialización de elementos de retardo y acumulador, dije que debería inicializarlos todos a 0. Alternativamente, podría inicializar la línea de retardo a lo que desee, pero el acumulador debería comenzar como una suma de los N elementos más nuevos en la línea de retardo (donde N es el número de elementos en su promedio móvil). Si el acumulador arranca con cualquier otro valor, el promedio calculado será incorrecto, ya sea demasiado bajo o demasiado alto, siempre en la misma cantidad (asumiendo las mismas condiciones iniciales). Le sugiero que intente aprender por qué esto es así mediante el uso de una "simulación de lápiz y papel".

tamaño del acumulador: también debe tener en cuenta que el acumulador debe ser lo suficientemente grande para almacenar la suma de todos los elementos en la línea de retardo si todos son positivos o negativos máx. Prácticamente, eso significa que el acumulador debe ser un tipo de datos mayor que los elementos de la línea de retardo y estar firmado, si los elementos de la línea de retardo están firmados.

truco: las líneas de retardo largas ocupan mucha memoria. Eso puede convertirse rápidamente en un problema. Si tiene mucha memoria restringida y no le importa mucho la precisión, puede aproximar el promedio de ejecución omitiendo el retardo por completo y haciendo esto en su lugar: reste 1 / N * acumulador del acumulador y agregue un nuevo valor (en el ejemplo de 8 promedio de ejecución larga: acumulador = acumulador * 7/8 + newValue). Este método da un resultado incorrecto, pero es un método decente para calcular el promedio móvil cuando se está quedando sin memoria.

lingüística: "promedio móvil / promedio" se usa típicamente cuando se refiere al promedio en tiempo real, mientras que "promedio móvil / promedio" generalmente significa que el algoritmo se está ejecutando en un conjunto de datos estáticos como una hoja de cálculo de Excel.

Paso 6: Conclusión

Espero que este instructivo sea lo suficientemente fácil de entender y que te ayude en tus proyectos futuros. No dude en publicar preguntas en los comentarios a continuación si hay algo que no esté claro.

Recomendado: