Post on 15-Oct-2015
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
TEORA SOBRE SERVO MOTORES DE CORRIENTE DIRECTA
Los servos normalmente trabajan a una frecuencia de f=50Hz lo que es lo mismo a un periodo
(tiempo) T=1/f, es decir T=1/50Hz=20ms.
Dependiendo del timer que disponga el microcontrolador del que se prefiera utilizar de
acuerdo a la precisin requerida se deber tener en cuenta primeramente de cuantos bits es dicho
timer para saber a cunto asciende el conteo de desbordamiento, por ejemplo el timer0es de 8
bits, es decir podemos contar hasta 256 valores sea de 0 a 255 (recuerde que 2^8=256), el
timer1es de 16 bitspor lo que podemos contar hasta 2^16=65536valores.
Otro factor de suma importancia que hay que tomar en cuenta es la frecuencia del oscilador (el
cristal) que se vaya a utilizar ya que de ello depende la frecuencia que tomar el reloj interno del
micro el cual en el caso de los Pics de Microchip toma 4 ciclos de reloj para leer una instruccin
por lo que la frecuencia de lectura de una instruccin frecuencia del ciclo de mquina es en
este caso f ciclo mquina=f oscilador/4, entonces para un cristal tpico de 4Mhz tendremos
f ciclo mquina =4MHz/4=1MHz.
Para calcular el periodo tiempo de un ciclo de mquina se puede entonces aplicar el inverso
de la frecuencia de un ciclo de mquina, es decir
T ciclo mquina=1/f ciclo mquina en donde la lectura de una instruccin utilizando un cristal de 4Mhz
tardar Tciclo mquina=1/1MHz=1us (1microsegundo).
Ahora se analizar la ecuacin que establece como calcular el desbordamiento tanto del timer0
como del timer1:
Para el timer0 tenemos
Tdesbordamiento=Tciclo mquina*prescaler*(256-Valor inicial cargado al timer0)Para el timer1 tenemos
Tdesbordamiento=Tciclo mquina*prescaler*(65536-Valor inicial cargado al timer1)
En donde el prescaler pre escalador es un divisor de frecuencia el cual permite ralentizar la
frecuencia original de un ciclo de mquina, es decir si se tiene una f ciclo mquina =4MHz/4=1MHz
entonces si se aplica un prescaler=4tendremos
f frecuenci a pre escalada= f ciclo mquina/prescaler
f frecuenci a pre escalada=1MHz/4=0.25MHz=25KHz
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Tambin se puede calcular como
Ttiempo pre escalado=Tciclo mquina*prescaler
Ttiempo pre escalado=1us*4=4us y entonces
F frecu encia pre escalada=1/Ttiempo pre escalado
F fr ecuencia pre escalada=1/4us=25000Hz=25Khz
El timer0 tiene los siguientes valores para establecer en el prescaler y son: 1, 2, 4, 8, 16, 32,
64, 128 y 256.
El timer1 tiene los siguientes valores para establecer en el prescaler y son: 1, 2, 4 y 8
Ejemplo1:
A continuacin se realizar un programa en lenguaje C en el compilador PICC de la empresa
CCS para controlar un servomotor marca Hitec modelo HS-311 standard el cual opera a una
frecuencia de 50Hz.
El fabricante establece que para obtener una posicin a 0 se debe manejar un tiempo de
0.6ms, para la posicin central 90 un tiempo de 1.5msy para 180 un tiempo de 2.4ms.
En este caso se utilizar un microcontrolador PIC 16F877A con un cristal oscilador de 20Mhz,
aunque podra utilizarse cualquier modelo de PIC siempre y cuando disponga del timer1 y
cualquier valor en MHz del oscilador de cristal que soporte dicho microcontrolador.
Aplicando la teora presentada sobre los timers, utilizando en este caso el timer1.
La rutina de interrupcin por desbordamiento del timer1 nos ayudar a generar una seal con
modulacin de ancho de pulso pwm (pulse width modulation) la cual tendr una frecuencia de
50Hz lo que es igual a un periodo de 20ms como ya se haba explicado, adems dependiendo
de la posicin que se desee en grados de giro del motor, la seal (tren de pulsos
rectangulares) deber tener una cierta duracin en alto y otra en bajo respectivamente.
Comenzaremos por establecer los extremos del intervalo de movimiento que son 0 y 180 y la
posicin central 90 en trminos de tiempo del valor inicial de carga requerido por el timer1
para desbordar en dichas posiciones en grados.
Utilizando la ecuacin
Tdesbordamiento=Tciclo mquina*prescaler*(65536-Valor inicial cargado al timer1)
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Despejamos:
Valor inicial cargado al timer1=(65536)-((Tdesbordamiento) / (Tciclo mquina*prescaler))
Sustituyendo los siguientes valores para la posicin 0que requiere de un tiempo de 0.6msen
alto:
Tdesbordamiento=0.6 ms=0.0006 s
Tciclomquina=1/fciclomquina=1/(20MHz/4)=1/(20000000Hz/4)=4/20000000Hz=0.0000002s=0.2us
Prescaler=2
Tenemos entonces
Valor inicial cargado al timer1=(65536)-((0.0006 s) / (0.0000002 s*2))
Valor inicial cargado al timer1=64036
Sustituyendo los siguientes valores para la posicin 90que requiere de un tiempo de 1.5ms
en alto:
Tdesbordamiento=1.5 ms=0.0015 s
Tciclo mquina=0.2 us=0.0000002s
Prescaler=2
Tenemos entonces
Valor inicial cargado al timer1=(65536)-((0.0015 s) / (0.0000002 s*2))
Valor inicial cargado al timer1=65536 - 3750=61786
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Sustituyendo los siguientes valores para la posicin 180que requiere de un tiempo de 2.4ms
en alto:
Tdesbordamiento=2.4 ms=0.0024s
Tciclo mquina=0.2 us=0.0000002s
Prescaler=2
Tenemos entonces
Valor inicial cargado al timer1=(65536)-((0.0024 s) / (0.0000002 s*2))
Valor inicial cargado al timer1=59536
Ahora para obtener los correspondientes tiempos en bajo simplemente restamos a los
20ms el tiempo que se requiere en alto para obtenerlos siguientes resultados:
Para 0 se ti ene que
Tdesbordamiento=20ms-0.6ms=19.4ms=0.0194s
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer1=(65536)-((0.0194 s) / (0.0000002 s*2))
Valor inicial cargado al timer1=17036
Para 90 se ti ene que
Tdesbordamiento=20ms-1.5ms=18.5ms=0.0185s
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer1=(65536)-((0.0185 s) / (0.0000002 s*2))
Valor inicial cargado al timer1=19286
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Para 180 se tiene que
Tdesbordamiento=20ms-2.4ms=17.6ms=0.0176s
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer1=(65536)-((0.0176 s) / (0.000002 s*2))
Valor inicial cargado al timer1=21536
En resumen se muestran los resultados obtenidos en una tabla:
Posicin
angular
Tiempo
requerido
Valor inicial de
carga en alto
Tiempo
requerido
Valor inicial de
carga en bajo
0 0.6 ms 64036 19.4 ms 1703690 1.5 ms 61786 18.5 ms 19286
180 2.4 ms 59536 17.6 ms 21536
El rango del timer1 en este caso se obtiene de restar los valores iniciales en las posiciones
lmite, es decir entre 0 y 180, por lo tanto para el caso alto se puede obtener una relacinlineal para obtener el valor inicial de carga para cualquier posicin angular x en grados,
comprendida dentro del intervalo de 0 a 180 como sigue:
Para el caso del valor inicial de carga en alto procedemos como sigue:
(59536-64036) / (Valor inicial de carga en alto- 64036)= (180-0) / (x-0) tambin puede
expresarse como
-4500/(Valor inicial de carga en alto- 64036)=180 / x
Despejando -4500 * x=180 * (Valor inicial de carga en alto- 64036) en donde finalmentese obtiene
Valor inicial de carga en alto= 64036 - ((4500 * x) / 180)
Para el caso del valor inicial de carga en bajo procedemos de forma similar como sigue:
(21536 17036) / (Valor inicial de carga en bajo - 17036)= (180-0) / (x-0) tambin
puede expresarse como
4500/(Valor inicial de carga en bajo- 17036)=180 / x
Despejando 4500* x=180 * (Valor inicial de carga en bajo-17036) en donde finalmente seobtiene
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Valor inicial de carga en bajo= ((4500* x) / 180)+17036
Estas son las frmulas genricas para cualquier valor de posicin angular de x grados dentro del
intervalo de funcionamiento del servo que es de 0 a 180.
Cabe aclarar que estas ecuaciones slo son aplicables a un servo con las caractersticas del Hitec
HS-311 Standard, y con un PIC que disponga del timer1, as como utilizando un cristal de
20MHz.
A continuacin se muestra el programa realizado en CCS compiler y el esquema en Proteus:
#Include
#Fuses HS,NOWDT
#Use delay(clock=20000000)
boolean flag;
unsigned long valor_carga_inicial;
int angulo;
#INT_TIMER1
void servito(){
const unsigned long alto[3]={64036,61786,59536};
const unsigned long bajo[3]={17036,19286,21536};
int i;
if(angulo==0){i=0;}
if(angulo==90){i=1;}
if(angulo==180){i=2;}
if(flag==true){
output_high(PIN_D0);
valor_carga_inicial=alto[i];
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
flag=false;
}
else if(flag==false){
output_low(PIN_D0);
valor_carga_inicial=bajo[i];
flag=true;
}
set_timer1(valor_carga_inicial);
}
void main(){
setup_timer_1(T1_internal|T1_div_by_2);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(true){
angulo=0;
delay_ms(2000);
angulo=90;
delay_ms(2000);
angulo=180;
delay_ms(1000);
}
}
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Ejemplo2:
A continuacin se realizar un programa en lenguaje C en el compilador PICC de la empresa
CCS para controlar un servomotor marca Hitec modelo HS-322 Deluxe el cual opera a unafrecuencia de 50Hz.
El fabricante establece que para obtener una posicin a 0 se debe manejar un tiempo de
0.6ms, para la posicin central 90 un tiempo de 1.5msy para 180 un tiempo de 2.4ms.
Utilizando la ecuacin
Tdesbordamiento=Tciclo mquina*prescaler*(256-Valor inicial cargado al timer0)
Despejamos:
Valor inicial cargado al timer0=(256)-((Tdesbordamiento) / (Tciclo mquina*prescaler))
Sustituyendo los siguientes valores para la posicin 0que requiere de un tiempo de 0.6msen
alto:
Tdesbordamiento=0.6 ms=0.0006 s
Tciclomquina=1/fciclomquina=1/(4MHz/4)=1/(4000000Hz/4)=4/4000000Hz=0.000001s=1us
Prescaler=128
Tenemos entonces
Valor inicial cargado al timer0=(256)-((0.0006 s) / (0.000001 s*128))
Valor inicial cargado al timer0=251.3125252 (debera ser 251 pero
se hizo un pequeo ajuste para que posicione con mayor precisin en la
prctica)
Sustituyendo los siguientes valores para la posicin 90que requiere de un tiempo de 1.5ms
en alto:
Tdesbordamiento=1.5 ms=0.0015 s
Tciclo mquina=1 us=0.000001s
Prescaler=128
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Tenemos entonces
Valor inicial cargado al timer0=(256)-((0.0015 s) / (0.000001 s*128))
Valor inicial cargado al timer0=244.2813245 (debera ser 245 pero
se hizo un pequeo ajuste para que posicione con mayor precisin en la
prctica)
Sustituyendo los siguientes valores para la posicin 180que requiere de un tiempo de 2.4ms
en alto:
Tdesbordamiento=2.4 ms=0.0024s
Tciclo mquina=1 us=0.000001s
Prescaler=128
Tenemos entonces
Valor inicial cargado al timer0=(256)-((0.0024 s) / (0.000001 s*128))
Valor inicial cargado al timer0=237.2500237
Ahora para obtener los correspondientes tiempos en bajo simplemente restamos a los
20ms el tiempo que se requiere en alto para obtener los siguientes resultados:
Para 0 se ti ene que
Tdesbordamiento=20ms-0.6ms=19.4ms=0.0194s
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer0=(256)-((0.0194 s) / (0.000001 s*128))
Valor inicial cargado al timer0=104.4375104
Para 90 se ti ene que
Tdesbordamiento=20ms-1.5ms=18.5ms=0.0185s
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer0=(256)-((0.0185 s) / (0.000001 s*128))
Valor inicial cargado al timer0=111.4688111
Para 180 se tiene que
Tdesbordamiento=20ms-2.4ms=17.6ms=0.0176s
Entonces el valor inicial cargado al timer1 ser esta vez
Valor inicial cargado al timer0=(256)-((0.0176 s) / (0.000001 s*128))
Valor inicial cargado al timer0=118.5000119
En resumen se muestran los resultados obtenidos en una tabla:
Posicin
angular
Tiempo
requerido
Valor inicial de
carga en alto
Tiempo
requerido
Valor inicial de
carga en bajo
0 0.6 ms 252 19.4 ms 10490 1.5 ms 245 18.5 ms 111
180 2.4 ms 237 17.6 ms 119
El rango del timer0 en este caso se obtiene de restar los valores iniciales en las posiciones
lmite, es decir entre 0 y 180, por lo tanto para el caso alto se puede obtener una relacin
lineal para obtener el valor inicial de carga para cualquier posicin angular x en grados,
comprendida dentro del intervalo de 0 a 180 como sigue:
Para el caso del valor inicial de carga en alto procedemos como sigue:
(237-251) / (Valor inicial de carga en alto - 251)= (180-0) / (x-0) tambin puede
expresarse como
-14/(Valor inicial de carga en alto - 251)=180 / x
Despejando -14 * x=180 * (Valor inicial de carga en alto - 251) en donde finalmente seobtiene
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
Valor inicial de carga en alto= 251 - ((14 * x) / 180)
Para el caso del valor inicial de carga en bajo procedemos de forma similar como sigue:
(119 104) / (Valor inicial de carga en bajo - 104)= (180-0) / (x-0) tambin puede
expresarse como
15/(Valor inicial de carga en bajo - 104)=180 / x
Despejando 15* x=180 * (Valor inicial de carga en bajo -104) en donde finalmente se
obtiene
Valor inicial de carga en bajo= ((15* x) / 180)+104
Estas son las frmulas genricas para cualquier valor de posicin angular de x grados dentro del
intervalo de funcionamiento del servo que es de 0 a 180.
Cabe aclarar que estas ecuaciones slo son aplicables a un servo con las caractersticas del Hitec
HS-322 Deluxe, y con un PIC que disponga del timer0, as como utilizando un cristal de 4MHz.
A continuacin se muestra el programa realizado en CCS compiler y el esquema en Proteus:
#Include
#Fuses HS,NOWDT
#Use delay(clock=4000000)
boolean flag;
unsigned long valor_carga_inicial;
int angulo;
#INT_RTCC
void servito(){
const unsigned long alto[3]={252,245,237};
const unsigned long bajo[3]={104,111,119};
int i;
if(angulo==0){i=0;}
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa
if(angulo==90){i=1;}
if(angulo==180){i=2;}
if(flag==true){
output_high(PIN_B7);
valor_carga_inicial=alto[i];
flag=false;
}
else if(flag==false){
output_low(PIN_B7);
valor_carga_inicial=bajo[i];
flag=true;
}
set_timer0(valor_carga_inicial);
}
void main(){
setup_timer_0(RTCC_internal|RTCC_div_128);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(true){
angulo=0;
delay_ms(2000);
angulo=90;
delay_ms(2000);
angulo=180;
delay_ms(1000);
}
}
5/25/2018 Teor a Sobre Servo Motores de Corriente Directa