You are on page 1of 29

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 - mor6an1@hotmail.com
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 (escoger
overshoot y tiempo de asentamiento).
• Implementación del sistema.
DESCRIPCION

Uno de los objetivos para el proyecto que se quiere


realizar es lograr posicionar con precisión el motor D.C,
para que 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 2
))

Obtenido el modelo matemático del motor podemos diseñar


nuestro controlador PID, pero para 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 adquisición de los voltajes de excitación y


generado, se uso según el criterio de estabilidad 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. Debido a que los datos adquiridos
presentaban alteración 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 Salida 1

Entrada 2 Salida 2
Entrada 3 Salida 3

Entrada 4 Salida 4

Entrada 5 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 SALIDA SALIDA SALIDA SALIDA


MODELO 1 MODELO 2 MODELO 3 MODELO 4 MODELO 5
SALIDA
94.68% 92.37% 91.93% 90.16% 91.66%
REAL 1
SALIDA
88.45% 91.78% 91.66% 90.55% 91.44%
REAL 2
SALIDA
85.55% 90.72% 90.78% 90.18% 90.65%
REAL 3
SALIDA
78.49% 87.62% 88.05% 88.24% 88.17%
REAL 4
SALIDA
82.54% 90.99% 91.16% 90.34% 91.44%
REAL 5
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 Tiempo de muestreo
4000000

Muestreamos el sistema:

num = 5.3859;
den =[0.0014 0.0749 1.0000 0]
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 XT,NOWDT,PUT,BROWNOUT,NOLVP,PROTECT //Tipo //de


//oscilador y frecuencia
#use delay (clock = 4000000, RESTART_WDT)

#use fast_io (A) //Configuración de puertos digitales


#use fast_io (B)
#use fast_io (C)
#use fast_io (D)
#use fast_io (E)

#byte porta=5
#byte portb=6
#byte portc=7
#byte portd=8
#byte porte=9

#include <kbd2.c> //Librerias


#include <lcd.c>
#include <math.h>
#include <float.h>

float kp; //Se definen las constantes del


//controlador PID
float kd;
float ki;

float I= 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 Duty; //Se define como entero con


32 caracteres de longitud
int util; //Entero
byte inc,bit_ini,j;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#INT_EXT //Interrupcion externa


signed int pulso() //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; //Define un registro flotante
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); //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); //Pre=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
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 :%ld
",set_point);demor(); //Visualiza

lcd_putc("\f 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 1-Kp :%2.4f
",kp);demor();

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();} //si la


salida del PID<0 increm. atras
else{inc=adelante();} //De lo
contrario adelante

out_PID = abs(out_PID); //Salida


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);
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