Autor Tema: MULTIPLICACION EN FLOTANTE.  (Leído 4556 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
MULTIPLICACION EN FLOTANTE.
« en: 28 de Septiembre de 2008, 17:22:07 »
Hola , estoy intentando hacer un filtro fir, y me encuentro con que no va del todo bien para coeficientes flotantes, es decir , las muestras de audio muestreadas y pasadas por el filtro a la salida del filtro tienen una calidad de audio buena pero tremendamente bajas en amplitud, y querria saber a que se puede deber, y si tendria que configurar algo para hacer estar conversiones, aunque ya he tocado el reguistro CORCON del dspic.

Un saludo desde Malaga.

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: MULTIPLICACION EN FLOTANTE.
« Respuesta #1 en: 29 de Septiembre de 2008, 23:37:50 »
Tu dices que estas haciendo un FIR y que no te sirve, entonces, varias cosas:

1. ¿Como es el filtro? pasbajas? pasaaltas? pasabanda? rechazabanda?

2. ¿Cuales son los parámetros del filtro?  banda de paso, banda de rechazo, frecuencia de muestreo.

3. Como es un FIR, que tipo de ventana, rectangular, triangular, hanning, hamming, blackman, etc etc ..

Ya lo simulaste?? ... Siento que estas haciendo todo mal  :?  ... entonces te voy a explicar con un pequeño ejemplo:

Pasos:

1. Antes de pegar piñatazos por todos lados y dejar de arrancarnos el cabello, debemos entender que en DSP las cosas nunca salen si no sabemos lo que hacemos. Para evitar esta situacion, nos conseguimos ya sea con un amigo o en tu facultad un programa para simulación y diseño de sistemas. En este caso, el mejor para mi es MATLAB. Evitemos entrarle a lo vaquero al C30, si es irresistible, desinstalalo.  :)

2. Ya que a mi me gusta MATLAB, seguiré el ejemplo con MATLAB. La herramienta (toolbox) para diseño de filtros se llama fdatool, digitamos FDATOOL en la linea de comandos e imediatamente se abre una ventana con el toolbox:



3. Digamos que vamos hacer un filtro pasobajos, entonces seleccionamos lowpass en response type.

3. Como querés un FIR, en seleccionamos FIR en design method y seleccionamos Window del menú deplegable. Y se me ocurre una ventana rectangular, entonces selecciono rectangular en window

4. Especifico el orden del filtro, yo seleccione 10, como te darás cuenta el filtro FIR necesita de un orden bastante grande para que sea un buen filtro (en su contraparte con el filtro IIR el cual con un orden bajo se obteniene buenos resultados); como el orden es grande, esto requerirá mucho mas cálculo y mas CPU (un importante aspecto de diseño!!).

5. Seleccionamos la frecuencia de muestreo (Fs), 1000Hz, recuerda que en el procesamiento digital la máxima frecuencia representable es la mitad de Fs, en este caso, la máxima frecuencia que podemos representar será 500Hz. Toda señal de frecuencia superior sufrirá aliasing, si no se filtran frecuencias superiores tendras un macarron de señales y ruido. Para evitar el aliasing primero se debe filtrar la señal con un filtro analógico pasobajos con frecuencia de corte en 500Hz, recomendable el BESSEL el cual casi casi lineal.

6. Selecionamos la frecuencia de corte del filtro FIR, para el ejemplo, haremos un filtro pasobajos con corte en 100Hz.

7. Damos a Design filter

Bueno asi me queda:



Ahi podemos ver la respuesta en frecuencia del filtro, y tambien podemos ver el comportamiento en el tiempo ante escalones e impulsos. Yo utilizo estas respuestas para verificar el funcionamiento en C30. Pero antes debemos, obtener los coeficientes, como el orden es 10 debemos esperar 10 o 11 coeficientes depende de la ventana que seleccionamos. Para ver los coeficientes yo utilizo el generador de header, para hacer esto, damos en targets -> generate c header ...   ahi no hay mucho que explicar ... yo selecciono single precision float en export as y guardo el .h en cualquier parte.

Ahora, genero la respuesta ante un impulso, para ello, doy en step response, este es un icono en la parte superior:



Despues copio, todas las muestras de la respuesta al escalon, los datos que tengo son (en orden de las muestras):

0.0, 0.040, 0.126, 0.255, 0.414, 0.585, 0.745, 0.874, 0.960, 1.0, 1.0

Vemos que el filtro FIR se estabiliza casi 10 muestras despues, si el filtro es de orden 32, este se estabilizará cuando se acerque la 32ª muestra, esto es una particularidad de este filtro. El filtro FIR es muy malo para sistemas de control, imaginemonos una muestra atrasada 32 muestras!!!. 

Ahora, falta implementar el filtro en C30, esto es muy facil, recordemos la ecuacion de un filtro FIR:

y[n]=b_0 x[n] + b_1 x[n-1] + ... + b_N x[n-N]

El algoritmo consiste en tomar un muestra y multiplicarla por el primer coeficiente, despues la muestra pasada con el coeficiente 2, despues la muestra pasada pasada por el coeficiente 3 y asi sucesivamente.

Mi código de prueba consiste en un escalon de magnitud 1.0 y tomaré 11 muestras del filtro, cada muestra la voy a guardar en un arreglo de salida de 11 datos. Los coeficientes los tomé del archivo .h que generé con MATLAB:

Código: [Seleccionar]
const float b[11] = {
  6.650492007e-018,  0.03989988193,  0.08607915789,   0.1291187257,   0.1595995277,
      0.1706054062,   0.1595995277,   0.1291187257,  0.08607915789,  0.03989988193,
  6.650492007e-018
     };
float entradas[11];
float salidas[11];
int i;
int muestra = 0;

for(i = 0; i < 11; i++)
{
      entradas[i] = 0.0;
}

while(muestra < 11) //Calculamos 11 muestras
{
entradas[0] = 1.0; //Escalon

// Calculo del filtro ...

salidas[muestra] = entradas[0]*b[0]; //Para asignar un primer valor al registro

for(i = 1; i < 11; i++)
{
salidas[muestra] += entradas[i]*b[i];
}

// Precalculo ..
muestra++;

for(i = 10; i > 0; i--)
{
entradas[i] = entradas[i-1];
}

}


Utilizo MPLAB SIM para simular el filtro y ver cada una de las 11 muestras, observemos que la respuesta ante el escalon da justamente lo mismo que la simulacion en MATLAB... con lo que concluyo que mi filtro esta bien y ya puedo utilizar el algoritmo para alguna aplicacion.




Verdad que estaba fácil!!! Espero que les sirva!
« Última modificación: 02 de Noviembre de 2008, 01:35:48 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: MULTIPLICACION EN FLOTANTE.
« Respuesta #2 en: 30 de Septiembre de 2008, 02:28:17 »
Uff, este pedazo de tutorial se merecería estar en un post aparte con un título que permitiera encontrarlo, blackcat.

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: MULTIPLICACION EN FLOTANTE.
« Respuesta #3 en: 30 de Septiembre de 2008, 14:29:49 »
Muchas gracias por la ayuda , el unico problema era la ganancia de mi filtro, como dije, la entrada a mi filtro es una cancion de audio en tiempo real y la salida dicha cancion pasada por el filtro, la salida era correcta pero de amplitud baja y no estaba seguro si el problema estaba en el filtro o debia configurar el tipo de multiplicacion a traves del registro corcon.

Para conseguir los coeficientes use funciones de matlab pero en ellas no aparece la ganancia como parametro, ahi estaba mi error.

De todos modos gracias por la gran respuesta.

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: MULTIPLICACION EN FLOTANTE.
« Respuesta #4 en: 30 de Septiembre de 2008, 19:09:19 »
Todos los filtros que genera MATLAB son de ganancia 1 ... la única forma que se te atenúe es que las frecuencias del audio sean superiores a la frecuencia de corte, en caso de que sea un filtro pasabajas.

Ademas, a que frecuencia de muestreo estas trabajando?? ... entiendo que haces operaciones en punto flotante, esto aumenta excesivamente el tiempo de cálculo. Supongamos que estas a 44100Hz .. esto significa un tiempo de muestreo de 22us .. esto implica que tu filtro calcule una muestra en un tiempo menor. El dsPIC33F a 40MIPS tarda aproximadamente 8us calculando una multiplicación en punto flotante de precisión simple. Si tenes 5 multiplicaciones significa que el tiempo de cálculo ronda los 40us (despreciando sumas y movimiento de datos!!!), con lo cual, el muestreo de 44100Hz es inútil y el funcionamiento del filtro no es adecuado.



« Última modificación: 30 de Septiembre de 2008, 19:28:28 por blackcat »
Control Automático, DSP & Microcontroladores