Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Control Digital de Velocidad de Un Motor DC 1 PDF
Control Digital de Velocidad de Un Motor DC 1 PDF
Introduccin
PWM es una manera eficiente, para simular un rango de valores anlogos usando circuitos
digitales. Switchando rpidamente entre cero voltios y el voltaje nominal del motor, se obtiene
un valor promedio comprendido entre esos dos lmites. Tres seales son presentadas en la
figura arriba, todas tienen la misma frecuencia, pero el ancho de los pulsos son diferentes.
Variando la duracin del tiempo on, el motor puede ver un promedio de cualquier valor entre
0V y +V. Frecuencias recomendadas para PWM estn entre 20 y 30 Khz.
H-Bridge
VS
.1uf 10nf
U1
1
6 1 +
3 Vs B1 2
5 Dir Out1 10
4 PWM
Brake
Out2
B2
11 A
7
8 Ground 9 -
Sense TFO
El pin sense sirve de sensor de corriente de salida. Tiene una sensibilidad de 377
microamperio por amperio de corriente de salida. Usando una resistencia de 2.7K se tiene
0.999 Voltios por amperio de salida. El pin TOF es una seal de advertencia de temperatura.
Es una salida colector abierto que se vuelve 0 a 145 grados centgrados. El pin Brake realiza
un freno de emergencia del motor cuando este pin pasa a 1y el pin PWM tambin.
El LMD18200 puede manejar seales PWM del tipo Signo-Magnitud y Locked-antiphase las
cuales se describen a continuacin.
PWM Locked-antiphase
Una de las grandes ventajas de usar seales PWM del tipo locked-antiphase es que slo se
necesita una lnea I/O para controlar completamente el motor. Si se tiene restricciones de
lneas I/O, esta puede ser una buena opcin.
Si se usa seal PWM del tipo signo-magnitud, el microcontrolador establece la direccin de giro
del motor a travs de un pin del H-Brigde destinado para tal fin (Dir) y varia la cantidad de
potencia aplicada al motor o duty-cicle con otro pin del H-Brigde denominado PWM. La
ausencia de pulso o lgica 0 en forma continua representa cero y lgica 1 en forma continua
representa 100%. Este tipo de seal, por su sencillez, se ha usado en la realizacin del
presente trabajo.
Para obtener una seal PWM, se usa el timer2, el cual establece la frecuencia de la seal
PWM cargando un valor en el registro PR2. El ciclo se inicia con un reset, donde timer2 pasa a
cero, luego se va incrementando hasta que su valor iguale a PR2, momento en que ocurre un
nuevo reset y as sucesivamente. La anchura del pulso el tiempo que la seal permanece a 1
(duty cycle), viene dado por el valor cargado en el registro CCPR1L:CCP1CON<5:4> (8bits
10bits). As cuando ocurre un reset del timer2, el pin de salida PWM pasa a 1, luego cuando
timer2 iguale el valor cargado en el registro CCPR1L:CCP1CON<5:4>, el pin de salida PWM
pasa a 0. El timer2 continua su conteo hasta que iguale a PR2 y un nuevo reset ocurre.
PWM_Periodo=(1/clock)*4*t2div*(PR2+1)
PR2=((PWM_periodo*clock)/(4*t2div))-1
y la anchura de pulso (duty cycle) o tiempo que la seal PWM esta alta durante cada ciclo,
viene dada por la formula:
Duty_cycle= value*t2div*(1/clock)
si value es INT.
set_pwm1_duty(value);
La instruccin:
Setup_timer_2(mode, P, postscale)
permite establecer el periodo del PWM dado un valor de PR2 entre 0 y 255. Este valor
determina cuando timer2 se resetea iniciando as un ciclo de PWM. Postscale es un nmero
entre 1 y 16 que determina cuantas veces el timer2 se resetea antes de ocurrir una
interrupcin.
Tenemos que Timer2 se incrementa cada 200nseg, reset cada 25.6 useg y genera una
interrupcin cada 25.6 * 5 = 128 useg.
Adems si hacemos PR2 igual a 100, un valor de 45 en CCPR1L crea un duty cycle de 45%,
un valor de 65 en CCPR1L crea un duty cycle de 65%.
Tacmetro digital
El tacmetro se construy usando un foto-interruptor CNZ1021 a travs del cual se hace pasar
un disco de acetato codificado colocado en la parte posterior del eje del motor. La fig. 5
muestra un disco codificado de 12 pulsos/rev. Los pulsos emitidos se hacen pasar por el Smith-
trigger 7414 y realimentados al microcontrolador para as calcular la velocidad de rotacin del
motor.
+5VDC
1 2 Seal
CNZ1021
Fig. 6 Tacmetro
1
t
de(t )
u (t ) = K e(t ) + e(t )dt + Td (1-1)
Ti 0 dt
Donde e(t) es la entrada al controlador (seal de error), u(t) es la salida del controlador, K es la
ganancia proporcional, Ti es el tiempo integral (o tiempo de reajuste) y Td es el tiempo
derivativo (o tiempo de adelanto).
Para obtener la funcin de pulso del controlador PID digital, se puede discretizar la ecuacin
1.1 aproximando el trmino integral mediante la sumatoria trapezoidal y el trmino derivativo
mediante diferencias de dos puntos, as se obtiene:
T T (1 Z 1 )
U ( Z ) = K 1 + 1
+ Td E (Z ) (1.2)
2Ti Ti (1 Z ) T
U (Z ) Ki
= Kp + 1
+ Kd (1 Z 1 ) (1.3)
E (Z ) 1 Z
donde:
KT Ki
Kp = K =K Ganancia Proporcional
2Ti 2
KT
Ki = Ganancia Integral
Ti
KTd
Kd = Ganancia Derivativa
T
y T es el periodo de muestreo.
La ecuacin 1.3 puede ser realizada utilizando programacin paralela como indica la figura 7.
p(kT)
+
Ki
+
T
+
e(kT) u(kT)
Kp
+
+
Kd
q(kT)
-
T
BEGIN
DO FOREVER
Periodo de Muestreo
Como periodo de muestreo se toma normalmente 1/10 del tiempo de subida del sistema en
lazo cerrado. El tiempo de subida se define como el tiempo necesario para que el sistema pase
del 10% al 90% del valor final de la respuesta.
Otro criterio que se puede usar es 1/10 de la constante de tiempo del sistema. La constante de
tiempo de un sistema se define como el tiempo necesario para que la respuesta a un escaln
unitario alcance el 63% del valor final de la respuesta. Para un sistema que logra su valor final
a los 2 seg. se toma como periodo de muestreo T igual a 0.12 seg. que es 1/10 de la
constante de tiempo del sistema.
La fig. 8 muestra el prototipo desarrollado que consta de: Motor DC de escobillas 25 Voltios,
tacmetro, H-Bridge basado en el LMD18200 y fuente de poder 5VDC para la lgica TTL. La
alimentacin de 25VDC para el motor se obtuvo de una fuente de poder variable de laboratorio.
El microcontrolador y el resto del circuito se implement en un break-board separado.
Motor DC
Fuente Poder
+5VDC
Tacmetro
Control LMD18200
+5VDC 10nf
+5VDC
U4
1
+5VDC 25VDC
10K 6 1 +
2 15 3 Vs B1 2
3 RA0 RC0/T1OSO/T1CKI 16 5 Dir Out1 10 180 10K 7414
4 RA1
RA2
RC1/T1OSI
CCP1/RC2
17 4 PWM
Brake
Out2 11
B2
A
5 18 7 1 2
VDD 6 RA3 RC3/SCK/SCL 23 8 Ground 9 -
7 RA4/TOCKI RC4/SKI/SDA 24 Sense TFO Seal
.1uf RA5/SS RC5/SDO 25 LMD18200
2
33 RC6/TX/CK 26 10nf
34 INT0/RB0 RC7/RX/DT +5VDC CNZ1021
35 INT1/RB1 19 MOTOR DC
36 INT2/RB2 RD0/PSP0 20
37 CCP2/RB3 RD1/PSP1 21
38 RB4 RD2/PSP2 22
.1uf 39 RB5 RD3/PSP3 27 10K
40 RB6 RD4/PSP4 28
RB7 RD5/PSP5 29
13 RD6/PSP6 30 +5VDC
1K 14 OSC1/CLKIN RD7/PSP7
LED OSC2/CLKOUT 8
1 RE0/RD 9
10Mhz MCLR/VPP RE1/WR 10
14
13
12
11
10
RE2/CS
9
8
7
6
5
4
3
2
1
11
VDD
VSS
VSS
32
VDD
D7
D6
D5
D4
D3
D2
D1
D0
E
RS
VEE
VSS
VC C
R /W
PIC18F452
12
31
LCD-Display
22pf
+5VDC
4.7K
El Software fue escrito utilizando el compilador C de CCS inc. Los valores de los parmetros
del PID se obtienen a travs de canales del convertidor analgico digital de 10bits. Estos
valores son puestos a formato q7, para que estn en un rango de 0 a 1. El rango de los
parmetros del PID se modifican, cambiando el valor de esta variable. Toda la aritmtica se
realiza utilizando formato q7 a fin de evitar overflow.
El lazo PID se realiza cada 26 miliseg y la actualizacin del duty cicle del mdulo PWM se
realiza cada 408 microseg. El despliegue de informacin en la pantalla LCD se refresca cada
segundo.
///////////////////////////////////////////////////////////////////////////
//// MAESTRO_PID.C ////
//// Control PID de Velocidad de un Motor DC ////
//// Versin Aritmetica Fixed Point ////
///////////////////////////////////////////////////////////////////////////
#include <18f452.h>
#device ADC=10
#fuses HS,PUT,BROWNOUT,WDT128,NOLVP
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use delay(clock=10000000,RESTART_WDT)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#zero_ram
#define LEDTIME 10
#define ALL_OUT 0
#define ALL_IN 0xff
/**************************************************************************
* Variables Globales
**************************************************************************/
int tickcount, t;
unsigned ledticks;
#include "lcd-pd.h"
/**************************************************************************
* Leer Velocidad Motor
**************************************************************************/
void read_Vel(void)
{
SET_ADC_CHANNEL(0);
delay_us(10);
Vel = READ_ADC(); // Motor Velocidad, escala0-1023
/**************************************************************************
* Leer Ganancias PID
**************************************************************************/
void read_pid_Gain(void)
{
SET_ADC_CHANNEL(1);
delay_us(10);
P_GAIN = READ_ADC(); // Ganancia Proporcional
P_GAIN_S8 = P_GAIN>>3; // Formato q7
SET_ADC_CHANNEL(2);
delay_us(10);
I_GAIN = READ_ADC(); // Ganancia Integral
I_GAIN_S8 = I_GAIN>>3;
SET_ADC_CHANNEL(3);
delay_us(10);
D_GAIN = READ_ADC(); // Ganancia derivativa
D_GAIN_S8 = D_GAIN>>3;
}
/**************************************************************************
* desplegar datos segun channel
**************************************************************************/
void desplegar_datos(int channel)
{
switch(channel) {
case 0:
printf(displays,"\r P I D ");
printf(displays,"\n%D %D %D ",P_GAIN_S8, I_GAIN_S8, D_GAIN_S8);
break;
case 1:
printf(displays,"\rVel. Counts ");
printf(displays,"\n%04LU %04LU ",Vel, Delta_counts);
break;
case 2:
printf(displays,"\rError ");
printf(displays,"\n%5ld ",error);
break;
case 3:
printf(displays,"\rPwmSet ");
printf(displays,"\n%5ld ",pwmSet);
break;
}
}
/**************************************************************************
* Actualiza el contador tick, retorna no-cero si cambia
**************************************************************************/
short geticks(void)
{
static BYTE tc, lastc=0;
tc = ((get_timer3()>>8) - lastc);
if (tc >= TIMER3_DIV)
{
tickcount++;
lastc += TIMER3_DIV;
return 1;
}
return 0;
}
/***************************************************************************
* Chequea si timeout usando el contador tick dado
***************************************************************************/
short timeout(int &var, int tout)
{
short ret=0;
if (!tout || tickcount-var>=tout)
{
var = tickcount;
ret = 1;
}
return(ret);
}
/**************************************************************************
* Interrupcion INT0
**************************************************************************/
#INT_EXT // Switch Display UP
void EXT0_isr(void)
{
if(channel == 3)
channel = 0;
else
channel++;
if(channel == 0)
channel = 3;
else
channel--;
}
/**************************************************************************
* Actualiza PWM Duty Cycle
**************************************************************************/
#int_TIMER2
void TIMER2_isr(void) // 408 microseg - 2450.98 Hz.
{ // update PWMs during rollover for
// glitch-free operation
set_pwm1_duty(Driver_pwm); // put x% duty on Drive Signal
}
/***************************************************************************
* Lazo PID
***************************************************************************/
#int_timer3
void timer3_isr(void) // Periodo de muestreo cada 26 miliseg
{
t = t + 1;
Wheel_counts = TMR1H;
wheel_counts = wheel_counts<<8;
Wheel_counts += TMR1L;
Wheel_test = TMR1H;
wheel_test = wheel_test<<8;
Wheel_test += TMR1L;
if(Wheel_test != Wheel_counts)
{
Wheel_counts = TMR1H;
wheel_counts = wheel_counts<<8;
Wheel_counts += TMR1L;
}
//velocidad del motor en pulsos/periodo de muestreo
/**************************************************************************
* Programa Principal
**************************************************************************/
void main() {
setup_adc_ports(ALL_ANALOG); // Configura los 8 Convertidores
setup_adc(ADC_CLOCK_DIV_32); // A/D
setup_wdt(WDT_ON); // Perro guardian ON
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); // Contador eventos Externos
setup_ccp1(CCP_PWM); // Configura modulos CCP1 como PWM
setup_timer_2(T2_DIV_BY_4, 255, 1); // PWM 2.44Khz, interrupcin 40 mseg
setup_timer_3(T3_INTERNAL|T3_DIV_BY_1); // Real time interval 26 milliseg
set_tris_A(ALL_IN);
set_tris_B(0x0F);
set_tris_c(0x01);
set_tris_D(ALL_OUT);
LCD_SETUP();
disp_serial = FALSE;
disp_lcd = TRUE;
timeout(ledticks,0);
port_b_pullups(false);
read_pid_Gain(); // Leer ganancias PID
set_pwm1_duty(0);
enable_interrupts(INT_EXT);
ext_int_edge(0,H_TO_L);
enable_interrupts(INT_EXT1);
ext_int_edge(1,H_TO_L);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_TIMER3);
enable_interrupts(GLOBAL);
while(1) {
restart_wdt();
geticks();
if(timeout(ledticks, LEDTIME)){
La realizacin de un control PID es una tarea sencilla, pero la entonacin de los parmetros es
compleja. Partiendo del conocimiento del efecto de cada parmetro sobre la accin de control
total y experimentando con diferentes valores, se puede obtener un rendimiento satisfactorio
del sistema.