Está en la página 1de 8

PROGRAMACIN

La programacin fue desarrollada en lenguaje C con el compilador CCS usando el entorno de MPLAB. Para un mejor entendimiento del cdigo se dividi en funcin a los mdulos usados dentro del PIC.

MOVIMIENTO DEL ROBOT-SUMO


Este robot utiliza dos motores DC (PGHM-01) de 300prm alimentado por 12v. Estos motores se encargan de los movimientos del robot (avanzar, retroceder, girar derecha y girar izquierda). Estos movimientos consisten en la conmutacin de ambos motores que son controlados por el pic a travs del puente H de la siguiente forma:

IN1_MOTOR1 IN2_MOTOR2 IN1_MOTOR1 IN2_MOTOR2 Tabla1

Avanzar Retroceder Girar Derecha Girar Izquierda 1 0 1 0 0 1 0 1 1 0 0 1 0 1 1 0

Este cuadro representa los bits que tiene que enviar el pic al puente H para poder mover los motores. Hasta este punto solo podemos controlar el movimiento del robot ms no la velocidad del mismo. Para poder controlar la velocidad de los motores utilizaremos el mdulo PWM.

Mdulo PWM
La modulacin por ancho de pulsos (tambin conocida como PWM, siglas en ingls de Pulse-Width Modulation) de una fuente de energa es una tcnica en la que se modifica el ciclo de trabajo de una seal peridica, para controlar la cantidad de energa que se enva a una carga. Este principio fue usado en el proyecto para poder variar fcilmente la velocidad de los motores en tiempo real, conectando la salida de PWM al pin enable del puente H. De esta manera al enviar este tren de pulsos del PWM dara el mismo resultado que prender y apagar el puente H rpidamente, reduciendo as la velocidad. Para poder utilizar el modulo PWM del pic primero hay que configurarlo, para trabajar de una manera ms ordenada crearemos una funcin llamada initPWM() para configurar el PWM.
void initPWM() { setup_ccp1(CCP_PWM); setup_ccp2(CCP_PWM); //******** configuracin del periodo PR2 *********** setup_timer_2(T2_DIV_BY_1 ,255, 1);

// Definimos la primera salida de PWM para el motor 1 // Definimos la primera salida de PWM para el motor 2

// Se define por defecto as: (Prescaler, PR2, 1)

// El tiempo de cada ciclo, PERIODO (seg) = (1/clock)*4*T2div*(period+1) // En este programa clock=20000000 y el periodo=255, ***PR2=255*** // Para diferentes cycle el tiempo es: // (1/20000000)*4*1*256 = 51.2 us or 19.5 KHz // (1/20000000)*4*4*256 = 204.8 us or 4.9 KHz // (1/20000000)*4*16*256 = 819.2 us or 1.22 KHz // Usaremos el comando set_pwm1_duty(valor de 0 a 255) para cambiar la velocidad set_pwm1_duty(0); // inicializamos con velocidad 0 el motor 1 set_pwm2_duty(0); // inicializamos con velocidad 0 el motor 2 }

En la funcin initPWM utilizamos el mdulo TIMER_2 ya que el PWM necesita una frecuencia de trabajo. Adems segn el datasheet del pic 18F4550 se debe utilizar el TIMER_2 cuando se usa la salida CPP como PWM. La frecuencia es muy importante en un PWM ya que mientras la frecuencia es mayor obtendremos mayor fuerza de los motores lo cual es favorable para nuestro propsito. Por ese motivo escogimos esta configuracin:

setup_timer_2(T2_DIV_BY_1, 255, 1)

Prescalar: El periodo es dividido entre ste nmero para obtener diferentes periodos: i.e.
T2_DIV_BY_1 T2_DIV_BY_4 T2_DIV_BY_16

PR2: Es el mximo ancho de pulso: 255 100%

Se asigna por defecto el numero 1

Para poder asignar controlar el porcentaje de velocidad se usara el comando:

set_pwm1_duty(valor desde 0 a 255);


Este valor representa el ancho de pulso del PR2 que estar en alto

set_pwm1_duty(127); set_pwm1_duty(255);

TPR2 Terico= TPR2 simulado= TDuty Cycle Terico= TDuty Cycle simulado=

TDuty Cycle Terico= TDuty Cycle ORC =

TPR2 Terico= TPR2 simulado= TDuty Cycle Terico= TDuty Cycle simulado=

TDuty Cycle Terico= TDuty Cycle simulado=

Segn lo observado en las grficas es posible variar la velocidad de los motores enviando pulsos por el PWM. Dichos anchos de pulsos varan conforme al valor ingresado en el comando set_pwm1_duty(valor). Hasta el momento ya podemos controlar la direccin del movimiento como la velocidad de los motores. Ahora veremos un algoritmo que une estos dos puntos para poder controlar la direccin y la velocidad con un solo parmetro.

Funcin Motor

motor(velocidad)
Esta funcin se encarga de enviar el sentido y la velocidad a los motores utilizando un solo nmero para representar ambos datos. La funcin motor(velocidad) requiere que se le asigne un valor de -100 a 100, este nmero representa el porcentaje de velocidad, adems si el nmero es positivo girar en un sentido y si es negativo girar en el sentido contrario. Cabe resaltar que el valor de -100 a 100 es el porcentaje del valor que ingresamos en la comando set_pwm1_duty(valor). Para entender mejor esta lgica observaremos la siguiente grafica:

Porcentaje de la Velocidad del motor motor(velocidad*) velocidad%

Valor de Duty Cycle del PWM

Sentido de giro del motor

motor(50)

50 %

motor(-50)

50 %

motor(100)

100 %

motor(0) Tabla 2

0%

stop

Como podemos observar es muy sencillo controlar el sentido y la velocidad del motor haciendo uso de esta funcin. Ahora veremos el algoritmo de esta funcin en un diagrama de flujo y luego en cdigo. * velocidad es una variable que representa el porcentaje de velocidad del motor.

Diagrama de flujo

INICIO

motor(velocidad)

valor = velocidad&0b10000000

SI

Si valor = 128

NO

Girar en sentido anti horario Girar en sentido horario velocidad=-velocidad;

a=2.55*velocidad; set_pwm1_duty(a);

FIN Explicacin: motor(velocidad) Llamamos a la funcin motor(velocidad), donde velocidad es una variable que representa el porcentaje de velocidad del motor.

Segn lo analizado, el sentido de giro del motor depende del signo del nmero dentro de la funcin motor(velocidad). Para poder determinar el signo analizaremos el nmero como binario. La variable velocidad es un int por lo tanto puede tomar valores desde -127 hasta 127. int =8 bits __ __ __ __ __ __ __ __

Este bit indica el signo: 0: Positivo 1: Negativo

Estos bits generan los nmeros:

i.e. 1 == 0000 0000 2 == 0000 0001 3 == 0000 0010 -1 == 1111 1111 -2 == 1111 1110 -3 == 1111 110

valor = velocidad&0b10000000

Para determinar si un nmero es positivo o negativo tenemos que analizar el primer bit de izquierda a derecha. Este bit lo obtenemos de la siguiente manera: valor = velocidad&0b10000000

Ejemplo: Si velocidad = 50 = 0b00110010 0 0 1 1 0 0 1 0 & 1 0 0 0 0 0 0 0 ___________________________ Valor = 0 0 0 0 0 0 0 0

=0

Si velocidad = -50 = 0b11001110 1 1 0 0 1 1 1 0 & 1 0 0 0 0 0 0 0 ___________________________ Valor = 1 0 0 0 0 0 0 0

= 128

De esta forma podemos obtener el primer bit de un nmero positivo o negativo. Si Valor es igual a 0 el nmero es positivo, si valor es igual a 128 el nmero ser negativo.

Si valor = 128 SI Girar en sentido anti horario velocidad= -1*velocidad;

Preguntamos si la variable valor es igual a 128 (nmero negativo).

Si la variable valor es igual a 128 (negativo) entonces giramos los motores en sentido anti horario. Ahora convertiremos la variable velocidad (nmero negativo) a un nmero positivo multiplicndolo por -1.

Girar en sentido horario

Si la variable valor es igual a 0 (positivo) entonces giramos los motores en sentido horario.

Hasta este punto el signo de la variable velocidad slo se us para determinar el sentido de giro del motor. Adems esta variable ya es positiva para todos los casos ya que se multiplic por -1 cuando era negativa. Ahora usaremos el mdulo de la variable velocidad para asignar el valor del porcentaje de la velocidad del motor en el PWM.

Como la variable velocidad representa el porcentaje de la velocidad es un nmero entre 0 y 100%. Pero hemos configurado el PR2 con 255. Entonces se debe hacer un regla de tres simple para asignar el valor en el comando: set_pwm1_duty(valor entre 0 y 255); a=2.55*velocidad; set_pwm1_duty(a); % de velocidad 100 velocidad Duty Cycle 255 a

Cdigo en CCS
void motor(int velocidad ) { unsigned int valor,a; valor=velocidad&0b10000000; if(valor==128) { output_low(IN1_MOTOR1); // Giramos el motor hacia atrs output_high(IN2_MOTOR1); velocidad=-velocidad; } else { output_low(IN2_MOTOR1); // Giramos el motor hacia adelante output_high(IN1_MOTOR1); } a=2.55*velocidad; set_pwm1_duty(a); } // Hacemos de conversin de % de velocidad a Duty Cycle // Asignamos el valor de Duty Cycle al comando del PWM // Multiplicamos la variable velocidad por -1 para que sea positiva // Si la variable valor es diferente a 128 (significa que el nmero es // positivo) // Definimos la funcin que tendr la entrada de un parmetro // Definimos la variable valor como un entero sin signo (0 a 255) // Obtenemos el primer bit del nmero para saber si positivo o // negativo // Si la variable valor es igual a 128 (significa que el nmero es // negativo)

Esta funcin la extrapolaremos para dos motores


void motor1(int velocidad1) { unsigned int valor1,a; valor1=velocidad1&0b10000000; if(valor1==128) { output_low(IN1_MOTOR1); output_high(IN2_MOTOR1); velocidad1=-velocidad1; } else { output_low(IN2_MOTOR1); output_high(IN1_MOTOR1); } a=2.55*velocidad1; set_pwm1_duty(a); } void motor2(int velocidad2) { unsigned int valor2,a; valor2=velocidad2&0b10000000; if(valor2==128) { output_low(IN1_MOTOR2); output_high(IN2_MOTOR2); velocidad2=-velocidad2; } else { output_low(IN2_MOTOR2); output_high(IN1_MOTOR2); } a=2.55*velocidad2; set_pwm2_duty(a); }

Ahora crearemos una funcin motores para controlar dos motores usando la funcin anterior.
void MOTORES(int velocidad1, int velocidad2) { motor1(velocidad1); motor2(velocidad2); } // definimos la funcin que tendr la entrada de dos parmetros // asignamos la variable velocidad1 al primer motor // asignamos la variable velocidad2 al segundo motor