jueves, 20 de diciembre de 2012

Filtrado digital con DSPIC.

En entradas anteriores ya he hablado de los DSPIC y los PIC24, en concreto hablamos de la gama media-alta de estos DSC de Microchip, los DSPIC33FJ, y los PIC24H. Estos DSC, como comentamos pueden funcionar hasta 40MIPS, que, aunque comparado con los DSP de TI, los PIC32, o incluso los PIC24E no es gran cosa, es una velocidad alta. Además de esa alta velocidad, los DSC de Microchip incorporan ciertas características que los diferencian de los PIC de 8 bits, como por ejemplo el conversor AD, que llega a velocidades de hasta 1,1Msps para 10 bits, y 500ksps para 12 bits. Otra característica importante del conversor, y que los acerca a los DSP de TI, es que podemos olvidarnos de disparar nosotros el conversor, ya que lo podemos programar para que realice las lecturas que nosotros queramos continuamente. Y ahora nos podemos preguntar…. ¿para que?
En esta entrada voy a introduciros a la implementación, de forma muy sencilla, de filtros digitales, que no son ni más ni menos que filtros como los analógicos, pero programados dentro de un microcontrolador, DSC, DSP o como queráis llamarlo. Lo primero que tenemos que saber es … ¿para que sirven?, y no hay nada como un ejemplo para describir su utilidad. Imaginemos que estamos controlando un inversor para inyectar corriente a la red. Como cualquier elemento conmutado, los inversores generan mucho ruido, por lo que la tensión de la red que nosotros adquiramos podrá en ciertas lecturas no tener el valor real, y esto es un problema porque si detectamos mal un paso por cero, e inyectamos corriente positiva cuando estamos en el semiciclo negativo, pasará de todo menos cosas buenas. Para esta situación lo que podemos hacer es filtrar la tensión que leemos para que solo deje pasar la frecuencia de 50Hz, de esta forma eliminamos el ruido de conmutación, además de cualquier otro ruido que exista, pero… no podemos hacer esto con filtros analógicos?, cierto! y además ahorraremos recursos del microcontrolador, pero ¿que pasa si en determinado momento, nuestro circuito se ve afectado por otro tipo de ruido? deberíamos cambiar el filtro, o incluso añadir otro en serie para aumentar su orden, cosa imposible si se trata de un circuito ya montado en una placa PCB… si implementamos un filtro digital,  tan solo tendremos que cambiar el firmware de nuestro dispositivo y se solucionará el problema, lo que añadirá robustez a nuestro sistema.
Diseñar un filtro, no es algo trivial, ya  que requiere de ciertos conocimientos teóricos, por lo que  vamos a recurrir a una web que nos va a calcular el filtro que nosotros queramos, además de darnos el código c para meter en nuestro microcontrolador!  mola eh!. la página en cuestión es esta, y tan solo tenemos que decirle el tipo de fitro, la frecuencia de corte, y su orden. En mi caso probado el mismo filtro pero cambiando el orden. El filtro que he utilizado es un filtro paso bajo, de butterworth, con una frecuencia de  muestreo de 10kHz, y una frecuencia de corte de 50Hz. El DSC donde lo he implementado es el DSPIC33FJ12GP202. La elección de este micro ha sido porque lo puedo simular en proteus, que es donde he hecho las pruebas. Y la señal a muestrear, es una señal bastante fea que he generado sumando varias senoidales, además de una cuadrada de ciclo de trabajo del 10%, esta es la señal.
image
Y este su espectro armónico. image Se observa que la frecuencia fundamental es de 50Hz, pero tenemos armónicos en 150, 200, 400, 500, 600, 800….. El primer filtro que voy a probar es el de segundo orden, el código que me genera la página web lo he metido dentro de una función y queda así.
unsigned int filtrado2(unsigned int lectura){
        xv[0] = xv[1]; xv[1] = xv[2];
        xv[2] = lectura / GAIN;
        yv[0] = yv[1]; yv[1] = yv[2];
        yv[2] =   (xv[0] + xv[2]) + 2 * xv[1] + ( -0.9565436765 * yv[0]) + (  1.9555782403 * yv[1]);
        return yv[2];
}
En donde GAIN es un valor que está en un #define. La salida la llevo al puerto B, que a través de un conversor digital analógico, obtenemos la siguiente señal.
image
Se observa que la señal ha  mejorado muchísimo, y aunque no es senoidal completamente, (el armónico a 150 Hz no lo elimina…), es mucho mejor que la anterior. A continuación vamos a compararla con la señal que obtenemos con el filtro de 4º orden, cuyo código es el siguiente:
unsigned int filtrado4(unsigned int lectura){
        xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4];
        xv[4] = lectura / GAIN;
        yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4];
        yv[4] =   (xv[0] + xv[4]) + 4 * (xv[1] + xv[3]) + 6 * xv[2] + ( -0.9211819292 * yv[0]) + (  3.7603495077 * yv[1]) + ( -5.7570763791 * yv[2]) + (  3.9179078654 * yv[3]);
        return yv[4];
}
El resultado es mucho mejor.
image
En este caso se eliminan por completo todos los armónicos, dejando únicamente la fundamental. Además observamos que la fase ha cambiado 180º, tal como nos dice que ocurrirá la página web.
Como en esta entrada me he extendido un poco, en la próxima entrada os contaré cuanto cuesta (en ciclos, ya que por ahora no nos cobran por filtrar) realizar estos dos filtrados, y formas de optimizarlo.

2 comentarios:

  1. Hola. Puedes especificar en qué página web calculas los coeficientes de los filtros.
    Muchas gracias.

    ResponderEliminar
  2. "Lectura" es el dato que viene del pin analogico del micro?

    ResponderEliminar