Robot Zero 2012. PWM ATmega.

Una de las formas de controlar el driver de los motores es utilizar dos señales PWM, una señal PWM en el Mosfet de canal N y otra señal de PWM inversa a la anterior en el Mosfer de canal P, de esta forma se evita que los dos estén activos al mismo tiempo y por tanto hagan un cortocircuito. Entre las dos señales PWM hay que meter un tiempo muerto ya que los transistores tardan un tiempo en encenderse y apagarse, todo esto es fácil de hacer con un timer de un ATmega.


Para controlar el driver del motor de la entrada pasada se va a utilizar un microcontrolador y uno de sus módulos hardware, un timer de 8 bits.  Lo primero para ver como funciona esta parte del timer es acudir al datasheet del micro.

TCNTn es un registro de 8 bits donde el timer lleva una cuenta ascendente o descendente, en cada ciclo de reloj se suma o se resta uno a este registro. El registro OCRnx contiene un valor que es continuamente comparado con el valor del registro TCNTn, cuando los dos registros son iguales  el pin del microcontrolador OCnx se pone a uno ó a cero y se continua con la cuenta y se va repitiendo la misma secuencia.

El timer0 tiene dos registros,OCR0A y OCR0B que se comparan continuamente con TCNT0, cuando uno de ellos es igual que TCNT0 pone a uno ó a cero su pin de salida correspondiente (OC0A y OC0B). Por lo que con un timer se pueden generar hasta dos señales PWM de la misma frecuencia y con distinto ciclo de trabajo, siendo el ciclo de trabajo función del valor guardado en los registros OCR0A y OCR0B.

Qué hace el pin de salida cuando ocurre la comparación depende del modo de funcionamiento seleccionado del timer. Para el caso de generar dos señales PWM inversas y con un tiempo muerto entre ellas debemos seleccionar el modo de funcionamiento del timer “phase correct pwm”.

La configuración del timer se realiza en los registros TCCR0A y TCCR0B:

Los distintos bits de este registro definen el modo de funcionamiento del timer, para este caso la configuración es la siguiente:

TCCR0A = 0xB1; es decir 10110001

TCCR0B = 0x01; o 00000001;

 COM0A1 y COM0A0 = 1 0 indican que la señal pwm de OC0A va a ser sin invertir.

COM0B1 y COM0B0 = 1 1 indican que la señal pwm de OC0B va a ser invertida.

WGM02, WGM01 Y WGM00 igual a 0 0 1, configuran el modo de funcionamiento a phase correct pwm mode.

CS02, CS01 y CS00 igual a 0 0 1 seleccionan el prescaler, es decir la frecuencia de reloj del timer. La frecuencia de este reloj del timer puede ser la del reloj del sistema dividida por 1, 8, 64, 256 y 1024 o un reloj externo conectado al pin T0. 0 0 1 se corresponde con que el reloj del timer va a ser el del sistema dividido por 1, el reloj del sistema es de 8 MHz por lo que el registro TCNT0 incrementará o decrementará su cuenta cada 0.125 uS.

Con esta configuración el funcionamiento de los pines del microconrtolador OC0A y OC0B donde se genera la señal PWM es el siguiente:

En cada ciclo de la señal PWM el registro TCNT0 cuenta desde 255 hasta 0 y desde 0 hasta 255. OC0A lo hemos configurado como una señal PWM sin invertir, ésto significa que la señal se pasa de 0 a 1 cuando OCR0A es igual que TCNT0 en la parte de la cuenta descendente, y pasa de 1 a 0 cuando ambos registros son iguales en la parte ascendente de la cuenta de TCNT0 desde 0 a 255. OC0B la hemos configurado como una señal PWM invertida, por lo que funciona al revés que OC0A, cuando OCR0B es igual a TCNT0 en la parte de la cuenta ascendente pasa de 0 a 1, y pasa de 1 a 0 cuando son iguales en la parte descendente.

Hay un caso especial y es cuando uno de los registros OCR0A o OCR0B vale 0 ó 255, en este caso el pin correspondiente OC0A/OC0B se ponen a uno ó a cero según su configuración, es decir si hacemos OCR0A = OCR0B = 0, el pin OC0A estará a cero durante todo el período y OCR0B estará a uno, y si el valor es 255 en lugar de 0 pues al revés que en el caso anterior.

La frecuencia de la señal PWM es nuestro reloj del sistema entre el prescaler seleccionado y entre los 510 tics de TCNT0 de cada período, con un reloj de 8 MHz, un prescaler de 1, deja una frecuencia de PWM de (8/510) MHz.

La condición para que las dos señales pwm no estén activas al mismo tiempo es que OCR0B (la señal invertida) sea siempre un tiempo mayor que OCR0A, este tiempo es el necesario para que al transistor tenga tiempo de apagarse antes de que la otra señal pwm encienda el otro transistor.

La mejor forma de conocer este retardo es medir con un osciloscopio el tiempo que tarda en subir la señal (teniendo en cuenta los propios del transistor del orden de nS) en la puerta del transistor, metiendo sólo una señal pwm y deshabilitando la otra para realizar cada prueba sobre los dos transistores. Por ejemplo en este driver se observan las siguientes señales generadas por el microcontrolador en la puerta de los transistores:

PWM canal N. Apagado y encendido.

PWM canal P. Encendido y apagado.

Como se puede ver el tiempo de subida para apagar el Mosfet de canal P es el mayor de todos, ya que la capacitancia de puerta se está cargando a través de la resistencia de pull-up de la puerta, y por tanto este tiempo es proporcional a esta resistencia, cuanto menor sea la resistencia menor sera el tiempo pero también mayor será el consumo cuando el transistor está activo.

El tiempo de retardo que metemos entre OCR0A y OCR0B como mínimo debe ser mayor que este último tiempo de apagado del transistor, aproximadamente 5 us (hay que tomar la referencia desde la base del transistor NPN) en este caso. Si el tic del programa a 8 MHz era de 0.125 uS pues OCR0B debe ser siempre como mínimo el valor de OCR0A + 40 (40*0.125  uS = 5 uS).

Cuando el valor de OCR0A + Retardo sea mayor de 255, debemos asignar a OCR0B el valor de 255, de está forma OC0B estará a cero durante todo el período. De igual forma si OCR0A es igual a cero, podemos asignar a OCR0B el mismo valor, estando uno a cero y el otro a uno durante todo el período.

Por últimos los valores de OCR0A y OCR0B el timer los coge cuando TCNT0 vale 255, es decir en TOP, aunque los actualicemos antes no los tendrá en cuenta hasta aquí. No he visto en el datasheet que estén protegidos por lo que es nuestra responsabilidad que el timer no coja el cambio de uno sin coger también el cambio del otro en TOP, es decir actualizar ambos registros un tiempo antes de que ocurra este evento, por ejemplo mediante un búcle de espera while(TCNT0 > 220){} que de tiempo a que se ejecute el código de actualización de los registros antes de que pase por TOP, y por tanto coja los dos actualizados.

Es responsabilidad del programa que no se pueda dar el caso en que ambos transistores conduzcan al mismo tiempo.

Una vez configurado el timer sólo nos queda activar los pines OC0A y OC0B como salida en el registro DDR correspondiente para tener presentes las dos señales PWM.

Haciendo la siguiente prueba se ven las siguientes salidas:

#define RETARDO 40
#define PWM 100 
//Configurar pwm timer0.
 TCCR0A = 0xB1;
 TCCR0B = 0x01;
 OCR0A = PWM; //Canal N, señal sin invertir.
 OCR0B = PWM + RETARDO; //Canal P, hay que comprobar que no sea mayor de 255. Invertida.
 
 _delay_us(100);
 
 DDRD |= (1<<MOTOR2); 
 DDRD |= (1<<FRENO2);

Señal amarilla, PWM sin invertir, ciclo de trabajo 100/255. Al Mosfet N. Señal azul, PWM invertido, ciclo de trabajo 140/255. Al Mosfet P.

El ciclo de trabajo de la señal sin invertir (amarilla) es 100/255 = 39.21%, y el de la señal azul que es la invertida (255 – 100 + 40)/255 = 45%

Se puede ver como la diferencia de tiempo entre que una señal baja a cero y la otra sube a 1 es de 5 uS, que se corresponde con el retardo de 40 que hemos programado.

Evidentemente el tiempo de apagado de 5 uS es altísimo, lo suyo es usar drivers para los Mosfets o un integrado que realice la función, y para el diseño de cualquier robot el integrado es la primera opción. He usado este driver porque me encontré olvidados integrados de parejas de transistores de los MiniZ, y algún uso hay que darlos..

Respecto al control del robot hacerlo de esta forma, meter un PWM en el canal N y el negado en el freno parece que mejora un poco la respuesta del robot, frente a meter una señal PWM en el N y dejar libre el motor en el Toff de dicha señal (frenando cuando el PWM sea cero claro está).

He hecho la prueba controlando el robot de ambas formas y aunque no sé si se apreciará en los vídeos, la respuesta es mejor y va un poco más rápido (100-150 ms por vuelta) controlandolo de la forma que aquí se explica, y 100 ms por vuelta en dos robots es la diferencia entre ganar y perder una carrera de 3 minutos.

Vídeo1. Una señal PWM, Toff motor libre.

Vídeo2. Dos señales PWM, Toff intenta frenar el motor si la bobina quiere.

El driver no va mal del todo, es el mismo programa de seguir la línea a velocidad constante del Cosmobot y va más o menos sobre los tiempos del robot con el driver de la Baby Orangutan.

 

Visitas :7851
Both comments and pings are currently closed.

Comments are closed.

Subscribe to RSS Feed Follow me on Twitter!