TODOPIC

Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: elgarbe en 10 de Mayo de 2017, 19:38:55

Título: [Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 10 de Mayo de 2017, 19:38:55
Hace rato que terminé y pude ensamblar unos paneles RGB (http://www.todopic.com.ar/foros/index.php?topic=43643.0) y estaba buscando un proyecto para usarlos.
Se me ocurrió un Vúmetro y como estoy muy metido con los STM32 decidía hacerlo con una placa de evaluacion de ST, en este caso la STM32F103 Nucleo, la cual posee un ARM M3.
En un principio hice un intento con un STM32F0 (ARM M0) pero me encontré con algunos problemas al portar mi driver escrito para un M4F a este micro. Así que decidí pasar a un M3.
Si bien el F103 no tiene manejo de punto flotante por hardware, en principio no me molesta ya que las CMSIS tienen librerías de DSP con funciones para punto fijo en formato Q31 y Q15.

Bien, un vúmetro es un indicador de amplitud de señal en funcion de la frecuencia. En el eje X del panel tendremos la frecuencia y en el eje Y tendremos la amplitud. Es una especie de analizador de espectro, muy básico, para audio. A mi me gusta ya que son muy decorativos para un centro musical.

Para realizar un vúmetro de forma digital tenemos que tener presentes 3 bloques. Primero el muestreo de la señal de audio. Según el teorema de nyquist la frecuencia de muestreo debe ser, al menos, el doble de la máxima frecuencia de nuestro sistems. Si lo que se va a muestrear es audio en la banda de 20Hz a 20KHz lo ideal es muestrear a 40KHz. Muestrear a 40KHz con un ADC de 12bits puede suponer una carga un poco excesiba para nuestro micro. Podemos considerar que la señal de entrada está acotada en banda y supongamos que queremos llegar a sonidos de hasta 10KHz. En dicho caso el muestreo será a 20KHz. Esto es, necesitamos que nuestro uC convierta y almacene en RAM 1 muestra cada 50uSeg.
El segundo bloque es el "calculador de espectro en frecuencia" o más conocido como FFT (transformada rápida de fourier). Con la FFT podes descoponer una señal almacenada en un array en sus componentes frecuenciales, dándonos como resultado la "potencia" de la señal en cada rango discreto de frecuencias. Un parámetro de la FFT es la cantidad de "bines" o divisiones de frecuencia que se realizarán. Este número es una potencia de 2. Valores típicos son de 32, 64, 128, 256.... 4096 puntos de FFT. A mayor cantidad de bines, mayor tiempo de cómputo y mejor resolucion en frecuencia. Por ejemplo, si eligo una FFT de 64 puntos dividiré la Fs de 20KHz entre 64 y tendré una resolucion de 312 Hz. Alguno se habrá dado cuenta que si la señal esta acotada en banda a 10KHz, que pasa con los bines 32 en adelante. Pues se repetirá el espectro que tenemos en los primeros 32 bines, pero espejado. Entonces, el bin 0 del array que devuelve la FFT corresponde a la F=0 a 106Hz -> nivel de continua de la señal. El segundo bin contendra la potencia de las componentes en frecuencia entre 106 y 418 Hz, centrado en F=312. Y así sucesivamente.
Finalmente el 3er bloque tendrá que tomar los bines de la FFT y convertirlos en el buffer de memoria que usará la pantalla LED para mostrar contenido. Este buffer y la forma de refrescar la pantalla es dependiente de la pantalla/driver que usemos.

Bien, siempre me gustó ir de atras para adelante, así que muestro el resultado y luego comenzaré con los pasos de diseño y mostrarles como el CubeMX de ST crea casi todo el código. Tambien mostrarles como usar las funciones de DSP en un M3!


En los próximos post el step by step de cada bloque.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 10 de Mayo de 2017, 22:11:47
El muestreo

Bien el primer problema al que nos enfrentamos es poder muestrar la señal de audio a una tasa mas o menos respetable y almacenar los datos en la RAM.
La señal ingresará a nuestro sistema por un canal ADC. En mi caso tengo AGND a 0V y AVDD a 3.3V por lo que necesito que la señal de audio que entre sea siempre positiva y este centrada en 1.65V. Hay uchas formas elegantes de hacer eso y ustedes me van a sugerir la mejor. En mi caso, para hacer la primeras pruebas colgé la entrada del ADC de un divisor resistivo, formado por 2 resistencias de 15K. De este modo, en reposo obtengo 1.65V. Luego con un capacitor cerámico entre la entrada del ADC y la señal de audio consigo el desacoplo de la señal y de este modo obtengo una señal que se movera centrada en 1.65V. La tension que sale de la mayoría de las placas de sonido o los celulares o los reproductores de mp3 no llegan a 1.65V por lo que no me preocupa la saturacion.
Bien, con esto y sabiendo que el ADC es de 12bits, sé que la señal de entrada estará en 2048 cuentas en reposo y se moverá en mas o menos cuentas de acuerdo al sonido que ingrese.

El siguiente paso es la adquisicion de los valores del ADC. Para esto tenemos al CubeMX que me permite fácilmente configurar el canal del ADC elegido e inicializarlo.
Aquí vemos que hemos elegido la entrada PA0 que es la AN1 como entrada analógica.

 - Tienes que ingresar para ver archivos adjuntos -

En el siguiente cuadro vemos la frecuencia de los distintos periféricos, la del ADC es de 10.66MHz.

 - Tienes que ingresar para ver archivos adjuntos -

En la siguiente pestaña podemos configurar los periféricos. En el caso del ADC tenemos el siguiente cuadro:

 - Tienes que ingresar para ver archivos adjuntos -

En él podemos elegir el modo de conversion, la alineación de los datos, el trigger del ADC el sampling time (que no es La frecuencia de muestreo de nuestro sistema).
Debido a que nuestro muestreo tiene que ser lo más constante/regular posible y como el uC además de manejar el muestreo tiene que manejar el refresco de la pantalla led y tiene que hacer la FFT (costosa en procesamiento) se necesita que el ADC trabaje de forma lo más autónoma posible.
Primero verifiquemos que el ADC puede muestrear a más de 20.000 muestras por segundo. El Tconv = Sampling time + 12.5 cycles. En nuestro caso tenemos elegido un sampling time de 1.5 cycle. Por lo que el Tconv es 14 cycles. A 10.6666 MHz son necesarios 1.31 useg para la conversion, por lo que estamos por demas de bien ya que tenemos 50uSeg.
Verificado esto tenemos que ver como hacer para que el ADC haga conversiones a una tasa regular. Para ello recurrimos al External Trigger Conversion Source. En este canal del ADC podemos elegir varios evento que disparen la conversion del ADC, uno de ellos es Timer 3 Trigger Out Event. o sea que podemos configurar un timer, el 3, para que nos de un evento que dispare la conversion del ADC. Los timer son muy precisos y será una excelente base de tiempos.
El siguiente tema es qué hacer cuando el ADC finalice una conversion. Una opcion es que interrumpa y nosotros tomemos el valor leído y lo almacenemos en un buffer, el cual deberemos mantener para hacerlo de un modo circular... Otra opción es mi querido DMA!!!! Configurando un canal DMA podemos hacer que el ADC almacene cada conversion directamente en la RAM, incluso podemos configurar al DMA en modo circular, con lo que al llegar al final del buffer, solito va a reiniciar el índice y empezará a pisar los datos del comienzo. Pero como, nos va a pisar los datos???? Si, obvio, pero nosotros nos tenemos que asegurar de haberlos usado antes que se pisen. Como hacemos esto? Pues dando un tamaño grande al buffer y configurando la interrupcion del DMA por transferencia "medio completa". Por ejemplo si nosotros necesitamos 128 muestras, podemos poner un buffer de 1024. Entonces cuando el DMA llegue a la muestra 512 interrumpirá, nosotros podemos usar las muestras 384 a 512 (las más recientes) y tendremos el tiempo de 896 muestras antes que se nos pisen los datos que estamos usando. Como ven, configurando el ADC disparado por timer y el DMA para almasenar las muestras tenemos un sistema de muestreo a tasa constante completamente for hardware!!!!
Entonces veamos como habilitar el DMA para el ADC y su configuracion:

 - Tienes que ingresar para ver archivos adjuntos -

Como ven hemos elegido el modo circular y el incremento automatico de la memoria de destino.
Veamos ahora la configuracion del timer para el sampleo a 20.000 KHz.

 - Tienes que ingresar para ver archivos adjuntos -

Con el core clock a 64 MHz podemos dividirlo por 16 para tener un tick de 4MHz en el timer. Luego contar 200 ticks para tener una frecuencia de 20KHz o una interrupcion/conversion cada 50uSeg. Para ello ponemos el prescaler en 16-1 y el Counter en 200.

Finalmente veamos el código que hay que agregar al generado por el CubeMX para que el sampleo automático funcione:

Código: C
  1. int main(void)
  2. {
  3.  
  4.   /* USER CODE BEGIN 1 */
  5.  
  6.   /* USER CODE END 1 */
  7.  
  8.   /* MCU Configuration----------------------------------------------------------*/
  9.  
  10.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  11.   HAL_Init();
  12.  
  13.   /* Configure the system clock */
  14.   SystemClock_Config();
  15.  
  16.   /* Initialize all configured peripherals */
  17.   MX_GPIO_Init();
  18.   MX_DMA_Init();
  19.   MX_SPI2_Init();
  20.   MX_TIM1_Init();
  21.   MX_ADC1_Init();
  22.   MX_TIM3_Init();
  23.  
  24.   /* USER CODE BEGIN 2 */
  25.         //Configuro los TLC
  26.         TLC_Config();
  27.         Cartel_Memoria_Init();
  28.         Cartel_make_mem_DMA();
  29.         // Inicializo el barrido vertical
  30.         vSync_Init();
  31.  
  32.         HAL_TIM_Base_Start(&htim3);
  33.         HAL_ADC_Start_DMA(&hadc1, (uint32_t *)DMA_ADCvalues, 1000);
  34.   /* USER CODE END 2 */
  35.  
  36.   /* Infinite loop */
  37.   /* USER CODE BEGIN WHILE */
  38.   while (1)
  39.   {
  40.   /* USER CODE END WHILE */
  41.  
  42.   /* USER CODE BEGIN 3 */
  43.           Cartel_put_32bars(msg);
  44.           Cartel_make_mem_DMA();
  45.           HAL_Delay(10);
  46.   }
  47.   /* USER CODE END 3 */
  48.  
  49. }

La idea es colocar nuestro código entre dos marcadores de este tipo:

Código: C
  1. /* USER CODE BEGIN 1 */
  2.  
  3.   /* USER CODE END 1 */
De ese modo cuando hacemos algun cambio en el CubeMX y regeneramos el código se nos actualiza todo pero no perdemos lo que hayamos puesto entre esos marcadores.

Básicamente yo hago la inicializacion de la pantalla LED, creo el buffer de memoria de la misma y llamo a dos funciones:

Código: C
  1. HAL_TIM_Base_Start(&htim3);
  2.         HAL_ADC_Start_DMA(&hadc1, (uint32_t *)DMA_ADCvalues, 1000);

La primera enciende la base de tiempos del TIMER 3 y la segunda comienza la transferencia por DMA de 1000 valores y modo circular. Al estar modo circular no necesito volver a iniciar la transferencia pasados los primeros 1000 muestreos. Hermoso!!!!

Bueno, dejo acá por un rato. En la próxima tomaremos los datos y haremos la FFT para obtener el espectro de frecuencia.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 10 de Mayo de 2017, 22:33:28
Hola elgarbe

Siempre me han gustado los páneles de LED y más con analizadores de espectros, pero déjame hacerte unas sugerencias:

1.- El primer factor de la FFT NO es tal cual el valor de frecuencia de 0 a X Hz, en realidad es el valor de voltaje DIRECTO que tiene la señal, en éste caso lo puedes notar porque la primera barra siempre está al tope, lo cual significa qué tu ADC NO esta centrado a la mitad del valor de voltaje medido, es decir, que tu FFT pareciera estar mostrando voltajes positivos cuando en realidad debería capturar el rango positivo y negativo.

2.- Hay un punto muy importante y a la vez curioso cuando se desarrolla una FFT, el cual normalmente se menciona en un solo párrafo en los libros (DSP Proakis Manolakis por ejemplo) y tiene que ver con qué tanto es tantito la resolución necesaria en bits para la FFT. 

Este valor, tiene qué ver con el nivel señal ruido, el cual normalmente es de 60 dB.
¿Qué significa? Que dado un tamaño de puntos de FFT y su frecuencia, se puede determinar cuantos bits es necesario tener en el ADC para asegurar una relación señal-ruido de 60 dB, lo cual, para aplicarse en un display bien podrían ser 8 bits (12 bits está sobrado)

3.- Lo más importante al momento de hacer un analizador de espectros, es precisamente mantener en tiempo REAL la captura y despliegue de la FFT, porque si capturas un segmento de audio, lo procesas y lo envías al display y luego comienzas de nuevo, vas a perder segmentos de audio...
Es en esos pequeños segmentos de audio qué se pierden, en donde las frecuencas media-altas se encuentran, tal que podrás notar que los graves y los medios se despliegan correctamente más pareciera que los agudos no.

Ese efecto NO se nota cuando pruebas tu sistema bajo un generador de señales, pues la señal aplicada es periódica, pero en audio, el sonido de los platillos de la batería suele no graficarse con la intensidad necesaria.

Para ello, lo correcto es que el tiempo de procesamiento de tu FFT, sea igual o menor al tiempo de captura de muestras, tal qué si tomas por ejemplo 32 muestras @ 50 uS = 1.6 milisegundos, ese sea el tiempo de procesamiento máximo de tu FFT, y al mismo tiempo, por interrupción o DMA, captures el siguiente bloque de muestras mientras procesas la FFT del bloque actual...

4.- La frecuencia de sampleo que tienes es muy baja, en realidad SI qué debería de ser de 40 Khz y hasta de 80 Khz para samplear el canal izquierdo y el derecho y promediarlos, más es posible que tu procesamiento de FFT tarde mucho (debido a los 12 bits del ADC) y hayas restringido el valor de frecuencia del ADC

Ahora, te recomiendo separar en dos partes el procesamiento de FFT versus el refresco de la pantalla de LEDS, pues eso te va a permitir hacer cosas bastante interesantes:

Si estableces tu refresco de pantalla a 30 o 60 hz, lo que puedes hacer entre refresco y refresco es capturar N FFT y promediarlas u obtener los PICOS de intensidad más altos de ellas tal qué cuando procedas a graficar la señal puedas precisamente representar los picos de los bines capturados entre periodos de refresco...

Ejemplo: Si usas 30 Hz de refresco y capturas 32 puntos @ 50 uS puedes capturar 20.83 FFTs entre los tiempos de refresco de tu pantalla

Por otro lado, al tener un periodo de refresco de pantalla independiente a la captura de FFT, puedes "simular" capacitores qué hagan qué cada barrita baje suavemente en lugar de presentar a "secas" la FFT procesada, recuerda que un analizador de espectros es más un elemento estético qué un instrumento de medición...

Este es un ejemplo, pero en un PIC18, en una pantalla OLED de 256 x 64 pixeles en 16 tonos de grises, sampleando a 80 Khz para capturar canal derecho e izquierdo, obtener el valor RMS de cada canal de audio y promediarlos para generar la FFT de 128 puntos usando el ADC en modo de 8 bits.

Primero se captura el primer bloque de audio, y mientras se procesa se continua en paralelo la captura del siguiente bloque de audio, de tal manera qué al final se capturar 7 FFT, se obtienen los picos de señal de cada una y se simula un capacitor de decay para suavizar las barras...

Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 10 de Mayo de 2017, 23:25:22
Muchísimas gracias por el aporte!!!! si bien la idea era mostrar una aplicacion hecha más o menos para ver lo facil que es trabajar con los micros de ST y el CubeMX, pues si se agregan conocimiento y podemos hacer algo más elavorado bienvenido sea.
Algunos de los conceptos que expones los tengo presente, simplemente mostré una simplificación del problema. Pero debo reconocer que la gran moyoría de los temas no los tenía presente.

Cuando termine la exposicion de la resolucion del Vúmetro básico, te propongo me ayudes a incluir las mejoras propuestas para obtener un mejor equipo!

Saludos y gracias!

Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 11 de Mayo de 2017, 00:21:05
Claro qué sí, con gusto iré proponiendo esas partes, no son difíciles, solo capciosas, digo, llevo mucho tiempo en esto de los analizadores de espectros y he pasado por cada etapa viendo los resultados...

Mi primera FFT se veía como la tuya, y no comprendía el porqué no mostraba todos los elementos de audio hasta que fui observando y aprendiendo uno x uno...

Saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 11 de Mayo de 2017, 19:17:13
Bien, nos quedamos entonces en que tenemos un bonito array de 1000 valores en la RAM, los cuales se van pisando constantemente. Por otra parte, cuando el canal DMA transfirió la mitad de los 1000 valores me dará una interrupcion.
Las HAL tienen un modo interesante de manejar las interrupciones. El punto de entrada de ellas esta en un archivo stm32f1xx_it.c. En él vamos a encontrarnos con algo como esto:

Código: C
  1. /**
  2. * @brief This function handles DMA1 channel1 global interrupt.
  3. */
  4. void DMA1_Channel1_IRQHandler(void)
  5. {
  6.   /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
  7.  
  8.   /* USER CODE END DMA1_Channel1_IRQn 0 */
  9.   HAL_DMA_IRQHandler(&hdma_adc1);
  10.   /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
  11.  
  12.   /* USER CODE END DMA1_Channel1_IRQn 1 */
  13. }

Ese es el canal del DMA que maneja al ADC. Por lo que o unico que tiene este ISR es una llamada a otra funcion de la HAL. Veamos una parte de lo que contiene:

Código: C
  1. /* Half Transfer Complete Interrupt management ******************************/
  2.   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
  3.   {
  4.     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
  5.     {
  6.       /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
  7.       if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
  8.       {
  9.         /* Disable the half transfer interrupt */
  10.         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
  11.       }
  12.       /* Clear the half transfer complete flag */
  13.       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
  14.  
  15.       /* Change DMA peripheral state */
  16.       hdma->State = HAL_DMA_STATE_READY_HALF;
  17.  
  18.       if(hdma->XferHalfCpltCallback != NULL)
  19.       {
  20.         /* Half transfer callback */
  21.         hdma->XferHalfCpltCallback(hdma);
  22.       }
  23.     }
  24.   }

Se verifican y borran algunas banderas y lo más importante es lo que esta al final y es "hdma->XferHalfCpltCallback(hdma);"
En esa instruccion se usa lo que se denomina callback y es una forma standar de darle al usuario funciones en donde poner el código para cada interrupcion en particular, dejando todo lo referente a banderas a las HAL.
Entonces lo que nosotros tenemos que hacer es implementar esa funcion en nuestro código y la misma será llamada de forma automática.

En mi código pongo:

Código: C
  1. void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
  2. {
  3. }

y en ese lugar pongo el código que quiero que se ejecute cuando el DMA valla por la mitad de la transferencia.
En ese momento lo que yo quiero hacer es calcular la FFT y obtener la magnitud (la FFT devuelve numeros complejos) de cada bin.

Código: C
  1. void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
  2. {
  3.         uint32_t i;
  4.  
  5.         for(i=0;i<128;i+=2)
  6.         {
  7.                 FFT_ADCvalues[i]=DMA_ADCvalues[i/2];
  8.                 FFT_ADCvalues[i+1]=0;
  9.  
  10.         }
  11.         arm_cfft_q31(&arm_cfft_sR_q31_len64, FFT_ADCvalues, 0, 1);
  12.     for (i = 0; i < 64 * 2; i+=2)
  13.     {
  14.         arm_sqrt_q31((FFT_ADCvalues[i] * FFT_ADCvalues[i]) + (FFT_ADCvalues[i+1] * FFT_ADCvalues[i+1]), &MAG_of_fft[i/2]);
  15. //Escalado para que llene las 16 lineas de la pantalla.
  16.         MAG_of_fft[i/2] *= 16;
  17.         MAG_of_fft[i/2] /= 2000000;
  18.         if(MAG_of_fft[i/2] > 16)
  19.                 MAG_of_fft[i/2]=16;
  20.         msg[i/2]=MAG_of_fft[i/2];
  21.     }
  22. }

Entonces, el DMA guarda en forma circular 1000 valores, cuando va por el 500 me interrumpe. Yo tomo los primeros 64 valores y armo un array con ADC[0], 0, ADC[1], 0, ADC[2], 0... esto es necesario por que la funcion arm_cfft_q31 de la CMSIS calcula los valores complejos de la FFT.
Dicha funcion calcula la FFT inplace entonces solo le enviamos ese array y le decimos la cantidad de puntos de FFT que haremos. En este caso 64 puntos. El paso siguiente es componer los 128 valores (parrte real e imaginaria de cada bin) en un nuevo array de 64 puntos con los valores de la magnitud de cada bin. En este caso en realidad estoy tomando solo 64 puntos para obtener mis 32, ya que la matriz tiene 64 puntos horizontal pero estoy mostrando cada barra con 2 columnas de ancho
Ya vimos (gracias vixctor) que esta implementaciòn no es la mejor, pero es la que me asegura un funcionamiento del sistema sin renegar demasiado. Hay mucho por optimizar!!!
La ultima parte del segundo for me arma el array msg[] con los valores que voy a mostrar en la pantalla led.

Finalmente en el while principal tengo:

Código: C
  1. while (1)
  2.   {
  3.   /* USER CODE END WHILE */
  4.  
  5.   /* USER CODE BEGIN 3 */
  6.           Cartel_put_32bars(msg);
  7.           Cartel_make_mem_DMA();
  8.           HAL_Delay(10);
  9.   }

Aquí, en forma asíncrona, tomo el array msg y lo transformo en barras de mi cartel. Luego tomo el buffer "de video" y lo convierto en un buffer que usará el DMA del SPI para refrescar la pantalla.
El refresco de la pantalla esta funcionando de fondo, todo con DMA e interrupciones.

Bien, hasta aquí lo que quería mostrar, una aplicacion de un stm32 a un proyecto puntual usando el CubeMX y ver que casi no hay código escrito más que el que crea el mismo CubeMX.

Veamos ahora como ir mejorando cada aspecto del sistema para obtener un resultado más profesional. Para ello espero contar con la ayuda de vixctor!!!

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 11 de Mayo de 2017, 19:51:23
Me gustaría aprender a mejorar el sistema por lo que vamos a tratar de entablar un intercambio de ideas.

Yo tengo una noción de la FFT, de lo que la relacion señal ruido y algunos otros conceptos, pero en otro contexto. Estoy trabajando en el desarrollo de un equipo de otoemisiones aucústicas. En dicho sistema debemos exitar 2 speaker miniaturas, con 2 tonos de diferente frecuencias. Uno en 60dBSPL y el otro en 50dBSPL. Las frecuencias se eligen de modo que f2=1.2f1. Exitando el oido humano con dichos sonidos se ha demostrado que se exita la coclea y ésta responde con lo que se llama producto de distorcion. Es una señal que esta hubicada en 2f1-f2 y tiene una amplitud de entre -10 a 10dB SPL. Uno de los requerimientos del sistema es poder leer la DPOAE al mismo tiempo que se leen los estímulos. En este caso tenemos unos 70dB de diferencia. Otro requisisto es llevar con algunas técnicas el piso de ruido a -20dB SPL. Lo que nos da una SNR de 80dB. En ese equipo trabajamos arduamente con FFT, promedios sincrónicos en tiempo para aumentar la SNR, etc.
Es por ello que me interesa muchísimo compartir ideas y tratar de aprender más sobre estos temas.

1.- El primer factor de la FFT NO es tal cual el valor de frecuencia de 0 a X Hz, en realidad es el valor de voltaje DIRECTO que tiene la señal, en éste caso lo puedes notar porque la primera barra siempre está al tope, lo cual significa qué tu ADC NO esta centrado a la mitad del valor de voltaje medido, es decir, que tu FFT pareciera estar mostrando voltajes positivos cuando en realidad debería capturar el rango positivo y negativo.
He leído decenas de explicaciones de que frecuencia representa cada bin de la FFT hasta que encontré un documento (que no tengo acá, esta en la facu) donde explicaba a la perfeccion y pude comprobar prácticamente. Si mal no recuerdo, el bin 0 no tiene solo la componente de continua. Cada bin de la FFT, por ser ésta discreta, presenta el contenido de un grupo de frecuencias y tiene una respuesta más precisa a una frecuencia central. Entonces con una Fs de 20.000Hz y una FFT de 1024puntos tenemos una resolucion de 19.53 Hz. Yo creo que eso no significa que el bin 1 me indique la potencia de la señal solo de 19.53Hz. De hecho, si coloco el GAF y voy variando la frecuencia de a 1 Hz puedo ver como el espectro se mueve de un bin a otro "de a poco" no hay un salto discreto entre 19.53 y 39.06, si no que se va "transfiriendo" de un bin a otro. Lo que no recuerdo es si el bin 0 es una excepcion y solo mide el contenido de DC (leí en muchos lugares que es así, pero en lugares donde para mi erran en el concepto anterior). Aquí tengo algunas dudas ya que la transferencia entre bines es medio rara, ya mostrare un video de lo que digo para que me ayuden a entender.
Coincido que hay algo raro en mi adquisicion y en mi FFT. Mi señal de entrada es toda positiva, ya que el ADC va de 0 a 4096. Yo pongo un bias, como explique al principio para que sin señal tenga 1.65V y mi ADC mida 2048 cuentas. Eso lo probe y es así. El tema está en que al momento de hacer los cálculos creo que debería restar ese ofset para que la señal tenga parte positiva y parte negativa. De hecho uso el formato Q31 porque es punto fijo de numeros positivos y negativos, pero creo que lo estoy usando mal.
Algo como esto:
https://community.arm.com/processors/f/discussions/6997/how-to-prepare-adc-data-for-q31_t-cmsis-dsp-functions
Una vez que solucione esto seguro que la barra del bin0 se irá a 0.

2.- Hay un punto muy importante y a la vez curioso cuando se desarrolla una FFT, el cual normalmente se menciona en un solo párrafo en los libros (DSP Proakis Manolakis por ejemplo) y tiene que ver con qué tanto es tantito la resolución necesaria en bits para la FFT. 

Este valor, tiene qué ver con el nivel señal ruido, el cual normalmente es de 60 dB.
¿Qué significa? Que dado un tamaño de puntos de FFT y su frecuencia, se puede determinar cuantos bits es necesario tener en el ADC para asegurar una relación señal-ruido de 60 dB, lo cual, para aplicarse en un display bien podrían ser 8 bits (12 bits está sobrado)

No lo sabía y es muy pero muy interesante para mi.
Aquí encontre lo que me dices:
 - Tienes que ingresar para ver archivos adjuntos -

12 bits es mucho. Pero me entra una duda. El uC es de 32bits por lo que maneja de forma nativa las funciones de 32 bits. Realmente será mas lento calcular una FFT en Q31 que en Q15 o que en 8 bits? algo para investigar.

3.- Lo más importante al momento de hacer un analizador de espectros, es precisamente mantener en tiempo REAL la captura y despliegue de la FFT, porque si capturas un segmento de audio, lo procesas y lo envías al display y luego comienzas de nuevo, vas a perder segmentos de audio...
Es en esos pequeños segmentos de audio qué se pierden, en donde las frecuencas media-altas se encuentran, tal que podrás notar que los graves y los medios se despliegan correctamente más pareciera que los agudos no.

Ese efecto NO se nota cuando pruebas tu sistema bajo un generador de señales, pues la señal aplicada es periódica, pero en audio, el sonido de los platillos de la batería suele no graficarse con la intensidad necesaria.

Para ello, lo correcto es que el tiempo de procesamiento de tu FFT, sea igual o menor al tiempo de captura de muestras, tal qué si tomas por ejemplo 32 muestras @ 50 uS = 1.6 milisegundos, ese sea el tiempo de procesamiento máximo de tu FFT, y al mismo tiempo, por interrupción o DMA, captures el siguiente bloque de muestras mientras procesas la FFT del bloque actual...

Coincido, lo ideal es no perder parte de la informacion de audio y tratar de optimizar todo para ello.


4.- La frecuencia de sampleo que tienes es muy baja, en realidad SI qué debería de ser de 40 Khz y hasta de 80 Khz para samplear el canal izquierdo y el derecho y promediarlos, más es posible que tu procesamiento de FFT tarde mucho (debido a los 12 bits del ADC) y hayas restringido el valor de frecuencia del ADC

Acá no coincido del todo... Hay que hubicarse en el contexto. El estandar de 22050Hz para audio existe y se usa. Un CD esta muestreado a 48KHz me parece que un equipo "regular" puede muestrear a 20KHz y perder los agudos (que es un porcentaje muy bajo de la señal).
De todos modos, coincido que si levantamos a 40KHz y encima muestreamos los dos canales, pues el resultado va a ser muchísimo mejor que el obtenido a 20K.

Ahora, te recomiendo separar en dos partes el procesamiento de FFT versus el refresco de la pantalla de LEDS, pues eso te va a permitir hacer cosas bastante interesantes:

Si estableces tu refresco de pantalla a 30 o 60 hz, lo que puedes hacer entre refresco y refresco es capturar N FFT y promediarlas u obtener los PICOS de intensidad más altos de ellas tal qué cuando procedas a graficar la señal puedas precisamente representar los picos de los bines capturados entre periodos de refresco...

Ejemplo: Si usas 30 Hz de refresco y capturas 32 puntos @ 50 uS puedes capturar 20.83 FFTs entre los tiempos de refresco de tu pantalla

Por otro lado, al tener un periodo de refresco de pantalla independiente a la captura de FFT, puedes "simular" capacitores qué hagan qué cada barrita baje suavemente en lugar de presentar a "secas" la FFT procesada, recuerda que un analizador de espectros es más un elemento estético qué un instrumento de medición...

Exclente, voy a ir tratando de mejorar el sistema para implementarlo de este modo.

Este es un ejemplo, pero en un PIC18, en una pantalla OLED de 256 x 64 pixeles en 16 tonos de grises, sampleando a 80 Khz para capturar canal derecho e izquierdo, obtener el valor RMS de cada canal de audio y promediarlos para generar la FFT de 128 puntos usando el ADC en modo de 8 bits.

Primero se captura el primer bloque de audio, y mientras se procesa se continua en paralelo la captura del siguiente bloque de audio, de tal manera qué al final se capturar 7 FFT, se obtienen los picos de señal de cada una y se simula un capacitor de decay para suavizar las barras...


 ((:-)) ((:-)) ((:-)) ((:-)) Ese Vúmetro con un PIC18!!!  ((:-)) ((:-)) ((:-))

El primer punto que me interesaría mejorar es el sistema analógico de entrada. Lo ideal es que sea un amplificadorcito al que le pueda regular la ganancia para ajustarlo a los niveles máximos de la pantalla...
Que has usado como acondicionador en la entrada?

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 11 de Mayo de 2017, 20:49:33
2.- Hay un punto muy importante y a la vez curioso cuando se desarrolla una FFT, el cual normalmente se menciona en un solo párrafo en los libros (DSP Proakis Manolakis por ejemplo) y tiene que ver con qué tanto es tantito la resolución necesaria en bits para la FFT. 

Este valor, tiene qué ver con el nivel señal ruido, el cual normalmente es de 60 dB.
¿Qué significa? Que dado un tamaño de puntos de FFT y su frecuencia, se puede determinar cuantos bits es necesario tener en el ADC para asegurar una relación señal-ruido de 60 dB, lo cual, para aplicarse en un display bien podrían ser 8 bits (12 bits está sobrado)

Me quedé pensando en este punto. Si la SNR es 60dB y pensamos que tenemos que pensar en representar señales que varíen en 60dB entonces me parece que 8 bits no alcanza.
60dB es una ganancia de 1000. O sea que si 256 bits representan la señal más grande, pues con no llego a poder representar una señal 1000 veces más chica. Solo una que es 256 veces más chica. una ganancia de 256 nos da 48dB.

Necesitaría al menos 10 bits para representar una señal con 60dB de variación.

Pienso bien? no encuentro el libro que citaste para ver como se calcula realmente.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 11 de Mayo de 2017, 22:38:19
Hola elgarbe

Creo saber qué es lo que pasa con el sampleo del ADC que tienes al momento de manipular los datos...

El tema está en el formato de los datos, veras:

Tu mencionas que simplemente acomodaste la señal para que quedara a la mitad, o sea, a 2047 - 2048 medido en el ADC...

Eso qué estas haciendo tiene un nombre: "positive straight offset binary code" o sea, es un OFFSET pero tus muestras NO tienen un formato numérico real...

Pues bien, te falta ese paso en ese punto, ya qué el sistema debe estar en complemento a 2 o con signo para leer de  + - 2048

La idea es simple: Negar el bit MSB de tus muestras:

En mi caso por ejemplo, usando 8 bits, el primer paso me entrega valores como...

0 1 2 .... 127 -  128 ... 129 ... 255, tomando la mitad es el offset positivo binario...

todo lo qué tengo que hacer es negar el bit MSB del ADC, para que me quede algo como...

128 129 130.... 255 ... 0 1 2 ... 127...  (viendolo como un valor entero)
 
Pero en realidad considerando el bit MSB como el signo, tengo...

- 128 -127 -126... -3 -2 - 1 0 1  2  3   4 ... 127

Y entonces ya la FFT puede procesar correctamente los valores, pues estarán con signo desde el inicio, de ahí que precisamente tu primer BIN salga hasta el tope...


Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 11 de Mayo de 2017, 23:52:54
Pasando a otro punto, una cosa es el ruido RMS y otra el rango dinámico de la FFT, el cual tiene una formula diferente a la que presentas:

SNR en la FFT, se refiere más a la relación señal ruido generada por los errores de cuantificación de las etapas intermedias de la FFT más que al propio SNR del ADC...

Por ejemplo, para la DFT directa SNR equivale a:

                                         (2b - 2N)
SNR = 10 Log (base 10) 2

Donde N es el numero de puntos expresados como potencia de 2

Pero, en la FFT, y cuando se usa escalación inicial SNR cambia a:

                                                                2b - v - 1
Signal Noise Ratio = 10 Log (base 10) 2

Log 2 base 10 x 10 es 3.010 (se puede tomar como 3)

SNR = 3 (2b - v -1)

Donde V es el numero de puntos expresados como potencia de 2

Ejemplo: (tomado de Proakis Manolakis): Se requiere una FFT de 1024 puntos con un SNR de 30 dB, cuantos bits son necesarios?

Para DFT:

3(2b - 20) = 30

2b - 20 = 30/3

2b = 10 + 20

b = 30 / 2 = 15 bits

Para el mismo ejemplo, pero usando FFT:

3 (2b - 10 - 1) = 30

2b - 11 = 30 / 3

2b = 10 + 11

b = 21 / 2 = 11 bits necesarios

Ciertamente 60 dB de SNR es mucho, y de hecho ese valor no lo recordaba del todo bien (30 dB lo mencionan mucho en el libro), pero aun con libro en mano no recuerdo en donde leí ese míni párrafo en donde venia el mínimo SNR necesario para que funcione bien la FFT, pero vamos, en realidad NO es un valor alto, porque el vúmetro al final del día, tiene una escala reducida en la AMPLITUD qué puede mostrar...

Por cierto, el libro es Digital Signal Processing, John G. Proakis y Dimitris G. Manolakis, editorial PRENTICE HALL, la edición que tengo es la 3ra

Y de hecho SNR en FFT depende del algoritmo usado, Radix 2 o 4, decimación en frecuencia o en tiempo, para lo cual hace años me metí muy a fondo pues implemente radix 2F decimación en frecuencia y leí al menos los dos capítulos relacionados al tema, y de ahí precisamente obtuve qué con 8 bits podía salir bien para FFT de 256 puntos o menos.

Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 12 de Mayo de 2017, 00:09:02
Ahora, de la última pregunta, use un amplificador inversor con divisor de tensión en la entrada no inversora, acoplado por capacitor a la entrada y salida directa al ADC, pero hay un punto importante relacionado con los otros dos puntos que ya escribí antes...

1.- Recuerdas que para adecuar el formato numérico del ADC simplemente niegas o complementas el bit MSB del ADC? Pues bien, si lo has cachado bien, hacer eso va a "invertir" la polaridad de las muestras tal que la señal quedará invertida, por eso se usa un amplificador inversor antes del ADC, para volver a la señal a su polaridad normal...

2.- El problema de samplear a menor frecuencia qué la máxima encontrada en AUDIO, es qué en la FFT, las frecuencias mayores a 10 Khz (en tu caso) te van a rebotar en la pared derecha, es decir, cuando la frecuencia de audio supera la frecuencia de sampleo, tus bines van a ir hacia el lado contrario...

Eso te obliga si o si al menos a poner un filtro de corte de frecuencias altas de alto Q en el amplificador operacional para evitar ese problema...
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 12 de Mayo de 2017, 00:47:31
Este es un test interesante, es largo el video pero explica mucho:


Antes que nada, esta versión de player que tengo es la penúltima generación, no la última, el cual corre en un PIC18F67K22 @ 64 Mhz

El video consta de 3 minutos, en donde se reproducen 2 archivos de 1 minuto de audio x cada archivo...

El test consiste en:

Minuto 1: Una señal de 10 a 20 Khz que dura 30 segundos y de 20 Khz a 10Hz los siguientes 30 segundos. (eso significa que cada segundo hay un incremento de 666 Hz)

Observación: Esta versión del reproductor de audio, no tiene la capacidad de llegar a los 80 Khz de sampleo por canal, sino a 60 Khz, por lo cual, la escala máxima de la FFT es de aprox 15 Khz.
Pasando los 15 Khz (21 -22 seg x 666 = 14666 Hz) la frecuencia de audio continua incrementandose pero ahora los "bines" van al revés, es lo que te explicaba qué sucedia en la FFT cuando la frecuencia del audio supera a la del ADC, o sea, ahora va de "reversa"
Cuando regresa de 20 Khz a 15 Khz las bandas vuelven a la normalidad...

Minuto 2: Ahora se reproduce un archivo de 10 a 15 Khz (500 Hz x segundo), y como podrás observar, efectivamente la FFT cubre todo ese espectro de audio, lo cual corrobora el ancho de banda de la FFT...

Minuto 3: Es el mismo archivo de 10 a 20 Khz pero ésta vez incremente el volumen a 0 dB... Lo que puedes observar, es precisamente los componentes de distorsión armónica generados cuando la señal SATURA la entrada de voltaje del ADC y se nota en esas componentes qué van de un lado para el otro, o sea, los múltiplos de la frecuencia fundamental...

Ese pequeño tremulo o vaiven de toda la FFT conforme avanza, se genera cuando NO aplicas una ventana de acotación a la FFT (Hamming, cuadrática, Gauss, etc) ya que la FFT al correr en multiplos de potencias de 2, cuando se captura un segmento de señal, y su periodo NO COINCIDE con el número de muestras capturadas, genera pequeños errores que se ven reflejados como componentes de frecuencia, por ello normalmente se aplica el llamado acotamiento por ventana, en donde la idea, es hacer qué las muestras del inicio del sampleo empiecen en 0 y se amplifiquen hasta llegar a su máxima amplitud y luego se desvanezcan hasta llegar nuevamente al valor de 0, lo cual evita esas pequeñas variaciones...

Nota1: La versión 2.0 del reproductor, hace un overclock del PIC llevandolo a 75 Mhz lo cual obliga al ADC a trabajar más rápido y por consiguiente el ancho de banda de la FFT llega a los 19-20 Khz efectivos...

Nota 2: Como puedes observar en las barras de medición de señal RMS, estas se mantienen CONSTANTES a lo largo del barrido de audio, con excepción al momento de llegar a la frecuencia de Nyquist, en donde se generan errores por ser el valor medio cuadrático...

Nota 3: No se los demás pero al menos Yo si alcanzo a escuchar toda la escala de audio hasta los 20Khz, lo cual es un buen test para probar la salud de nuestros oidos...  :P
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 12 de Mayo de 2017, 20:19:16
Hola elgarbe

Creo saber qué es lo que pasa con el sampleo del ADC que tienes al momento de manipular los datos...

El tema está en el formato de los datos, veras:

Tu mencionas que simplemente acomodaste la señal para que quedara a la mitad, o sea, a 2047 - 2048 medido en el ADC...

Eso qué estas haciendo tiene un nombre: "positive straight offset binary code" o sea, es un OFFSET pero tus muestras NO tienen un formato numérico real...

Pues bien, te falta ese paso en ese punto, ya qué el sistema debe estar en complemento a 2 o con signo para leer de  + - 2048

La idea es simple: Negar el bit MSB de tus muestras:

En mi caso por ejemplo, usando 8 bits, el primer paso me entrega valores como...

0 1 2 .... 127 -  128 ... 129 ... 255, tomando la mitad es el offset positivo binario...

todo lo qué tengo que hacer es negar el bit MSB del ADC, para que me quede algo como...

128 129 130.... 255 ... 0 1 2 ... 127...  (viendolo como un valor entero)
 
Pero en realidad considerando el bit MSB como el signo, tengo...

- 128 -127 -126... -3 -2 - 1 0 1  2  3   4 ... 127

Y entonces ya la FFT puede procesar correctamente los valores, pues estarán con signo desde el inicio, de ahí que precisamente tu primer BIN salga hasta el tope...

Totalmente de acuerdo, anoche cuando termine de postear me quede investigando el formato Q15 y es como dices, no puedo almacenar un uint16 en un Q15 como si nada. Hay que acomodar el formato del número.
Como primer medida voy a pasar el buffer del ADC a 16 bits. y voy a ver si puedo hacer funcionar el Q15, luego seguimos con los ortos mensajes, que por cierto son muy interesantes!.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 12 de Mayo de 2017, 22:36:54
Estoy bastante complicado con la tranformacion a Q15. El formato Q15 lo necesito porque la funcion FFT se hace sobre numeros en formato q15.
pero ya lo voy a destrabar...

saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: KILLERJC en 12 de Mayo de 2017, 23:02:23
Se puede saber que estas intentando convertir?
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 12 de Mayo de 2017, 23:28:58
Código: C
  1. for(i=0;i<128;i+=2)
  2.         {
  3.                 FFT_ADCvalues[i]=(q15_t)((int16_t)(DMA_ADCvalues[i/2]-2048)<<4);
  4.                 FFT_ADCvalues[i+1]=(q15_t)0;
  5.         }
  6.         arm_cfft_q15(&arm_cfft_sR_q15_len64, FFT_ADCvalues, 0, 1);
  7.         arm_cmplx_mag_q15(FFT_ADCvalues, MAG_of_fft, 64);

La funcion arm_cfft_q15 necesita como entrada las muestras del ADC en formato Q15. Por otra parte el vector de entrada de la FFT es para cada punto un (real, imaginario). La entrada es todo real, por eso el lazo for primero.
Luego se hace la FFT, la cual devuelve 64 puntos (real, imaginario).
Finalmente la ultima funcion calcula la magnitud (sqrt(real*real+imaginario*imaginario)) y esos son los valores a usar (creo que hay que dividir por 64 tambien).

El tema es que no me funciona, la salida MAG_of_fft termina siendo el primer valor 511 y el resto todos ceros... estoy buscando informacion por todos lados, pero no lo tengo muy claro aun...

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 13 de Mayo de 2017, 17:46:44
Bueno, estoy aprendiendo algo nuevo... Punto Fijo!

Como esto no me está funcionando como es eperado no me queda otra que estudiar bien como funciona!
Las librerías de DSP de las CMSIS estan programadas en punto flotante, para ser usada preferentemente con FPU por hardware, luego hay versiones para punto fijo Q1.31 y Q1.15. El tema es que no tenía idea como funcionaban esos formatos de punto fijo.
La primer referencia, wikipedia:
https://en.wikipedia.org/wiki/Q_(number_format)

Nuestro Q15 no es otra cosa que un typedef a un int16_t, por lo que el contenedor de nuestro Q15 es un número de 16 bits CON signo.
Entonces los que vale es:
Rango: [ -20 , 20-2-15 ] = [ -1 , 0,999969482421875 ]
Pero com ose representan los números?
Bien, el primer bit es de signo. 1 -> números negativos. 0-> números positivos.
Luego los numeros positivos cada bit arrancando del 15 hacia el bit 0 valen 2-n en este caso b15->n=1, b14-> n=2.
O sea:
0.99 = 0111 1111 1111 1111
0.75 = 0110 0000 0000 0000b
0.5 = 0100 0000 0000 0000b
0.25 = 0010 0000 0000 0000b
0    = 0b

Entonces lo que en número binarios comunes van del 0 al 0111 1111  1111 1111(32767o 0x7FFF) es el recorrido de 0 a 0.99999

Con los negativos es un poco menos intuitivo. Pero sería así
-1      = 1000 0000 0000 0000b
-0.75 = 1010 0000 0000 0000b
-0.5   = 1100 0000 0000 0000b
-0.25 = 1110 0000 0000 0000b

O sea que cuántos más 1 hay, mas chico es el número entonces vamos desde  1111 1111 1111 1111  (-0.0 o 0xFFFF) hasta 1000 0000  0000 0000(-1 ó 0x8000)

Luego para pasar de un número flotante a q15 hay que multiplicar por 215 y redondear al entero más cercano.

Sabido esto podemos hacer un programita de testeo de todo esto más la FFT.

La idea es crear un seno de 1.5Khz (1562Hz en realidad), muestreado a 10KHz en formato flotante (funcion sin de math.h) Luego pasarla a q15, hacer la FFT y calcular la magnitud de los resultados. Recordar que la salida de la FFT es en formato complejo (real, imaginario) y para obtener un valor "usable" hay que calcular la magnitud (y la fase si se quiere):

Código: C
  1. float fltSinWave[64];
  2.         q15_t q15SinWave[64];
  3.         q15_t q15FFT[128];
  4.         q15_t MAG_of_fft[64];
  5.         uint32_t F=1562;
  6.         uint32_t Fs = 10000;
  7.         uint8_t i;
  8.         for(i=0;i<64;i++)
  9.         {
  10.                 // Seno discreto FLOTANTE
  11.                 fltSinWave[i] = (sin(2*M_PI*i*F/Fs));
  12.                 // Seno discreto en Q15
  13.                 q15SinWave[i] = (q15_t)(fltSinWave[i] * (1<<15));
  14.         }
  15.         // Preparo el array de la FFT
  16.         for(i=0;i<128;i+=2)
  17.         {
  18.                 q15FFT[i] = q15SinWave[i/2];
  19.                 q15FFT[i+1] = 0;
  20.         }
  21.         // Calculo la FFT
  22.         arm_cfft_q15(&arm_cfft_sR_q15_len64, q15FFT, 0, 1);
  23.         // Calculo la magnitud de cada punto
  24.         arm_cmplx_mag_q15(q15FFT, MAG_of_fft, 64);

Corriendo esta parte en el uC obtengo:
fltSinWave
0, 0.831295013, 0.924119771, 0.196014598, -0.706217647, -0.981090546, -0.38442421, 0.553740382, 0.999996841, 0.557918906, -0.3797791, -0.980105221

q15SinWave
0, 27239, 30281, 6423, -23141, -32148, -12596, 18144, 32767, 18281, -12444, -32116

Aquí podemos verificar que 0.83129 en float es 27239 en q15. 27239 en binario es 0110 1010 0110 0111. Componiendo en q15 tenemos: 0.5 + 0.25 + 0.0625 + 0.015625 +.... sumando solo esos bits tenemos 0,828125 por lo que podemos verificar que el formato es el correcto.

El siguiente paso es armar un array con el doble de puntos necesario para la FFT.
Finalmente calculamos la FFT y la magnitud de cada bin.

La señal que creamos tiene 1562Hz por una razon. Si calculamos la resolucion de la FFT: Fs/Nfft = 10.000/64 = 156.25 Hz. Por lo que el centro de cada bin estará en un múltiplo de 156.25. En este caso 1562 (.5). En que bin deberíamos encontrar el pico de la FFT? 1562 / 156 = 10.
Cuando voy al visor de expresiones en el IDE obtengo esto para MAG_of_fft:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8191, 0 <repeats 43 times>

Como ven tengo toda la potencia de la señal en el bin 10  :-/

Entonces ahora ya tengo funcionando la FFT y el cálculo de magnitud. Solo resta acomodar los datos del ADC en un q15. Eso queda para dentro de un rato.

Saludos

Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 13 de Mayo de 2017, 18:02:11
Un punto que falta resolver es que el resultado de la FFT dió 8191. En binario es 0001 1111 1111 1111 si tomo ese número como q15 y lo paso a decimal el número que obtengo es 0.249969482.
La FFT aplicada a un seno nos debe devolver la Vp. En este caso el seno va de 1 a -1 por lo que la Vp = 1 y yo debería obtener como espectro de potencia 1 y no 0.25

Mirando la funcion arm_cmplx_mag_q15 encuentro esta nota:

"The function implements 1.15 by 1.15 multiplications and finally output is converted into 2.14 format."

Entonces la salida esta en otro formato, siendo los primeros 2 bits parte entera + signo y los 14 restantes decimales. Una forma de pasar de q2.14 a q1.15 simplemente hacemos un shift a la izquierda. Entonces el número en q1.15 es 0011 1111 1111 1110 que es aproximadamente 0.5... Hay algún factor más que me está faltando para llegar a 1. Voy a investigar la FFT para ver si cambia de formato.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 13 de Mayo de 2017, 18:59:06
Finalmente puedo probar simulando en el uC los datos como entrarían por el ADC, es decir, con un offset de 2048 cuentas. Con esto puedo probar la forma de pasar esos datos a q15.
Para ello hago este código de testeo:

Código: C
  1. float fltSinWave[64];
  2.         q15_t q15SinWave[64];
  3.         uint16_t uintSinWave[64];
  4.         q15_t q15FFT[128];
  5.         q15_t q15MAG[64];
  6.         uint32_t F=1562;
  7.         uint32_t Fs = 10000;
  8.         uint8_t i;
  9.         for(i=0;i<64;i++)
  10.         {
  11.                 // Seno discreto FLOTANTE
  12.                 fltSinWave[i] = (sin(2*M_PI*i*F/Fs));
  13.                 // Seno discreto en uint16_t Así es como lo leería el ADC si le metiera un senos de +- 1.65V
  14.                 uintSinWave[i] = (uint16_t)((fltSinWave[i] * 2048) + 2048);
  15.                 // Esta es la propuesta para obtener el Q15
  16.                 q15SinWave[i] = (q15_t)((uintSinWave[i] - 2048) << 4);
  17.         }
  18.  
  19.         // Preparo el array de la FFT
  20.         for(i=0;i<128;i+=2)
  21.         {
  22.                 q15FFT[i] = q15SinWave[i/2];
  23.                 q15FFT[i+1] = 0;
  24.         }
  25.         // Calculo la FFT
  26.         arm_cfft_q15(&arm_cfft_sR_q15_len64, q15FFT, 0, 1);
  27.         // Calculo la magnitud de cada punto
  28.         arm_cmplx_mag_q15(q15FFT, q15MAG, 64);

Entonces, primero creo un seno en flotante, de -1 a 1. Luego lo paso a un array de uint16, primero multiplicando por 2048 y luego sumando el offset. Ese es el seno más grande que puede entrar.
El resultado de ese array es: 2048, 3750, 3940, 2449, 601, 38, 1260, 3182, 4095, 3190, 1270, 40.... Como vemos arranca en 2048.
Luego hago una transformacion sugerida, la cual es restar los 2048 de offset para que quede un número int16 y luego subir los 4 bits que faltan a la izquierda.
Los siguientes puntos son iguales al anterior, prepar el array de la FFT y luego hago FFT y saco magnitud.

Probando esto, obtengo el mismo resultado que trabajando todo con q15, entonces ya tengo la forma de pasar de valores del ADC a formato q15, hacer la FFT y calcular la magnitud de forma correcta (excepto por un "x2" que me falta encontrar).

Saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 13 de Mayo de 2017, 19:52:14
Excelente, ya casi tienes esa parte, ahora si podrás notar los resultados...

Fijate que me recordaste algo: Cuando desarrolle lo de la FFT, pase por muchas cosas parecidas, como era frustrante ver que no salian los resultados o los signos de las operaciones...
 
Precisamente termine creando tablas de frecuencias como la que hiciste, para corroborar que salieran bien los bines de la FFT.

Luego, cuando la senoidal jalaba perfectamente, probaba con una tabla de onda cuadrada y otra triangular y pfff, de nuevo, datos falsos, componentes erroneas y regresar de nuevo a corregir el código, etapa por etapa de la FFT...

Quizas el proceso fue mucho más frustrante para mi de que lo que ha sido para ti, debido a que no use una libreria como tal para la FFT. En aquel entonces, la única librería que tenía microchip estaba plagada de errores, así que ni para jugar con ella.

Lo que termine haciendo fue leer muchísimo e implementarla en ensamblador, y eso de los números y los signos, que  si había que escalarlos al final... y luego hacer un algoritmo super eficiente y rápido para obtener la raíz cuadrada y sacar la magnitud etc... fue mucho dolor de cabeza pero el conocimiento queda y al final vale la pena...

Saludos.
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 14 de Mayo de 2017, 09:58:27
Este es un test interesante, es largo el video pero explica mucho:



Como realizas el cómputo de lo que muestras?
Porque hay 2 efectos que son vistosos, pero ireales.
El primero es que hay una "latido" en los bines, es como si fuesen "bailando" con una frecuencia de 0.5Hz o algo así
El segundo es que nunca tienes bines puros, siempre tienes perdida (frequency leckage) alrededor del bin y simpre es la misma cantidad, en ves de tener un bin tiene una "campana". Eso no parece real. A medida que la frecuencia va subiendo, llega un punto que pasa por la frecuencia central de un bin de la FFT, en ese momento deberías tener un baston perfecto. Luego entre 2 frecuenicas centrales hay un efecto que creo es frequency leackage que hace que el espectro valla pasando de un bin al siguiente "desparramando" un poco el espectro...

No digo que el resultado que muestras no sea lindo, todo lo contrario, es muy vistos. Pero debe tener algo de procesamiento adicional porque no me parece real y no me permite comparar con lo que yo obtengo.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: Picuino en 14 de Mayo de 2017, 13:33:18
Me suscribo.
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 14 de Mayo de 2017, 15:15:01
Este proyecto terminó siendo una gran fuente de aprendizaje. Entre post y post y decenas de cosas que aparecen y enzeñan algo.

Voy a tratar de ordenar los pensamientos y escrivir lo más claro posible.

El primer punto que nunca estudié es que iba a pasar cuando el refresco de la pantalla (SPI + DMA1) compita por el bus con el muestreo de mediana velocidad (ADC + DMA1). En mi caso el micro (STM32F103RB) posee un solo módulo DMA y 7 canales. Cada canal puede manejar un periferico distinto. Pero la RAM es una sola y puede ser un problema si el SPI quiere LEER la RAM para escrivir en el SPI y a la vez el ADC quiere ESCRIVIR la RAM con los datos del ADC.

En los micros ARM hay muchas fuentes de interrupcion y a veces un mismo módulo funcional puede utilizar mas de 1 interrupcion. Por ejemplo, el módulo de muestreo y almacenaje tiene un TIMER (el nro 3) que cada 1/40.000 = 2.5uSeg interrumpe (en mi caso solo para hacer un toggle en un led y verlo en el analizador lógico) y a la vez dispara al ADC para su conversion. A la vez el DMA está configurado para mover datos del ADC a la RAM. Se configura un buffer de 256 puntos y el DMA se encarga de moverlos, cuando llega a la muestra 256 vuelve a empezar de 0 pisando los datos previos. Para usar los datos el DMA tiene una interrupcion por "buffer mitad lleno" (en este caso se dará cada 3.2mseg). En esa interrupcion debemos poner el código que procese las primeras 128 muestras. Tambien posee una IRQ por transferencia completa, en la que deberemos poner el codigo que procesa las segundas 128 muestras. Pero que pasa si el tiempo que tardamos en procesar es mayor a 2.5useg? Puede pasar que, como estamos dentro de una interrupcion, la del DMA, no se pueda ejecutar la del TIMER 3. En este caso, el problema es menor, ya que como el disparo del timer3 hacia el ADC no es por software, aunque la IRQ no se dé, el disparo se hará igual por hardware, pero no tendría el toggle del LED que sí está por software.

Todo esto se resuelve con las PRIORIDADES de las interrupciones. Generalmete en los PIC solo hay 1 o 2 prioridades, en los cortex M hay un sistema de prioridades mucho más avanzado. Pudiendo hacer grupos con subprioridaes entre otras cosas.

Fijar las prioridades en los ARM es algo que siempre me pega en la cabeza y cuando algo complejo no funciona, muchas veces viene por aquí el tema.

Quiero mostrar entonces un poquito este tema.

Primero condiguro el TIM3 para que dispare cada 2.5useg. Con un reloj de 64MHz obtengo eso con un prescaler de 0 y un counter de 1600. Lo configuro como disparo del ADC y para que interrumpa. En la ISR pongo el toggle de un LED para medirlo con el analizador.
Configuro tambien el ADC, para que convierta con el disparo de TIM3, sin interrupcion por conversion finalizada, pero con DMA. En el DMA configuro la interrupcion con prioridad mayor que el TIM3 (mayot priotidad se consigue con un número menor en el registro).
Luego pongo el código de la FFT dentro de la interrupcion por medio buffer lleno.

Corro el programa y veo el analizador:

 - Tienes que ingresar para ver archivos adjuntos -

Luego paso la interrucion del timer a mayor prioridad que la del DMA y veo esto:

 - Tienes que ingresar para ver archivos adjuntos -

Bien, teniendo en cuanta esto, en la proxima veremo como definir las prioridades para que todo funcione de la mejor forma posible.

Saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 14 de Mayo de 2017, 15:59:29
Configurando el refresco de la pantalla LED

Ahora veamos que pasa con la pantalla LED.
Lo primero que quiero es un refresco de 60 cuadros por segundo. Esto es, barrer la pantalla completa cada 16.666mSeg. Esta pantalla tiene 16 filas por lo que cada fila requiere 1.041mSeg
Para el barrido vertical uso el TIM1, configurado para que interrumpa cada 1.041 mseg. A 64MHz lo consigo con un prescaler de 64 y un counter de 1041. En cada pedido de interrupcion se actualiza se pone en blanco la pantalla, se actualiza la fila actual, se prepara el DMA para que transmita todos los datos y se sale de la interrupcion. Cuando el DMA transmite todo los datos interrumpe y en dicha interrupcion hacemos el pulso de LAT y quitamos la señal de blank. En este caso no hay problemas con la prioridad de la interrupcion, ya que cuando la del DMA quiere interrumpir, el TIMer ya termino su ISR. Por lo tanto pueden tener la misma prioridad.

Veamos los tiempos que conseguimos con ese refresco:

 - Tienes que ingresar para ver archivos adjuntos -

Si hago un zoom en una sola transmision vemos:

 - Tienes que ingresar para ver archivos adjuntos -

Con 60 Hz tengo una imagen bien estable. Con 30Hz se ven un pequeño flikering...

Saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 14 de Mayo de 2017, 16:29:10
Todo Junto

Ahora veamos como juntar el muestreo + el procesamiento + el refresco del cartel.

El primer punto son la prioridades.
El evento de mayor prioridad es el muestreo del ADC. Ese evento está garantizado por hardware, nada que haga en software me va a afectar el muestreo. Pero si yo quiero ver cuando el timer me dispara al ADC, debo ponerlo que interrumpa y dicha interrupcion debe ser la mas alta. Le pondré prioridad 1 al TIM3.
El procesamiento se da en la interrupcion por DMA del ADC y debo darle prioridad porque es un evento rápido y el tiempo de procesamiento es lento. a 40KHz tengo una interrupcion cada 128 muestras -> cada 3.2mseg. Como vimos en la imagen anterior el procesamiento parece durar 170 useg (ya veremos como verificar esto a la perfeccion). Le daremos al DMA1 canal 1 la prioridad 2. Luego tengo el refresco de pantalla, el cual parece ser el más sobrado de tiempo, por lo que le dare la prioridad 3, tanto al timer1 como al DMA1 canal 5:

 - Tienes que ingresar para ver archivos adjuntos -

Bien, si probamos ahora el sistema completo obtengo:

 - Tienes que ingresar para ver archivos adjuntos -

Como vemos todo parace funcionar de maravillas.

Finalmente, este es el resultado en la pantalla, de un barrido en frecuncia con el Vumetro recientemente configurado y optimizado para Fs=40KHz


Ahora creo que estamos mucho mejor y ya con los tiempos de procesamiento medidos podemos ver que cosas se pueden mejorar.

Saludos!
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 19 de Mayo de 2017, 21:14:20
Estoy analizando circuitos para amplificar un poco la señal de audio de entrada.

Que les parece esta opción?

 - Tienes que ingresar para ver archivos adjuntos -

No estoy seguro la amplitud de la señal de un reproductor de mp3 o la salida de audio de un celular... Tendría que hacer una medicion para ajustar la ganancia y quizá poner un preset para ajustar diferentes tipos de señal...

Saludos
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 19 de Mayo de 2017, 21:48:25
Citar
Como realizas el cómputo de lo que muestras?
Porque hay 2 efectos que son vistosos, pero ireales.
El primero es que hay una "latido" en los bines, es como si fuesen "bailando" con una frecuencia de 0.5Hz o algo así
El segundo es que nunca tienes bines puros, siempre tienes perdida (frequency leckage) alrededor del bin y simpre es la misma cantidad, en ves de tener un bin tiene una "campana". Eso no parece real. A medida que la frecuencia va subiendo, llega un punto que pasa por la frecuencia central de un bin de la FFT, en ese momento deberías tener un baston perfecto. Luego entre 2 frecuenicas centrales hay un efecto que creo es frequency leackage que hace que el espectro valla pasando de un bin al siguiente "desparramando" un poco el espectro...

No digo que el resultado que muestras no sea lindo, todo lo contrario, es muy vistos. Pero debe tener algo de procesamiento adicional porque no me parece real y no me permite comparar con lo que yo obtengo.

Saludos!

Efectivamente has notado ese efecto, lo cual solo es notorio ante a aquellos que dominan el tema de FFT y saben como deberían de ser las señales...

Ocurren 3 cosas:

La PRIMERA es qué mi FFT es de 128 muestras para tener un vector final de 64 (la FFT entrega 128 pero la mitad es SIMETRICA).
Lo que ocurre ahí es que la pantalla es de 256 pixeles, en donde dejo 1 espacio de separación entre bines, pero me faltarían 64 bines más para acompletarla...

Entonces, lo que estoy haciendo, es "extrapolar" bines intermedios para precisamente rellenar los bines faltantes y tener 128 barras qué graficar...

Bien podría haber capturado mejor una FFT de 256 muestras de ADC y graficar las 128 que entrega, pero eso rompe dos puntos a mi consideración importantes:

1.- Una FFT de 256 muestras tiene más operaciones butterfly, lo cual NO es el doble de la FFT de 128 muestras sino más, al ser estas una potencia de 2.
Eso haría que se rompiera el paradigma del tiempo REAL y capturara menos FFTs o perdiera muestras de audio, lo cual se vería reflejado en los agudos...

2.- Después de años de hacer analizadores de espectro, la verdad es que, la FFT, al tener precisamente (como mencionas), bines MUY DEFINIDOS, solo cuando cambia la amplitud entre ellos cuando la frecuencia tiende a cambiar (levemente) entre ellos, lo cual se asemeja mucho a filtros pasabanda de ALTISIMO Q...

Eso es PRECISO pero no ESTETICO, pues cuando ves una versión de un "analizador de espectros" hecha con N filtros pasabandas y multiplexores, puedes notar que SIEMPRE entre los "bines" de esos analizadores hay una continuidad, dado el bajo Q de los filtros pasabanda....

A simple vista, puedes SABER cuando un analizador de espectros está hecho a matemática pura FFT o esta hecho con filtros pasabanda, e incluso por la forma de onda hasta puedes determinar qué tanta calidad o factor de mérito Q tienen sus filtros...

Entonces, el intercalar "bines" extrapolados, crea precisamente ese efecto, qué no se vea como una FFT pura y dura, y sí con un toque más estético (simulando filtros pasabanda)...

La SEGUNDA cosa qué ocurre es que la amplitud de mi FFT NO es lineal...
Esto es porque si te das cuenta, cuando metes audio a bajo volumen no se aprecian bien determinadas frecuencias y a alto volumen tiende a "aplanarse" debido a que estas cerca de la saturación del ADC...

Entonces, del vector de muestras qué obtengo como resultado de la FFT, aplico un filtro exponencial (antilogaritmico) que me permita ver mas la señal como un VUMETRO de audio, que como un medidor lineal...

Esa por ejemplo, es otra diferencia de cuando ves un VUMETRO hecho con el viejo y conocido LM3914 (lineal) versus el LM3915 (logaritmico)

La TERCERA cosa qué has notado, es ese vaiven generaro, el cual puedes ver en tu FFT también, (se nota menos por ser lineal y no tener extrapolaciones).
Este fenomeno o tremulo ocurre cuando la señal capturada termina en un valor diferente de 0, es decir, que si sampleas una señal senoidal, y su periodo no coincide con el numero EXACTO de muestras capturadas, lo que verás es que la FFT calcula ese valor como un pequeño desplazamiento en DC y que tiende a afectar a las frecuencias adjacentes y en conjunto a todas.

Se nota mucho cuando pones señales periódicas y hay varias maneras de MITIGAR ese efecto (ventana hamming, GAUS, Cuadrática etc) pero no tiene caso aplicar una ventana de amplitud a las muestras de audio pues éstas NUNCA van a ser periódicas...
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 19 de Mayo de 2017, 22:18:41
Citar
El primer punto que nunca estudié es que iba a pasar cuando el refresco de la pantalla (SPI + DMA1) compita por el bus con el muestreo de mediana velocidad (ADC + DMA1). En mi caso el micro (STM32F103RB) posee un solo módulo DMA y 7 canales. Cada canal puede manejar un periferico distinto. Pero la RAM es una sola y puede ser un problema si el SPI quiere LEER la RAM para escrivir en el SPI y a la vez el ADC quiere ESCRIVIR la RAM con los datos del ADC.

Bueno, a lo mejor en un ARM la tienes más fácil pero ahora imaginate hacer eso en un PIC...

El método qué propones es util y funciona, quizás porque en este caso solamente tienes 2 eventos: Capturar (y procesar) y Graficar...

Lo resuelves estableciendo el orden de las interrupciones, cosa qué es más "fácil" de hacer en un ARM dado sus multiples prioridades de interrupción pero no en un PIC...

En mi caso, en el PIC, lo procesos de la captura de muestras de audio, FFT, y graficación, en realidad son SECUNDARIOS pues el propósito principal del PIC, es estar leyendo el archivo de audio desde una tarjeta uSD y llenar el buffer de RAM del decodificador VS1063a, o sea, el objetivo PRIMARIO de mi sistema es reproducir audio, sin PAUSAS, por eso es qué la FFT e incluso graficación son solo procesos secundarios...

Habiendo explicado esto, lo que hice para resolver el problema fue lo siguiente:

Uso un solo timer MAESTRO, el cual está a 64 hz (para refrescar la pantalla a 64 FPS en lugar de 60).  Esto es porque es más fácil usar un refresco de tiempo en potencias de 2 que en decimal...

Ahora bien, lo que hago, es que ese timer dispara el evento de capturar muestras, y durante ese intervalo de tiempo, capturo y proceso todos los bloques de muestras y FFT posibles, tal qué en 64 Hz, puedo tener un máximo de 4 FFTs capturadas y guardando los picos de señal máximos...

pero no se cumple a rajatabla el que SIEMPRE tenga 4 FFTs, pues ocurre que además debo de graficar, tal que a veces de esas 4 partes de tiempo, ocupo 3 para FFT y 1 para graficar, lo cual hace que capture el audio 3/4 = 75% del tiempo y 1/4 (25%) del tiempo grafique los bines (más gráficos, el string de la canción rote etc)....

Ocurre también, que debo de leer el archivo de audio de la tarjeta uSD y enviarlo al decodificador VS1063A

Entonces, lo que hice, fue hacer un toogle cada 64 hz, lo cual me devuelve 32 hz...

En el primer periodo de 32 Hz, lo uso para FFT y graficación, en 32 Hz caben 8 FFT, pero debido a la graficación, de esas 8/8 ocupo 7/8 = 87.5 % del audio capturado y 1/8 en graficarlo, eso es mejor al 75% obtenido usando 3/4 partes del tiempo si usara solo 64 Hz para hacer todo...

En el segundo periodo de 32 hz, solo capturo audio y FFT pero uso el resto del tiempo para rellenar el buffer de audio del VS1063 y así no tener pausas en la reproducción...

Originalmente el tiempo era de "refresco" del VS1063A era de 1/8 luego paso a 1/16... 1/32, la razón es que si bien se puede "llenar el tanque" del VS1063a cuando este ha consumido todo el buffer de audio, es mejor rellenar su tanque cuando está al 70% de capacidad...

La analogía: Pasarías más tiempo en la gasolinera llenando el tanque por completo (45 lts) que solo rellenando ese cachito que le haga falta (10 o 15 lts)...

Jugar con los tiempos fue un dolor de cabeza y acomodarlos aun más, para qué todos los procesos corrieran sin interrupciones, se capturaran el mayor número posibles de muestras de audio, y si bien nunca voy a tener el 100% del tiempo de audio capturado, el tener al menos casi el 90% ya es mucha ganancia...

En resumen: Puedes acomodar tus procesos de graficación y FFT si los vuelves "sincronos" y distribuyes el tiempo en partes fraccionarias (en telefonía celular se llama TDMA) en lugar de dejar tus procesos asíncronos y que se resuelvan por interrupciones...
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 19 de Mayo de 2017, 22:23:38
Estoy analizando circuitos para amplificar un poco la señal de audio de entrada.

Que les parece esta opción?

 - Tienes que ingresar para ver archivos adjuntos -

No estoy seguro la amplitud de la señal de un reproductor de mp3 o la salida de audio de un celular... Tendría que hacer una medicion para ajustar la ganancia y quizá poner un preset para ajustar diferentes tipos de señal...

Saludos

El primer ADC, que usas para partir la alimentación en 2 es inecesario, puedes ahorrartelo y poner un divisor de voltaje directo en la entrada NO inversora del op amp que amplifica...

Los valores que usé Yo para el  op amp que amplifica son:

Rin = 680 ohms

R retroalimentacion = 2.8K

Cap In = 220 nanofaradios (evitará que satures siempre los bajos)

Cap retroalimentación = 1 nf

Es importante tener un "baja impedancia" de entrada en el amplificador pues así como lo tienes el capacitor de entrada de 10 uf quedará con mucha carga residual de DC...

Saludos...
Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: vixctor en 19 de Mayo de 2017, 22:37:54
Por cierto, hace tiempo (8 años ya  :D) cuando hice mis primeros analizadores de espectro con la FFT pura y dura, así es como se veía...



Lo cual si bien era la representación fiel y matemática de la señal de audio NO me gustaba...

El circuito estaba hecho con 2 PICS 18F452 (ya obsoletos)

1 PIC generaba los gráficos en VIDEO y el otro PIC estaba encargado de la captura y procesado de la FFT...

Después fue cuando le añadí todos esos "artilugios" no reales pero estéticos...

PD: Viendo como se veía en aquellos años parecieran graficos de pasto mal cortado...  :-)


Título: Re:[Proyecto] Vúmetro con pantalla LED
Publicado por: elgarbe en 28 de Mayo de 2017, 15:35:23
Los valores que usé Yo para el  op amp que amplifica son:

Rin = 680 ohms

R retroalimentacion = 2.8K

Cap In = 220 nanofaradios (evitará que satures siempre los bajos)

Cap retroalimentación = 1 nf

Con esos valores la Fc sería 1/(2 x 3.1415 x 0.000000001 x 2800) = 56.8KHz es correcto???
para adaptar la señal de entrada, vos usaste una sola etapa?

Voy a provar con este circuito:

 - Tienes que ingresar para ver archivos adjuntos -

y los valores los iré probando para obtener el mejor resultado. Voy a tener que cambiar R12 por un preset para ajustar ganancia, aunque no estoy seguro entre que valores debería poder variar.

Saludos