DISEÑO E IMPLEMENTACIÓN DE UN SISTEMA DE CONTROL DIGITAL DE POSICIÓN PARA UN MOTOR DC
PRESENTADO POR: EDWIN ALONSO GONZALEZ QUERUBIN MORGAN GARAVITO VASQUEZ -
[email protected] ING. MECATRONICA
UNIVERSIDAD SANTO TOMAS BUCARAMANGA 2006
OBJETIVO GENERAL
Diseñar e implementar un sistema de control digital de posición para un motor DC, utilizando el microcontrolador PIC16F877A.
OBJETIVOS ESPECÍFICOS
•
Reconocimiento y Análisis del sistema.
•
Establecer el modelo matemático del sistema.
•
Simular el sistema modelado diseñando el controlador digital
para
una
respuesta
específica
overshoot y tiempo de asentamiento). •
Implementación del sistema.
(escoger
DESCRIPCION
Uno
de
los
realizar es para
que
objetivos
para
el
proyecto
que
se
quiere
lograr posicionar con precisión el motor D.C,
así,
el
error
de
estado
estacionario
de
la
posición del motor sea cero; además se desea que el error de estado estacionario debido a una perturbación también sea nulo. Otro requerimiento es que el motor alcance muy rápidamente su posición final. En este caso, se desea disminuir el tiempo de establecimiento para que sea mínimo y
tenga un
sobrepaso considerable. Para lograr esto, dispondremos de un microcontrolador PIC que incorpora todas las funciones necesarias para realizar el diseño y control. La eficiencia del sistema va ligada a los parámetros de la planta, debido a que nuestro sistema es retroalimentado, es necesario diseñar un controlador digital de tal forma que el sistema se estabilice en la posición deseada y en el menor tiempo posible. La
retroalimentación
se
hará
por
medio
de
un
encoder
incremental acoplado al eje del motor, el cual enviará constantemente
códigos
digitales
al
microcontrolador
indicándole su posición. Ante estos códigos el microcontrolador tomará una desición relacionando la posición actual con el Set Point o valor
deseado, enviando pulsos digitales a un integrado (L293B) para hacer girar el motor en el sentido indicado.
MODELO MATEMATICO DE LA PLANTA
Considerando que nuestro motor tiene un eje rígido, por medio
de
sus
ecuaciones
eléctricas
y
mecánicas,
al
relacionarlas, podemos obtener el modelo del motor en el cuál la entrada es el voltaje aplicado y la salida es la velocidad
rotacional
del
eje,
para
esto
es
necesario
conocer los diferentes parámetros de los que se encuentra compuesto: •
momento de inercia del rotor J.
•
coeficiente de amortiguamiento del sistema mecánico (b).
•
constante de fuerza electromotriz K=Ke=Kt.
•
resistencia eléctrica (R).
•
inductancia eléctrica (L).
•
entrada (V): Fuente de Tensión.
•
salida (W): velocidad rotacional del eje.
Las ecuaciones eléctricas: -V+RI+LdI+e=0 Dt Ecuaciones mecánicas: Jdw
+ bw=KI
dt Relacionando ambas ecuaciones y expresándolas en el dominio s: Como e=Kw -V+RI(s)+SLI(s)+Kw(s)=0 JSw(s)+bw(s)=KI(s) Obtenemos la función de transferencia de la velocidad del rotor respecto al voltaje aplicado: W
=
___________K____________
V
(JS+b)(LS+R) + K^2
Como nos interesa es la relación del ángulo que se desplaza el rotor con respecto al voltaje aplicado integramos a ambos lados de la ecuación multiplicando por 1/s:
θ / V = K /( S * (( J * S + b ) * ( LS + R ) + K Obtenido el modelo matemático del motor nuestro
controlador
PID,
pero
para
2
))
podemos diseñar
esto
es
necesario
conocer el valor de los parámetros J, K, b, R, L del sistema los cuales desconocemos.
La
solución
que
proponemos
para
la
obtención
de
los
parámetros del sistema, consiste en acoplar
los ejes de
dos motores con similares características.
Uno actuaría
como motor y el otro como generador. Esto se realizaría con el fin de obtener por medio de una tarjeta de adquisición de datos (DAQ) y Matlab, dos señales que serían el voltaje aplicado al motor uno y el voltaje generado por el motor dos, y por medio de la toolbox de Matlab ident relacionar estas dos señales para obtener un modelo aproximado al del motor. Adquisición de las señales de entrada y salida Para
la
generado,
adquisición se
uso
de
según
los el
voltajes criterio
de de
excitación estabilidad
y de
Nyquist, una frecuencia de muestreo de 2000Hz debido a que el
sistema
trabaja
con
frecuencias
bajas.
También
se
definió un tiempo de adquisición de 10 segundos suficientes para poder observar el comportamiento del sistema. Durante el tiempo de adquisición voltaje de entrada o de excitación del motor se varío de forma aleatoria en un rango entre 0V y 10V. presentaban
alteración
Debido a que los datos adquiridos por
ruido
con
una
frecuencia
aproximadamente de 30Hz, se implementó un filtro Butter pasa bajos de orden 10 y frecuencia de corte de 60Hz
con
el fin de eliminar este ruido y así poder apreciar las señales originales.
Señal de salida con ruido
Señal de salida filtrada
A continuación se puede observar el algoritmo empleado para la adquisición de datos por Matlab: clc clear close all ai=analoginput('nidaq',1); % Canal 1 voltaje de excitación % Canal 2 voltaje generado chans=addchannel(ai,1:2); % Frecuencia de muestreo fs=2000; set(ai,'SampleRate',fs); % Tiempo que dura la adquisición duration=10; set(ai,'SamplesPerTrigger',fs*duration); % Rango de entrada adquisición 0-10V set(chans,'InputRange',[0 10]); disp('Pulse ENTER para dar inicio de adquisición') pause % Inicio adquisición start(ai) [d1,t1]=getdata(ai); u=d1(:,1); y=d1(:,2); % Gráfica de acción de control figure(1) plot(t1,u) xlabel('Tiempo(seg)'); title('voltaje de excitación'); grid %Gráfica del voltaje generado figure(2) plot(t1,y) xlabel('Tiempo(seg)'); title('voltaje generado'); grid
%filtro pasabajos [B,A]=butter(10,0.03,'low'); %filtramos señal de entada H1=filter(B,A,u); figure(3) plot(H1) grid %filtramos señal de salida H2=filter(B,A,y); figure(4) plot(H2) grid
Durante el proceso de adquisición, se tomaron cinco muestras de entrada y salida del sistema con el fin de implementarlas en la IDENT, obtener diferentes modelos y así validarlos para obtener un modelo aproximado al real.
Entrada 1
Entrada 2
Salida 1
Salida 2
Entrada 3
Entrada 4
Entrada 5
Salida 3
Salida 4
Salida 5
Obtención y validación de los modelos mediante la IDENT: Importamos las señales de entrada y salida filtradas en la opción import data, ponemos sus nombres en los edits input y output, así como el tiempo de muestreo que se empleo para la adquisición (1/2000).
En la opción estimate seleccionamos process model el cual hallará un modelo aproximado de la planta. En nuestro caso tomamos un sistema con 2 polos reales Tp1, Tp2 y una ganancia K, este sería un sistema de segundo orden. Luego de definir el tipo de sistema, seleccionamos la opción estimate que hallará el modelo aproximado de éste.
Después se obtiene el valor de la ganancia y de los polos de forma que el sistema sea similar al real. Para poder validar el sistema, se obtuvieron los cinco modelos de las diferentes señales adquiridas y se compararon las salidas de los modelos con cada una de las salidas reales adquiridas para observar el porcentaje de exactitud de cada salida de los diferentes modelos con la salida real.
Validación con la primera señal de salida adquirida
Validación con la segunda
señal de salida adquirida
Validación con la tercera señal de salida adquirida
Validación con la cuarta señal de salida adquirida
Validación con la Quinta señal de salida adquirida
En la siguiente tabla se puede observar el porcentaje de exactitud de la salida de cada modelo respecto a cada salida real, además resaltamos los porcentajes más satisfactorios.
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%
Tabla comparativa de los diferentes modelos
En las gráficas anteriores así como en la tabla comparativa, observamos que el modelo más aproximado al real, es el segundo modelo, por lo tanto, este va a ser el modelo de nuestro motor.
Función de transferencia: El modelo aproximado obtenido en Matlab fue el siguiente:
Pero este no es completamente el modelo a analizar debido a que este representa K*W(s))/ V(s) y nuestro sistema debe representar Ө(s) / V(s). Para solucionar este problema, debemos agregarle un integrador al sistema ya que este integra W(s) y la convierte en Ө(s)y comparar el modelo obtenido en la Ident con el modelado con el fin de obtener los parámetros de la planta y así identificar el modelo real.
Primero que todo multiplicamos el modelo matemático por el facto K(constante electromotriz) para que quede de la forma:
Ahora procedemos a comparar ambos sistemas:
Al comparar ambos sistemas se puede observar que:
Donde el parámetro K(constante electromotriz) es igual a la raíz de 0.73482. Ya conocido el parámetro, K podemos expresar el sistema o función de transferencia de nuestro motor:
Otro inconveniente es que la variable teta, esta expresada en revoluciones debido a que W en el análisis del circuito se da en revoluciones/segundo. Para esto es necesario convertir teta en radianes, para mayor comodidad multiplicando al sistema por el factor 2π.
Función de transferencia del motor
Debido a que el sistema se encuentra en tiempo continuo es necesario discretizarlo. Para el microcontrolador se empleo un oscilador XT de 4MHZ. De acuerdo con esta frecuencia y los ciclos de máquina que efectúa el microcontrolador durante la retroalimentación con el encoder (300 aprox.), se obtiene el periodo de muestreo necesario para obtener la planta en formato de Z´s. T = 4*300 ------- = 0.3 milisegundos 4000000 Muestreamos el sistema: num = 5.3859; den =[0.0014 0.0749 1.0000 0]
Tiempo de muestreo
G=Tf(num,den) Gz=c2d(G,3e-4)
Nuestro sistema discretizado sería el siguiente:
El las gráficas siguientes se puede observar la respuesta al escalón y el lugar de las raíces respectivamente: Se puede observar que el sistema alcanza su valor máximo en aproximadamente 0.7 segundos, por lo que el tiempo de establecimiento se debe disminuir.
Respuesta al escalón
En el lugar de las raíces se puede observar que el sistema tiene 3 polos; (z-1) (z-0.9923) (z-0.9917) y dos ceros (z+3.717) (z+0.2669).
Para el diseño del controlador PD debido a que nuestro sistema es tipo uno, se escogió un Overshoot del 16% y un tiempo de establecimiento de 1 segundo.
Controlador PD
Controlador obtenido mediante la SISOTOOL
Sistema con controlador
Salida del sistema controlado DESARROLLO CON EL MICROCONTROLADOR
El proyecto se fundamenta en el diseño de un controlador de posición de un motor D.C basado en un PIC 16F877A. En una pantalla LCD se visualizará el set point o valor de posición deseado, el error actual, el ciclo útil, realimentación y la constante del PID, junto con las constantes del controlador PID (Kp, Ki, Kd), que son ingresadas por el usuario por medio de un teclado matricial. Ingreso de datos: Al iniciar, el microcontrolador se visualiza el valor deseado de posición y las constantes del controlador (Kp, Ki, Kd), después de ingresar el último valor de las constantes, el microcontrolador empieza a posicionar el motor comparando, si el valor actual es igual al ingresado. Esto se logra por medio de un encoder que está acoplado a uno de los engranes del motor (que en este caso es el de menor diámetro), este tiene la función de producir una señal cada vez que el engrane realiza dos vueltas.De esta forma se va corrigiendo la posición actual con la deseada.
Elementos utilizados -
PIC16F877A LCD Teclado matricial CD40106B L293B Encoder Motor de corriente continua Visualizador angular. Fuente de alimentación de 5V. Oscilador de 4MHz. Panel de visualización para el desplazamiento del motor.
Programa del Microcontrolador Para la programación del PIC, fue necesario crear el código a partir de lenguaje C, debido a que este cuenta con librerías para el control del LCD, teclado, interrupciones, etc., que facilitan el control de estos y además reduce las líneas de código. Una vez que se ha realizado el programa en C, procedemos al crear el archivo “.hex”, el cual es el que se guarda en la memoria del microcontrolador, esto se realiza por medio de un compilador llamado PCW C Compiler.
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)
<math.h>
delay
//Tipo //de
(clock = 4000000, RESTART_WDT)
//Configuración de puertos digitales
#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=
//Se definen las constantes del
kd; ki; 0.5;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% float err_ant,err_ant1,err_ant2,err_ant3,A; //Definición 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;
//Se define como entero con
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() {
//Cambio de giro del motor output_bit(PIN_C0,0); output_bit(PIN_C1,1); return(1);
//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 {
//Define un registro flotante
uno=kbd_getc(); } while ((uno<'0') || (uno>'9')); lcd_putc(uno); uno-='0'; ctte += uno; demor_1();demor_1();demor_1(); return(ctte);
//Regresa el valor de (ctte).
} //==================================================================== int32 aprox(float rta_controlador) //Funcion aprox { //Esta función aproxima el valor de la salida del controlador al entero más 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 más cercano } else { ciclo_pwm=floor(rta_controlador); //aprox al entero menor más cercano } return (ciclo_pwm); //Regresa el valor de ciclo_pwm,que es } //un entero de 32 caracteres. //==================================================================== //==================================================================== void main(void) { portb=portc=0;
//Reset para los puertos
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
lcd_putc("\f SANTO TOMAS\n"); //Mensajes de inicio lcd_putc("CONTROL II");demor(); lcd_putc("\f MORGAN\n"); lcd_putc(" EDWING ");demor(); lcd_putc("\fING\n"); lcd_putc(" MECATRONICA "); demor(); //Retardo lcd_putc("\f INICIANDO\n"); lcd_putc(" SISTEMA"); demor(); lcd_putc("\f VALOR : "); set_point = get_bcd(); //Obtiene el valor ingresado printf(lcd_putc,"\f ",set_point);demor(); //Visualiza lcd_putc("\f
set Point :%ld
1-Kp : ");
//Imprime mensaje 1-Kp en el LCD A=get_bcd(); //Obtiene valor de Kp kp = 0.001*A; //Multiplica valor ingresado por 0.001 printf(lcd_putc,"\f ",kp);demor();
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;
//Ecuacion para el error actual //------------------PROPORCIONAL--------------------------------------
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; //Memorización 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 •
Para la obtención de modelos matemáticos por medio de datos adquiridos, es necesario la obtención de diferentes modelos a partir de varios datos, con el fin de validarlos y así obtener un sistema que satisfaga las características de comportamiento del sistema real.
•
Los datos que se adquirieron fueron filtrados con el fin de eliminar el ruido que alteraba la señal de salida del generador.
•
Para el proceso de discretización del modelo, la frecuencia de funcionamiento del microcontrolador es la frecuencia de muestreo.
•
El controlador que se diseño fue un PD debido a que el PID no es aconsejable implementarlo debido a que el sistema ya posee un integrador.
ANEXOS
Circuito diseñado en Proteus