Mostrando entradas con la etiqueta C30. Mostrar todas las entradas
Mostrando entradas con la etiqueta C30. Mostrar todas las entradas

miércoles, 16 de enero de 2013

Primeros pasos Robot.

Después de bastante tiempo sin escribir nada he vuelto!! la verdad que ahora ando bastante liado entre el trabajo y las pruebas del proyecto de final de carrera, pero bueno, hay tiempo para todo. También he estado ocupado intentando hacer funcionar un par de proyectos en MPLABX, sin éxito de momento, por lo que pospondré su publicación a más adelante. En esta entrada os voy a comentar ese proyecto que quería empezar de un robot equilibrista. Lo primero que hice, como ya os comenté fue pedir unos motores competentes, y una vez me llegaron monté el que sería el primer piso de mi robot. Esta parte del robot va a ser donde va a ir alojado todo el módulo de alimentación de 12, 5 y 3,3 voltios, y la parte del control del motor, que como os comenté va a ser un L293D.


  El robot en principio está siendo alimentado con 12 voltios de una fuente de alimentación, la idea es que sea alimentado con una batería. Las tensiones que se obtienen son de 12 voltios (de la entrada), para la alimentación de los motores, 5 voltios por si acaso… y 3,3 voltios para el microcontrolador, que finalmente no será un PIC32, ya que la mini placa que iba a utilizar sufrió un pequeño accidente, por lo que el control lo voy a hacer con un DSPIC33FJ, que como ya sabéis funciona a 40MIPS, más que suficiente para nuestra aplicación. Además una ventaja enorme es que se encuentra en encapsulado PDIP, lo que facilita enormemente el prototipado.
En la parte superior del robot, además del microcontrolador, también encontraremos el acelerómetro, en un futuro supongo que un giroscopio, y un módulo bluetooth para comunicarnos con el robot.
No se si se aprecia en la imagen, pero he tenido que añadir a la alimentación un condensador bastante grande, además de separar las masas de la parte del motor y la parte del DSPIC mediante una bobina ya que, cuando el motor arrancaba, el microcontrolador se reseteaba. Bien  pues esto es lo que tengo hasta ahora, lo próximo es probar un control proporcional sencillo a ver como responde el robot, aunque seguramente con ese control no pueda mantenerlo en pié, pero  por algo empezaremos!!!

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.

miércoles, 18 de julio de 2012

Osciladores y PLLs.

Después de 2 entradas hablando de nuestro servidor WEB, para cambiar un poco de tercio vamos a hablar de un elemento que es fundamental en nuestros diseños con microcontroladores, tanto que sin uno de estos, nuestro micro simplemente no funciona. Este elemento tan importante es el oscilador el cual nos va a dictar a la velocidad que que va a ejecutar nuestro microcontrolador las instrucciones, lo que permitirá que nuestro micro pueda realizar o no ciertas tareas.
El bloque del oscilador en todos los micros es muy parecido, y está compuesto por un cristal de cuarzo, que formará nuestro circuito tanque, y una puerta inversora para que se mantenga la oscilación. Si queremos frecuencias muy bajas de oscilación podemos sustituir el cristal de cuarzo por una red RC, aunque es muchísimo menos estable y no recomendable. Una vez tenemos generada nuestra señal de reloj, los microcontroladores nos ofrecen muchas posibilidades para poder modificar esa señal de reloj a nuestro antojo. A continuación tenéis el esquema del circuito oscilador de un PIC24H:
image
Como veis el bloque del oscilador es bastante complejo, pero sencillo de entender y configurar. En primer lugar tenemos el Bloque oscilador principal, en el que tenemos los dos pines OSC1 y OSC2 que van a la puerta inversora que nos generara la oscilación a la frecuencia del cristal. De la salida de este bloque, tenemos 2 caminos diferentes, podemos utilizar esta frecuencia como frecuencia de oscilación directamente, poniendo el registro NOSC en la posición XT, HS o EC, dependiendo de la velocidad del cristal, o podemos, mediante S3, entrar al PLL, del cual hablaremos más tarde, para modificar esta frecuencia. Una vez tenemos seleccionada la frecuencia de oscilación FOSC, pasamos por un divisor por 2 (recordemos que los PIC24 ejecutan una instrucción por cada 2 ciclos de reloj), y sacamos directamente la frecuencia de oscilación de los periféricos, y mediante el registro DOZE dividimos FOSC para seleccionar una frecuencia para la CPU.
Además de este path (camino) tenemos otros que utilizan  los osciladores internos del micro. Por una parte tenemos el oscilador RC de alta velocidad FRC, que mediante el registro FRCDIV podemos dividir para introducir en el multiplexor principal una frecuencia menor a FRC, o igual a FRC. La frecuencia principal de este oscilador la seleccionamos mediante el registro TUN.  Además la salida del multiplexor FRCDIVC la podemos introducir en el PLL para modificarla y adecuarla a nuestro propósito.
Los otros dos osciladores que quedan son el RC de baja frecuencia y el oscilador secundario. Estos osciladores, en general serán de baja frecuencia y se utilizarán para los relojes en tiempo real, para temporizaciones grandes mediante el TIMER1 o para el WDT.
Hasta ahora hemos hablado del PLL sin que os haya explicado lo que es realmente, así que de os voy a hablar ahora. Como hemos dicho el PLL es un bloque que nos modifica la frecuencia de oscilación, en la mayoría de los casos aumentándola pero, ¿No basta con utilizar un cristal de mayor frecuencia?, si, hasta cierto punto.
image
Existen limitaciones debidas a la fabricación de los propios cristales que hacen que sea difícil hacer osciladores de frecuencias muy elevadas, y los que hay a veces tienen precios excesivos, así que para suplir ese costo existen los PLL. Aunque los PLLs originalmente son elementos puramente analógicos, los que montan los micros son PLLs digitales, aunque su funcionamiento es bastante parecido. El esquema que teneis arriba corresponde al PLL de los PIC24h, y como veis tiene varios bloques. En primer lugar tenemos el registro PLLPRE el cual tenemos que seleccionar para que la frecuencia de entrada al bucle PLL esté comprendida entre 0.8 y 8MHz. A continuación tenemos el PLL, el cual es un bucle. Es este bloque el que vamos a utilizar para multiplicar la frecuencia. El factor de multiplicación lo establece el registro PLLDIV. Los valores que puede tener este registro depende del PIC, siendo tan solo de un valor (4), para algunos PIC18, o pudiendo valer hasta 512 valores para los PIC24, por lo que podemos conseguir cualquier frecuencia de oscilación. El ultimo bloque es un divisor de frecuencia. El valor minimo por el que podemos dividir la frecuencia es 2, por lo que la salda del PLL deberá ser del doble de la que queramos. Así pues la frecuencia de oscilación del micro vendrá dad por la siguiente ecuación:
image
Por ejemplo, si teneos un reloj de 10MHz, PLLDIV = 32, PLLPRE = PLLPOST = 2, tenemos:
image
Con lo que con un reloj de 10MHz, conseguimos 80MHz, que corresponden a 40MIPS.
Por último decir que la mayoria de las caracteristicas del bloque oscilador se pueden configurar mediante los bits de configuración, por lo que no es necesario trabajar con los registros.

domingo, 27 de mayo de 2012

Primera experiencia con PIC24H

Hola a todos!! en la entrada anterior os comentaba que me habían llegado a casa 2 DSCs de microchip de 16 bits. Tenia pedidos también dos microcontroladores PIC24H en concreto un PIC24HJ64GP202 y un PIC24HJ12GP202. Las características de estos son muy parecidas a las que describí en los DSPIC33FJ, con la salvedad de que estos no llevan un núcleo DSP.
Este fin de semana, en el poco tiempo que he tenido libre, me he decidido a probarlos con algunos programas muy sencillos, los típicos “Hola mundo”, ya que nunca había programado antes en C30, y la verdad, como ya comenté, es muy parecido a C18, así que en cuento a la programación no he tenido problemas.
Si que me ha surgido algún problema en cuento al programador, os lo resumo. Yo utilizo el PIckit2, que si que es compatible con este tipo de micros, pero al intentar programarlo desde MPLAB, me salía el siguiente mensaje:
Programming Target (26/05/2012  21:58:08)
PIC24HJ64GP202 found (Rev 0x3002)
Erasing Target
Programming Program Memory (0x0 - 0x2FF)
   PE Error: Using ICSP
Verifying Program Memory (0x0 - 0x2FF)
   PE Error: Using ICSP
PK2Error0027:  Failed verify (Address = 0x80 - Expected Value 0x290 - Value Read 0xFFFFFF)
PICkit 2 Ready
Al no saber lo que pasaba pregunte en el foro de ucontrol, y me sugirieron que actualizara el firmware del PK2 al más reciente, y así lo hice, lo bajé desde la página de microchip y mediante la aplicación Pickit2, yéndome a Tools > Download Pickit2 Operating System, actualicé el firmware y lo pude programar perfectamente.
Lo que más echo de menos en C30, es un archivo de ayuda para configurar los fuses, al estilo C18, que tenemos el Config settings file, en estos hay que ir al archivo .h del pic y ver allí las configuraciones que admite, que son muchísimas menos que en C18, por cierto.
Aquí os pongo un código sencillísimo que hace parpadear un led mediante retardos creados con bucles for.
   1: #include <p24hj64gp202.h>
   2:  
   3: _FICD( ICS_PGD1)
   4: _FOSCSEL( FNOSC_PRI)
   5: _FOSC( POSCMD_HS)
   6:  
   7: main(){
   8:  
   9:     _TRISB5 = 0;
  10:     AD1PCFGL = 0xffff;
  11:     _RB5 = 0;    
  12:     
  13: unsigned int i;    
  14:  
  15:     while(1){
  16:     
  17: for(i=0;i<65000;i++);
  18: for(i=0;i<65000;i++);
  19:     _RB5 = 0;
  20:  
  21: for(i=0;i<65000;i++);
  22: for(i=0;i<65000;i++);
  23:  
  24:     _RB5 = 1;
  25:  
  26:     }
  27:  }
Como veis el código es muy parecido a c18, lo más destacable es la declaración de fuses, que como he comentado antes es ligeramente diferente.
Para ver de una forma muy visual la diferencia de velocidades entre los PIC24 y los PIC18, he cogido el mismo código y se lo he metido a un PIC18, funcionando con el mismo oscilador, y la aquí tenéis el resultado.


Como veis la diferencia es notable, va incluso a más del doble de velocidad, y esto es porque, además de que el procesador va al doble de velocidad, es mucho más eficiente trabajando con enteros de 16 bits.

En el siguiente ejemplo, he querido probar la versatilidad del PLL que llevan integrado estos microcontroladores, para ello, utilizando el mismo oscilador de 20MHz (10MIPS), he obtenido la velocidad máxima que admiten estos micros de 80MHz, 40MIPS. la explicación del módulo PLL la dejo para otra entrada, pero os voy a poner un código que funcionando a 40MIPS, obtenemos una señal de 200ms de periodo.

   1: #include <p24hj64gp202.h>
   2:  
   3: _FICD( ICS_PGD1)
   4: _FOSCSEL( FNOSC_PRIPLL)    //activamos el oscilador principal con PLL
   5: _FOSC( POSCMD_HS)
   6:  
   7:  
   8: main(){
   9:     
  10: // configuración del oscilador para 40MIPS
  11:     
  12:     _PLLPRE = 0x02;    // N1 = 4
  13:     _PLLPOST = 0;    // N2 = 2
  14:     _PLLDIV = 0x1E;    // M = 32 -> 20MHz / 4 = 5MHz * 32 =                                  160MHz /2 = 80MHz / 2 = 40MIPS
  15:     
  16: //configuración del Timer1
  17:     
  18:     T1CON = 0x8030;    //preescaler 1:256
  19:     
  20:     AD1PCFGL = 0xffff;    // todos los puertos digitales
  21:  
  22:       _TRISB5 = 0;
  23:     _RB5 = 0;
  24:  
  25:     while(1){
  26:         
  27:         while(TMR1 <= 15625);    //temporización de 100ms
  28:         TMR1 = 0;
  29:         _RB5 = !_LATB5;    
  30:         }    
  31:     }
y aquí una capture del osciloscopio donde se ve que la señal de salida tiene 100ms de semiperiodo.

2012-05-27-172

la calidad no es muy buena, pero se observa que el tiempo entre los dos cursores es de 100ms. Este dato nos va a servir para verificar que estamos funcionando a 40MIPS.

El temporizador esta configurado con un preescaler de 256, y necesitamos que llegue a contar hasta 15.625, por lo que tenemos en total 256 x 15625 ciclos para obtener 100ms, lo que nos da 4.000.000, si eso lo dividimos entre 100ms, nos da que estamos trabajando a 40.000.000, es decir, 40MIPS.