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
window4. 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 filterBueno 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.0Vemos 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:
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!