Laboratorio de Procesamiento Digital de Señales
Docente: Ing. Roger Guachalla Narváez
[email protected]
PRACTICA 08: FFT con Arduino 1. Objetivos: Adquirir datos mediante el conversor análogo/digital para su posterior procesamiento con la librería FFT para Arduino y la transferencia transferencia de resultados por por puerto serial Armar un generador de funciones con la t arjeta Arduino con componentes discretos (resistencias)
2. El algoritmo FFT (Fast Fourier Transform) Transform) La transformada rápida de Fourier es simplemente un algoritmo rápido para la evaluación numérica de integrales de Fourier desarrollado en los laboratorios de IBM, y su importancia radica en la rapidez de cálculo conseguida, en varios tipos de aplicaciones: ecualización y filtrado en equipos de audio/vídeo en tiempo real, comunicaciones, etc. La diferencia de velocidad de cálculo entre la tradicional transformada discreta DFT y la FFT aumenta según aumenta el número de muestras a analizar, según se puede apreciar en la gráfica, ya que mientras una aumenta el número de operaciones necesarias para la resolución de forma exponencial, la otra lo hace de forma prácticamente lineal.
Velocidad FFT es un algoritmo muy eficiente para el cálculo de la DFT.
¿Cuán rápida es la FFT comparada con la DFT? Para la DFT se requiere realizar Para la FFT solamente:
operaciones Ecuación 1.
Por ejemplo para 1024 muestras, la DFT requiere 10242 = 1 048 576 operaciones, mientras que la FFT necesita solamente operaciones. Esto significa que para un número de 1024 muestras, la FFT es 102.4 veces más rápida que la DFT. Para números de muestras mayores la ventaja en velocidad se incrementa. Si tomamos 4096 muestras, la FFT es 340 veces más rápida.
3. Librería FFT para Arduino La librería FFT para Arduino es una implementación estándar del algoritmo d e FFT que opera sólo con datos re ales. Puede operar con hasta 256 datos de 16 bits con una actualización de 7mseg. Se puede configurar para trabajar con grupos desde 16 hasta 256 datos, tiene varias funciones de salida para 16 bit lineal, 8 bits lineal, 8 bits logarítmico y 8 bits octavo. Debido a que trabaja con datos en punto fijo de 16 bits, tiene un nivel de ruido de -72 dB para bajas frecuencias y -76 dB para altas frecuencias. Cuando se utiliza con el conversor Análogo Digital (ADC) de la tarjeta Arduino, el nivel de ruido del ADC es del mismo orden del nivel de ruido de la rutina FFT, dando como resultado una Relación Señal a Ruido (SNR) entre 9 bit y 10 bit (-55 dB).
Características de velocidad Función N 256 128 64
Run Reordenar (mseg) (useg) 6.32 412 2.59 193 1.02 97
Window (useg) 608 304 152
lin lin8 log (useg) (useg) (useg) 588 470 608 286 234 290 145 114 144
32 16
0.37 0.12
76 37
80 46
41 21
59 30
74 39
Características de la memoria Function N 256 128 64 32 16
Run Reorder Window S/F(B) F(B) F(B) 1k/952 120 512 512/448 56 256 256/200 28 128 128/80 12 64 64/24 6 32
lin lin8 log S/F(B) S/F(B) S/F(B) 256/768 128/640 128/256 128/768 64/640 64/256 64/768 32/640 32/256 32/768 16/640 16/256 16/768 8/640 8/256
S = SRAM, F = Flash ROM
Instalación de la librería
Después de descomprimir ArduinoFFT2.zip, copiar el contenido en la carpeta de ‘librerías’ en el directorio de instalación del IDE Arduino. Posteriormente reiniciar Arduino
Funciones FFT Hay varias funciones que puede llamar para realizar la FFT. La razón por la que se divide en varias secciones, es para que se pueda adaptar la FFT a distinto requerimientos.
fft_run () - Es la principal llamada a la función FFT. No requiere ninguna variable y no devuelve ningún valor. Se supone que existe un bloque de datos que ya están en SRAM, y que ya está reordenado. Los datos se almacenan en la matriz llamada fft_input [], que contiene 2 columnas de valores de 16 bits por cada punto de datos FFT - una para la parte real y la otra para la parte imaginaria. Si se ingresa los valores en el propio código, colocar los valores reales en las posiciones pares, y los valores imaginarios en las posiciones impares. Por ejemplo: fft_input [0] = real1, fft_input [1] = imaginario1 fft_input [2] = real2, fft_input [3] = imaginario2 Por lo tanto existe el doble de datos en la matriz que los datos FFT. Si s e utiliza sólo los datos reales (es decir, valores muestreados del conversor ADC), poner esos valores en las posiciones pares, y escribir 0 a las posiciones impares. La salida final se mantiene en fft_input [], con las posiciones pares conteniendo las magnitudes reales, y l as posiciones impares las magnitudes imaginarias. Las posiciones están en secuencia de incremento de fr ecuencia. Por ejemplo: fft_input [0] y fft_input [1] = magnitudes posición 0 (0 Hz -> Fs / N) fft_input [2] y fft_input [3] = magnitudes posición 1 (Fs / N -> 2Fs / N) Se debe ejecutar una de las funciones de magnitud para obtener datos útiles de estos v alores.
fft_reorder () - Reordena las entradas FFT para prepararlos para el modo particular en que el algoritmo FFT procesa los datos. Se debe llamar a esta función antes de ejecutar la función fft_run ().No requiere ninguna variable y no devuelve ningún valor. La función utiliza los datos de la matriz fft_input [], por lo que los datos deben ser llenados en esa matriz antes de que esta función sea llamada.
fft_window () - Esta función multiplica los datos de entrada por una función de Ventana para ayudar a incrementar la resolución de frecuencia de los datos FFT. No requiere ninguna variable y no devuelve ningún valor. La función procesa los datos en la matriz fft_input [], de modo que los datos deben ser ingresados en esa matriz antes de que sea llamada. También debe llamarse antes fft_reorder () o fft_run ().
fft_mag_lin8 () - Entrega la magnitud de cada dato de la FFT. Suma los cuadrados de las partes imaginaria y real, y luego toma la raíz cuadrada, redondeando la respuesta a 8 bits de precisión (utiliza una tabla y escala los valores a un rango completo de 8 bits). No requiere ninguna variable y no devuelve ningún valor. Opera en la matriz fft_input [] y devuelve los datos en una matriz llamada fft_lin_out8 [].La magnitud se calcula únicamente para los primeros N/2 datos, ya que la segunda mitad de la FFT es idéntica a la primera mitad para todas las entradas reales. Por lo tanto, fft_lin_out8 [] tiene N/2 valores de 8 bits, con cada índice que representa el orden de datos.
Por ejemplo: fft_lin_out8 [0] = primer dato de magnitud (0 Hz -> Fs / N) fft_lin_out8 [1] = segundo dato de magnitud (Fs / N -> 2Fs / N) La salida se puede escalar para maximizar la resolución mediante el factor de Escala.
fft_mag_lin () - Entrega la magnitud de cada dato de la FFT. Suma los cuadrados de las partes imaginaria y real, y luego toma la raíz cuadrada. Utiliza una tabla para calcular la raíz cuadrada, por lo que su precisión es limitada. Cubre la gama completa de 16 bits, pero sólo tiene 8 bits de precisión en cualquier punto en ese rango. Los datos se toman de la matriz fft_input [] y son devueltos en fft_lin_out []. Los valores están en orden secuencial, y sólo hay N/2 valores en total, debido a que la FFT de una señal r eal es simétrica con respecto de la frecuencia central.
fft_mag_log () - Entrega la magnitud de cada dato de la FFT. Suma los cuadrados de las partes imaginaria y real, y luego toma la raíz cuadrada, posteriormente toma el logaritmo en base 2 de ese valor. Por lo tanto, la salida se comprime de forma logarítmica, y esta esencialmente en decibelios (multiplicada por un factor de escala). No requiere ninguna variable y no devuelve ningún valor. Utiliza una tabla para calcular el logaritmo de la raíz cuadrada, y escala la salida al rango completo de 8 bits (la ecuación es 16 * (log 2 ((img 2 + 2 real2) ½)) almacenada en un valor 8 bits. Los valores se toman de la matriz fft_input [], y se devuelven en fft_log_out []. Los valores de salida están en orden secuencial de frecuencia FFT, y sólo hay N/2 datos en total, ya que la segunda mitad del resultado FFT es redundante para las entradas reales.
fft_mag_octave () - Entrega el valor efectivo RMS de los datos en formato de octava (duplicación de frecuencia). Esto es más útil en algunos aspectos ya que está más cerca de cómo los seres humanos perciben el sonido. No requiere ninguna variable y no devuelve ningún valor. La entrada se toma de la matriz fft_output [] y se devuelve en fft_oct_out ½ []. Los datos se representan como un valor 8 bits (16 * log2 ( (mag) ). Los datos LOG_N se dan como sigue: FFT_N = 256: datos = [0, 1, 2, 4, 5: 8, 09:16, 17:32, 3:64, 65: 128] FFT_N = 128: datos = [0, 1, 2, 4, 5: 8, 09:16, 17:32, 3:64] Donde, por ejemplo, (5: 8) es la suma de todos los datos desde 5 hasta 8. Los datos se elevan al cuadrado (partes imaginarias y reales) y luego se suman con todas las magnitudes al cuadrado del rango. A continuación, se divide por el número de datos y se toma la raíz cuadrada, seguido por el cómputo del logaritmo.
4. Generador se señales basado en Arduino - Autor: Ajoy Raman 4.1 Características Requiere tan solo de componentes pasivos: 10 resistencias y un capacitor Generador de Onda por el método de Síntesis Digital Directa ‘Direct Digital Synthesis’ (DDS) Formas de onda: Sinusoidal, Triangular, Rampa Creciente, R ampa Decreciente Generador de formas de onda arbitrarias ‘Arbitrary Waveform Generation’ (AWG) Frecuencia de salida de hasta 45 kHz
4. 2 Lista de componentes Componente Resistencia Resistencia Resistencia Resistencia Resistencia Resistencia Resistencia Capacitor
Cantidad 1 1 4 1 1 1 1 1
Valor 560 Ω 1 kΩ 2.2 kΩ 2.7 kΩ 8.2 kΩ 15 kΩ 33 kΩ 10 nF
4.3 Hardware El circuito implementa un conversor Digital Análogo (DAC) de 6 bits usando una combinación de resistencias 8-4-2-1 conectada a 6 pines PWM (PB0 a PB5) de la tarjeta Arduino UNO. Adicionalmente se incorpora un capacitor al conversor DAC con fines de suavizar la forma de onda.
4.4 Firmware Arduino Para subir el firmware 007_DDS.hex a la tarjeta Arduino, utilizar el software utilitario Xloader. Este permite subir archivos .hex a la tarjeta Arduino sin necesidad de usar el IDE Arduino.
4.5 Software PC a) Descomprimir el archivo Windows GUI.rar b) c) d) e) f) g)
Ejecutar el archivo Establecer la comunicación serial con la tarjeta Arduino Elegir el tipo de forma de onda Elegir la frecuencia de salida Para iniciar el Generador de Señal, presionar el botón RUN Para terminar presionar el botón EXIT
4.6 Formas de Onda Arbitrarias Archivos de formas de onda arbitrarias deben ser creadas en formato .csv (valores separados por comas) que contengan una columna de datos de longitud 128. Los valores de los datos deben ser números enteros en base decimal en el rango de 0 a 63. Estos valores son transferidos a la tarjeta Arduino Uno donde salen como una forma de onda arbitraria. Tres formas de onda típicas con sus respectivos archivos .csv se proveen como ejemplos: arb1_SinSq.csv (495 bytes) arb2-f2f.csv (489 bytes) arb3_Rect.csv (500 bytes)
5. Ejemplo FFT con Arduino La biblioteca FFT se utiliza para obtener una salida de magnitud de8 bits logarítmica en base una Señal de Entrada proveniente del Generador de Señales Arduino. Los datos procesados serán enviados al computador mediante el puerto serial. Los resultados se observarán con la herramienta Serial Plotter del IDE Arduino.
6. Procedimiento en Laboratorio 1era Firma: Mostrar el funcionamiento del Generador de Señales Arduino viendo la salida en un osciloscopio
2da Firma: Mostrar el funcionamiento del Ejemplo FFT con Arduino ingresando los siguientes tipos de señal: Cuadrada, Triangular, Sinusoidal con frecuencias bajas menores a 1 KHz.
7. Informe escrito I.
Mostrar las capturas de pantalla en Matlab para cada tipo de señal.
II.
Realizar un RESUMEN (escrito a mano): ALGORITMO FFT Comprender el algoritmo FFT es una tare a un tanto larga, se deben incluir los siguientes puntos:
1. Comprender el concepto del Lema Danielson-Lanczos (D-L Lemma). Si bien requiere escribir ecuaciones largas, es un componente vital para la FFT.
2.
Explicar el concepto del Factor de Giro ‘Twiddle Factor’ que junto al D-L Lemma son esenciales para comprender
como trabaja la FFT.
3. El Diagrama Butterfly (Mariposa). El cual se basa en los dos conceptos anteriores y es una representación diagramática del algoritmo FFT.
4. Comprender el patrón de bit reverso ‘reverse bit pattern’ para el ingreso de datos y la razón de su uso. Incluir: Fuentes de Información: direcciones web o bibliografía Impresión de las primeras páginas de la fuente de información Resumen escrito a mano (de un mínimo de 6 páginas )
III.
Conclusiones