Documentos de Académico
Documentos de Profesional
Documentos de Cultura
12 Control de Motor Encoder
12 Control de Motor Encoder
PRESENTADO POR:
EDWIN ALONSO GONZALEZ QUERUBIN
MORGAN GARAVITO VASQUEZ - mor6an1@hotmail.com
ING. MECATRONICA
OBJETIVO GENERAL
OBJETIVOS ESPECFICOS
para
una
respuesta
especfica
(escoger
DESCRIPCION
Uno
de
los
realizar es
para
que
objetivos
para
el
proyecto
que
se
quiere
as,
el
error
de
estado
estacionario
de
la
tenga un
sobrepaso considerable.
Para lograr esto, dispondremos de un microcontrolador PIC
que incorpora todas las funciones necesarias para realizar
el diseo y control.
La eficiencia del sistema va ligada a los parmetros de la
planta, debido a que nuestro sistema es retroalimentado, es
necesario disear un controlador digital de tal forma que
el sistema se estabilice en la posicin deseada y en el
menor tiempo posible.
La
retroalimentacin
se
har
por
medio
de
un
encoder
cdigos
digitales
al
microcontrolador
indicndole su posicin.
Ante estos cdigos el microcontrolador tomar una desicin
relacionando la posicin actual con el Set Point o valor
de
sus
ecuaciones
elctricas
mecnicas,
al
rotacional
del
eje,
para
esto
es
necesario
+ bw=KI
dt
Relacionando ambas ecuaciones y expresndolas en el dominio
s:
Como e=Kw
-V+RI(s)+SLI(s)+Kw(s)=0
JSw(s)+bw(s)=KI(s)
Obtenemos la funcin de transferencia de la velocidad del
rotor respecto al voltaje aplicado:
W
___________K____________
(JS+b)(LS+R) + K^2
/ V = K /( S * (( J * S + b ) * ( LS + R ) + K
Obtenido el modelo matemtico del motor
nuestro
controlador
PID,
pero
para
))
podemos disear
esto
es
necesario
La
solucin
que
proponemos
para
la
obtencin
de
los
los ejes de
Uno actuara
la
generado,
adquisicin
se
uso
de
segn
los
el
voltajes
criterio
de
de
excitacin
estabilidad
y
de
sistema
trabaja
con
frecuencias
bajas.
Tambin
se
alteracin
ruido
con
una
frecuencia
con
%filtro pasabajos
[B,A]=butter(10,0.03,'low');
%filtramos seal de entada
H1=filter(B,A,u);
figure(3)
plot(H1)
grid
%filtramos seal de salida
H2=filter(B,A,y);
figure(4)
plot(H2)
grid
Entrada 1
Entrada 2
Salida 1
Salida 2
Entrada 3
Entrada 4
Entrada 5
Salida 3
Salida 4
Salida 5
SALIDA
REAL 1
SALIDA
REAL 2
SALIDA
REAL 3
SALIDA
REAL 4
SALIDA
REAL 5
SALIDA
MODELO 1
SALIDA
MODELO 2
SALIDA
MODELO 3
SALIDA
MODELO 4
SALIDA
MODELO 5
94.68%
92.37%
91.93%
90.16%
91.66%
88.45%
91.78%
91.66%
90.55%
91.44%
85.55%
90.72%
90.78%
90.18%
90.65%
78.49%
87.62%
88.05%
88.24%
88.17%
82.54%
90.99%
91.16%
90.34%
91.44%
En
las
grficas
anteriores
as
como
en
la
tabla
comparativa, observamos que el modelo ms aproximado al
real, es el segundo modelo, por lo tanto, este va a ser el
modelo de nuestro motor.
Funcin de transferencia:
El modelo aproximado obtenido en Matlab fue el siguiente:
Tiempo de muestreo
G=Tf(num,den)
Gz=c2d(G,3e-4)
Respuesta al escaln
Controlador PD
Elementos utilizados
-
PIC16F877A
LCD
Teclado matricial
CD40106B
L293B
Encoder
Motor de corriente continua
Visualizador angular.
Fuente de alimentacin de 5V.
Oscilador de 4MHz.
Panel de visualizacin para el desplazamiento del
motor.
CODIGO C
#include <16f877A.h>
#fuses
//oscilador y frecuencia
#use
#use
#use
#use
#use
#use
fast_io
fast_io
fast_io
fast_io
fast_io
(A)
(B)
(C)
(D)
(E)
<kbd2.c>
<lcd.c>
<math.h>
<float.h>
delay
//Tipo //de
#byte porta=5
#byte
#byte
#byte
#byte
#include
#include
#include
#include
XT,NOWDT,PUT,BROWNOUT,NOLVP,PROTECT
portb=6
portc=7
portd=8
porte=9
//Librerias
float
//controlador PID
float
float
kp;
float
I=
kd;
ki;
0.5;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float
err_ant,err_ant1,err_ant2,err_ant3,A;
//Definicin de variables
float
sum_int=0;
//Condicion inicial
float
integral,proporcional,derivativo,
out_PID,out_PID2;
signed long
err_act,set_point,realimentacion;
int32
32 caracteres de longitud
int
byte
Duty;
util;
//Entero
inc,bit_ini,j;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#INT_EXT
signed int pulso()
{
//Interrupcion externa
//Funcion pulso valor entero
if(inc == 0x00){realimentacion--;}
else{realimentacion++;}
return(realimentacion);
}
//====================================================================//======
==============================================================
void demor_1()
//Retardos
{
char i;
for(i=0;i<30;i++)
{delay_ms(5);}
}
void demor()
//Retardos
{
char i;
for(i=0;i<250;i++)
{delay_ms(7);}
}
//====================================================================
byte adelante()
{
//Asigna a la salida un
(1).
}
byte atras()
{
output_bit(PIN_C0,1);
output_bit(PIN_C1,0);
return(0);
//Asigna a la salida
un(0).
}
//====================================================================
//====================================================================
long get_bcd() {
long uno;
float
ctte;
ctte=0x00;
do {
uno=kbd_getc();
} while ((uno<'0') || (uno>'9'));
lcd_putc(uno);
uno-='0';
ctte = uno*1000;
demor_1();
do {
uno=kbd_getc();
} while ((uno<'0') || (uno>'9'));
lcd_putc(uno);
uno-='0';
ctte += uno*100;
do {
uno=kbd_getc();
} while ((uno<'0') || (uno>'9'));
lcd_putc(uno);
uno-='0';
ctte += uno*10;
demor_1();
do {
uno=kbd_getc();
} while ((uno<'0') || (uno>'9'));
lcd_putc(uno);
uno-='0';
ctte += uno;
demor_1();demor_1();demor_1();
return(ctte);
}
//====================================================================
int32 aprox(float rta_controlador)
//Funcion aprox
{
//Esta funcin aproxima el valor de la salida del controlador al entero ms
proximo
float parte_entera,parte_decimal;
int32 ciclo_pwm;
parte_decimal=modf(rta_controlador,&parte_entera);
if(parte_decimal>=0.5)
{
ciclo_pwm=ceil(rta_controlador);
//aprox al entero mayor ms cercano
}
else
{
ciclo_pwm=floor(rta_controlador);
//aprox al entero menor ms cercano
}
return (ciclo_pwm);
//Regresa el valor de ciclo_pwm,que es
}
//un entero de 32 caracteres.
//====================================================================
//====================================================================
void main(void)
{
portb=portc=0;
set_tris_a(0xFF);
//Configuracion de puertos
(E/S)
set_tris_b(0xFF);
set_tris_c(0x08);
set_tris_d(0x00);
set_tris_e(0x00);
setup_timer_2(T2_DIV_BY_16, 255, 1);
Periodo=255 Pos=1
setup_ccp1(CCP_PWM);
//Configuracion contador PWM
enable_interrupts(INT_EXT);
//Int. sensor encoder
ext_int_edge( L_TO_H );
//Interrupcion flanco Bajo a alto
enable_interrupts(GLOBAL);
//Activar interrupciones globales
lcd_init();
//Inicializacion del LCD
//Pre=1
1-Kp : ");
1-Kp :%2.4f
lcd_putc("\f
2-Ki : ");
A=get_bcd();
ki = 0.001*A;
printf(lcd_putc,"\f
2-Ki:%2.4f
",Ki);demor();//%demor();
lcd_putc("\f
3-Kd : ");
A=get_bcd();
kd = 0.001*A;
printf(lcd_putc,"\f
3-Kd :%2.4f
",kd);demor();//%demor();
/*
set_point=20;
kp=1;
ki=0;
kd=0;
*/
err_ant= err_act= err_ant1= err_ant2= err_ant3=
out_PID= integral= proporcional= derivativo= 0x00; //Condicion inicial
realimentacion= bit_ini=0;
//Bandera de inicio
set_tris_b(0x01);
//Configuracion
del puerto B
for(;;)
{
delay_ms(5);
err_act = set_point - realimentacion;
proporcional = kp*err_act;
//Ecuacion de parte Proporcional
//------------------INTEGRAL-----------------------------------------if(bit_ini==0)
//Si est en
condicion inicial 0
{
integral = ki*err_act;
//Ecuacion
integral
//
sum_err=err_act;
sum_int=integral;
bit_ini=0xFF;
}
else
{
integral = I*(err_ant+err_act);
integral += sum_err;
integral *= ki;
sum_int+=integral;
//
//sum_err += err_act;
err_ant =err_act;
}
//----------------DERIVATIVO-----------------------------------------derivativo = 3*(err_ant1-err_ant2);
derivativo += err_act;
derivativo -= err_ant3;
derivativo *= kd;
err_ant3=err_ant2;
//Memorizacin para la parte derivativa
err_ant2=err_ant1;
err_ant1=err_act;
//-------------------------------------------------------------------out_PID = proporcional + sum_int + derivativo;
if(out_PID < 0x00){inc=atras();}
salida del PID<0 increm. atras
else{inc=adelante();}
contrario adelante
out_PID = abs(out_PID);
del PID positivo
lcd_putc('\f');
printf(lcd_putc,"\fe: %ld D: %U \nR:%U
PID:%f",err_act,util,realimentacion,out_PID);
for(j=0;j>=170;j++)
//Retardo
delay_ms(1);
out_PID*=60;
Duty = aprox(out_PID);
//si la
//De lo
//Salida
if(Duty>254){Duty=255;}
util=Duty;
set_pwm1_duty(util);
}
}
CONCLUSIONES
ANEXOS