Anda di halaman 1dari 9

Universidad de Monterrey

Divisin de Ingeniera y Tecnologas


Laboratorio de Microprocesadores

Prctica 3
Nombre: Daniel Antonio Barrera Mndez
Matrcula: 356612
Horario: 19:00 21:50 Mircoles
Saln: 3205 C
Instructor: Ing. Francisco Hidalgo

A 31 de Marzo del 2017, San Pedro Garza Garca, Nuevo Len


Yo, Daniel Antonio Barrera Mndez, declaro que he realizado esta prctica con estricto apego
al Cdigo de Honor de la UDEM.
1. Diagrama de flujo
2. Cdigo
// Conexiones del mdulo LCD
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Final de las conexiones del mdulo LCD

//Definicin de pulsadores - puertos


#define PID_ON porta.ra1 //Encender PID
#define PID_OFF porta.ra2 //Apagar PID
#define SP_I porta.ra3 //Incrementar Setpoint
#define SP_D porta.ra4 //Bajar Setpoint

int c_time; //Variable auxiliar para el contador del timer


int duty=0; //Duty cycle del PWM, nmero entero
char output[6]; //Variable que guarda el texto del LCD
float sum_error=0; //Integral de errores acumulados
float errorac=0; //Error actual
float erroran=0; //Error anterior
float kp=10; //Ganancia proporcional
float ki=0.07; //Ganancia integral
float kd=0.001; //Ganancia derivativa
int sp=50; //Set point (valor deseado de la temperatura)
float cv=0; //Valor de la ecuacin del PID en decimales
int cv2=0; //Valor de la ecuacin del PID en enteros
int pv=0; //Temperatura en nmero entero
float escalon; //Escalonamiento del valor de la ecuacin PID de 0 a 255
int control=1; //Selector del encendido/apagado del control PID

void interrupt(){
if(c_time<31){ //Cuenta 31 ciclos para que el timer cuente 1 segundo
c_time++;
INTCON=0b10100000; //Configuracin del registro INTCON para activar interrupciones
TMR0=0; //Timer 0 comienza en 0

if(c_time>=31){ //TMR0 cuenta 1 segundo


c_time=0; //Contador reset
pv=(adc_read(0)*0.488); //Lectura de la Temperatura
INTCON=0b10100000; //Configuracin del registro INTCON para activar interrupciones
TMR0=0; //Timer 0 comienza en 0
}
}

void main() {
ANSEL=0x01; //Pin A0 como analogico
ANSELH=0; //Todos los demas pines como digitales
TRISA=0xFF; //PORTA como entradas
TRISC=0; //PORTC como salida
PORTC=0;
PORTA=0;
OPTION_REG=0b00000111; //Timer0 temporizador con preescalador de 256
INTCON=0b10100000; //Configuracin del registro INTCON para activar interrupciones
TMR0=0; //Timer 0 comienza en 0
c_time=0; //Reinicio del contador
lcd_init();//Inicia LCD
lcd_cmd(_LCD_CURSOR_OFF); //Apaga el cursor del LCD
lcd_cmd(_LCD_CLEAR); //Limpia la Pantalla del LCD
ADC_init(); //Inicia ADC

//Inicializacin del PWM1


PWM1_Init(1000); //Frecuencia 1000Hz del PWM
PWM1_Start(); //Inicia PWM

//Primer escalonamiento para del PID (cv)


errorac=sp-pv; //Calcula el error
sum_error=sum_error+erroran; //Guarda el error anterior
cv=(kp*errorac)+(ki*sum_error*1)+(kd*(errorac-erroran)); //Valor mximo del CV
escalon=255/cv; //Escalona el valor del PID a 255
duty=(int)(255-(cv*escalon)); //Se adquiere el valor del PWM (logica inversa)
erroran=errorac; //Guarda el error actual como el error anterior para prox lectura

while(1){

while(control==0){ //PID apagado

pwm1_set_duty(255); //El foco estara apagado


if(PID_ON==1){ //Enciende el Control PID
control=1;
}
sprintl(output,"%3u",sp);
lcd_out(1,4,output);
sprintl(output,"%3u",pv);
lcd_out(2,4,output);
sprintl(output,"%4u",duty);
lcd_out(2,9,output);
}

while(control==1){// PID encendido

pwm1_set_duty(duty); //Envia el valor del PWM anterior


errorac=sp-pv; //Error
sum_error=sum_error+erroran; //Integral de los errores
cv=(kp*errorac)+(ki*sum_error*1)+(kd*(errorac-erroran)); //CV de Lectura actualizada
duty=(int)(255-(cv*escalon)); //Se escalona al valor del PWM con logica inversa
erroran=errorac; //Guarda el error actual como el anterior
if(duty<0){ //Valores menores a 0 son 0
duty=0;
}
if(duty>=0){ //Valores entre 0 y 255 se quedan igual
duty=duty;
}
if(duty>=255){ //Valores mayores a 255 son 255
duty=255;
}
cv2=(int)cv; //Convierte el valor del PID en entero

while(SP_I==1){//Se vuelve a calcular el CV mximo para el nuevo SP


sp++;
errorac=sp-0;
sum_error=sum_error+erroran;
cv=(kp*errorac)+(ki*sum_error*1)+(kd*(errorac-erroran));
escalon=255/cv;
duty=(int)(255-(cv*escalon));
erroran=errorac;
delay_ms(1000);
}

while(SPDec==1){//Se vuelve a calcular el CV mximo para el nuevo SP


sp--;
errorac=sp-0;
sum_error=sum_error+erroran;
cv=(kp*errorac)+(ki*sum_error*1)+(kd*(errorac-erroran));
escalon=255/cv;
duty=(int)(255-(cv*escalon));
erroran=errorac;
delay_ms(1000);
}

if(PID_OFF==1){ //Apaga el PID


control=0;
}
sprintl(output,"%3u",sp);
lcd_out(1,4,output);
sprintl(output,"%3u",pv);
lcd_out(2,4,output);
sprintl(output,"%4u",duty);
lcd_out(2,9,output);
}
}
}

3. Simulacin
Para la simulacin, se utiliz un sensor de temperatura, el cual puede controlarse su temperatura
manualmente. Adems se incluy un foco de intensidad modulada, de modo que cuando el PWM
tenga el valor de 0, el foco estar brillantemente prendido, mientras que si el PWM est en 255,
el foco estar completamente apagado. En el LCD se muestra el valor del ciclo de trabajo.
Utilizando como referencia el 0 como mxima intensidad y el 255 como intensidad nula, se subir
la temperatura del sensor manualmente con una velocidad rpida/lenta. Recordemos que nuestro
setpoint inicialmente es 50C y que adems en la implementacin utilizamos un rel de estado
slido con un enable en baja, por lo que su lgica es inversa.
Primero iniciamos con el sensor en 20C, temperatura ambiente, por lo que en teora el duty cycle
debera ser muy pequeo ya que est muy lejano a los 50C.
En la imagen anterior podemos observar claramente que el set point se encuentra en 50C, la
lectura del sensor es de aproximadamente 20C, y el duty cycle es de 0, por lo tanto el foco se
enciende intensamente.
Posteriormente, subimos la temperatura del foco por arriba del setpoint, de modo que creamos
el pequeo sobretiro caracterstico de un sistema controlado por PID, a continuacin mostramos
captura de pantalla de lo mismo:
Podemos observar que el duty cycle se est alejando de 0, y el foco baja su intensidad, debido
a que la temperatura deseada ya se alcanz y se pas, pero necesitamos bajar la intensidad
para regresar al punto deseado, por lo que de ahora en adelante la temperatura debera estar
bajando hasta volver a alcanzar el valor de 50C.

Una vez que el sensor baja a una temperatura cercana al set point, se puede observar que el
duty cycle es muy cercano a 255, por lo que el foco estar muy tenue, brindando el calor justo
para mantener una temperatura constante, manteniendo el valor de la temperatura oscilando
muy poco alrededor de los 50C, pero nunca apagando el foco.
4. Circuito Elctrico

5. Conclusiones
Esta prctica fue bastante retadora, en otras clases ya habamos realizado un control PI, o PID,
pero era mucho ms fcil debido a que utilizbamos Simulink y descargbamos el modelo de
bloques, solamente cambibamos las constantes de control; sin embargo, el reto para sta clase
fue hacerlo desde cero, utilizando un lenguaje de programacin en donde la operacin de integral
de una funcin y la derivada, no estn precargadas, por lo que se necesitan hacer unas
manipulaciones, para lo que utilizamos el concepto de suma de rectngulos de errores para la
integral, y la pendiente de los errores, para la derivada. En esta parte fue lo complicado porque
debamos asegurarnos que en efecto debemos estar comparando errores actuales, y errores
guardados anteriormente.
Otra cosa que aprend fue a comprender el comportamiento de un sistema sin observar su
grfica, como el sobretiro que tiene nuestro control de temperatura la primera vez que va desde
la temperatura ambiente al setpoint, incluso pens que haba programado mal, porque a veces
el valor suba hasta los 60C y lo apagaba, pero no estaba considerando que las K podran
generar un sobretiro bastante grande, por lo que deba esperarme a que el sistema reaccionara
y bajara la intensidad del foco, para poder juzgar correctamente.

Anda mungkin juga menyukai