Tabla de contenido:

QuickFFT: FFT de alta velocidad para Arduino: 3 pasos
QuickFFT: FFT de alta velocidad para Arduino: 3 pasos

Video: QuickFFT: FFT de alta velocidad para Arduino: 3 pasos

Video: QuickFFT: FFT de alta velocidad para Arduino: 3 pasos
Video: Uso de la FFT en Python 2024, Noviembre
Anonim
QuickFFT: FFT de alta velocidad para Arduino
QuickFFT: FFT de alta velocidad para Arduino

El Arduino típico tiene RAM y potencia de procesamiento limitadas, y FFT es un proceso computacionalmente intensivo. Para muchas aplicaciones en tiempo real, el único requisito es obtener la frecuencia con la amplitud máxima o necesaria para detectar picos de frecuencia.

En uno de mis instructivos, preparé un código para FFT que se puede encontrar aquí: EasyFFT

Este código pudo realizar FFT de hasta 128 muestras en Arduino nano. No es posible un número de muestra superior a este debido a la memoria limitada de Arduino. He modificado un poco la función para mejorar la velocidad y reducir el consumo de memoria. Esta modificación permite a Arduino realizar FFT cinco veces más rápido y consume casi la mitad de la memoria. Este Instructable no cubre el funcionamiento de FFT, las referencias al mismo se pueden encontrar en EasyFFT.

Paso 1: trabajar

Laboral
Laboral
Laboral
Laboral
Laboral
Laboral
Laboral
Laboral

La función típica de FFT se modifica para mejorar la velocidad con menor precisión. Como se muestra en la imagen, una señal de prueba debe multiplicarse por formas de onda sinusoidal o cosenoidal. Estos valores pueden estar entre 0 y 1, por lo que es imprescindible realizar una multiplicación flotante. en Arduino, la multiplicación flotante es lenta en comparación con las operaciones con números enteros.

En esta función, la onda seno / coseno se reemplaza por una onda cuadrada. Como tenemos que multiplicar una señal de prueba con una onda cuadrada que puede tener valor 0, 1 o -1. Debido a eso, podemos reemplazar la multiplicación flotante por una simple suma o resta de números enteros. Para Arduino, la suma o resta de enteros es alrededor de 5 veces más rápida. Esto hace que la resolución sea 5 veces más rápida.

Debido a esta modificación, ahora los valores del intervalo de frecuencia se pueden almacenar como un número entero (que antes era flotante) y obtenemos otra ventaja de un menor consumo de memoria. En Arduino Nano, int consume 2 bytes de memoria mientras que float consume 4 bytes de memoria. Debido a esta ventaja en el nuevo código, podemos realizar FFT para casi 256 muestras (anteriormente 128 muestras).

En Normal FFT necesitábamos almacenar el valor del seno para hacer una solución más rápida. En la nueva función, como ya no requerimos más valores de seno / coseno, podemos eliminarlo y ahorrar algo de memoria.

Implementación:

Implementar esta función es sencillo. Simplemente podemos copiar la función al inicio del código. Esta función se puede ejecutar usando el siguiente comando:

float f = Q_FFT (datos, 256, 100); En la función Q_FFT, datos: este término es una matriz que tiene valores de señal, el tamaño de muestra recomendado es 2, 4, 8, 32, 64, 128, 256, 512,… en adelante. si el tamaño de la muestra no pertenece a estos valores, se recortará al lado inferior más cercano de los valores. por ejemplo, si el tamaño de la muestra es 75, se llevará a cabo FFT para 64 números de muestras. El número máximo de tamaño de muestra está limitado por la RAM disponible en Arduino.

El segundo término especifica el número de muestras en una matriz y el último término es la frecuencia de muestreo en Hz.

Paso 2: Código

Esta sección explica la modificación realizada en el código EasyFFT que debe tenerse en cuenta al realizar modificaciones en el código.

1. Como se explicó antes, aquí se usan números enteros para hacer FFT. Int en Arduino es un número de 16 bits y puede contener valores de -32768 a 32768. Siempre que el valor de este int excede este rango, causa el problema. para eliminar este problema después de cada cálculo de nivel. si alguno de los valores excede 15000 matrices completas se dividirá por 100. esto evitará que el int se desborde.

2. Cálculo de la amplitud: Para calcular la amplitud, la parte real e imaginaria deben elevarse al cuadrado y se requiere la raíz cuadrada de la suma. elevar al cuadrado y la raíz cuadrada de la función toma tiempo. para acelerar el proceso, este código simplemente hará algunas de las magnitudes de las partes reales e imaginarias. Esto seguramente es menos exacto y puede llevar a conclusiones erróneas en algunos casos. puede optar por volver al método Normal para el cálculo de la magnitud, pero llevará más tiempo y también debe hacer algunos arreglos para almacenar estos números.

3. Este código no tiene un módulo para detección de picos múltiples. Simplemente elegirá el valor con amplitud máxima (excluyendo el primer número que es el desplazamiento de CC). Si necesita varios picos, puede consultar el código EasyFFT y realizar las modificaciones necesarias aquí. En ese caso, alguna matriz / variable también debe declararse como variable global.

4. La función contiene la siguiente línea:

unsigned int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

declarar las variables anteriores como una variable global (pegarlas al comienzo del código) ahorrará en algún lugar 1 milisegundo de tiempo en cada ejecución.

5. A diferencia de la función EasyFFT, donde los 5 picos superiores se almacenaron en la matriz predefinida. Esta función devolverá un valor flotante. este valor representa la frecuencia con máxima amplitud en Hz. Entonces, la representación del código se verá así.

flotar f = Q_FFT (datos, 256, 100);

6. Detección de picos: una vez que se encuentra la frecuencia con amplitud máxima, esta función utiliza una amplitud de frecuencia justo antes y después para calcular los resultados precisos. La amplitud utilizada en este cálculo también es la suma del módulo (no la raíz cuadrada de la suma de cuadrados)

si Fn es la frecuencia con amplitud máxima, entonces la frecuencia se puede calcular a partir de la siguiente fórmula.

F real = (A n-1 * Fn-1 + An-1 * Fn-1 + An-1 * Fn-1) / (An-1 + An + An + 1)

donde An es la amplitud de n la frecuencia y Fn-1 es el valor de frecuencia.

Paso 3: Resultados:

Resultados
Resultados
Resultados
Resultados

El tiempo de resolución se muestra en la comparación de la imagen anterior con EasyFFT. Velocidad de la misma que se muestra con la comparación.

Para los datos de muestra que tienen 3 ondas sinusoidales con diferentes frecuencias, se muestran. El resultado de QuickFFT se compara con la salida de Scilab. Como podemos ver en la imagen, 3 picos con amplitud máxima coinciden con la salida de Scilab. Sin embargo, la salida consiste en mucho ruido, que puede ser engañoso para algunas aplicaciones. Por lo tanto, se recomienda verificar el código correctamente antes de aplicarlo a su aplicación.

Espero que este código le haya resultado útil para su proyecto. En caso de cualquier consulta o sugerencia por favor comente.

Recomendado: