Servos de modelismo o RC
Control de un servo - Prueba 01: Control básico
por Eduardo J. Carletti
|
Servo utilizado: Hitec HS-311
|
Esta es la primera de un grupo de pruebas de laboratorio en las que, partiendo desde cero,
implementaremos el control de servos de modelismo por medio de un microcontrolador PIC. El
microcontrolador elegido es el
PIC16F628A, que tiene una distribución de patas igual a
las del histórico y archiconocido
PIC16F84A,
aunque con mejores prestaciones. Las razones
de elegir este PIC para las pruebas de aprendizaje en lugar del PIC16F84A las he
desarrollado en el artículo Prueba de conexión
serie entre un PIC y una PC y no tiene sentido repetirlas aquí.
A los servos de modelismo también se les llama servos RC (por
Radio Control) o, en inglés, RC servos. En estas pruebas utilizaremos
el servo HS-311
de Hitec, que se consigue en Argentina a mejor precio que otros
similares de Futaba, por ejemplo.
La forma de controlar el posicionamiento de este tipo de servos es bastante sencilla, y
como ya la hemos descripto en detalle en el artículo Servos,
Características básicas, no voy a extenderme aquí. A aquellos que aún no han
profundizado en el método que se utiliza para controlar los servos de modelismo que tiene mucho
que ver con las características del radiocontrol les recomiendo dar una ojeada a
este artículo antes de seguir.
A continuación se puede observar el primer circuito que vamos a utilizar:
Primera prueba de control de un servo RC
En el circuito se pueden apreciar los pocos elementos que estamos
utilizando en esta primera prueba. Se trata del PIC, que como funciona con su generador
interno de reloj de 4 MHz no requiere de un cristal; el enchufe para el servo; y tres
pequeños pulsadores. Los resistores son para polarizar a un valor positivo, o valor
lógico 1, las entradas del PIC que se utilizan para "leer" los pulsadores. Los
pulsadores llevan este nivel a lógico 0, o tierra, cuando se los presiona.
Montaje del circuito básico de control de un servo RC
Como se ve en la foto, al servo le hemos colocado un círculo de
cartulina con una línea negra que nos servirá como indicador de su posición.
Los tres pulsadores que se observan en la foto corresponden, de izquierda
a derecha, a "pulsador 1", "pulsador 2" y "pulsador 3" en el circuito. El pulsador 1 servirá para
llevar al servo a su posición central, o "neutra". Con el pulsador 2 se hará avanzar
lentamente al servo en sentido antihorario, y con el pulsador 3 se lo hará girar, de a poco,
en sentido horario.
Este circuito, y el programa asociado en el PIC, no cumplen otro propósito
que el de dar una primera aproximación al método de programa utilizado para controlar a
este tipo de servos. En las pruebas siguientes iremos avanzando hasta llegar a una
sofisticación y utilidad mucho mayor.
Programa básico de control de servos RC
;**********************************************************************
; MANEJO DE SERVOS - Programa Básico 1
; Por Eduardo J. Carletti, Robots Argentina, 2007
;**********************************************************************
list p=16F628A ; definir procesador
#include <p16F628A.inc> ; definiciones de variables específicas del procesador
ERRORLEVEL 1;-302 ; para evitar los mensajes de cambio de
; banco en el resultado del compilador
__CONFIG _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
;***** DEFINICIÓN DEL NOMBRE DE ENTRADAS Y SALIDAS
#define SERVO1 PORTA,0 ; puerto de salida de servo 1
#define PULSADOR1 PORTA,1 ; puerto de entrada de pulsador 1
#define PULSADOR2 PORTA,2 ; puerto de entrada de pulsador 2
#define PULSADOR3 PORTA,3 ; puerto de entrada de pulsador 3
;***** VARIABLES
CBLOCK 0x20
acum_A ; variable momentánea
Posic ; posición servo
ENDC
;***********************************************************************************
org 0x000
goto principal
;***********************************************************************************
; Principal
;***********************************************************************************
principal
movlw b'00000111' ; deshabilita comparadores. Esto es
movwf CMCON ; algo importante en el PIC 16F628A
clrf PORTA ; inicia ports
clrf PORTB ; inicia ports
bsf STATUS,RP0 ; Apunta a banco 1
movlw b'00001110' ; PORTA
movwf TRISA ; salidas menos 1, 2 y 3, entradas
MOVLW b'00000000' ; PORTB
movwf TRISB ; salidas
movlw b'00000010' ; Configuración para TMR0
movwf OPTION_REG ; preescaler 2, 1:8 con CLK interno (que es
; de 1 MHz si el oscilador es de 4 MHz).
; El contador cuenta cada 8 useg
bcf STATUS,RP0 ; Apunta a banco 0
clrf TMR0 ; inicia registro de timer en 0
movlw d'133' ; inicia valor de posición de servo (centro)
movwf Posic
;***********************************************************************************
; Lazo principal
;***********************************************************************************
lazo
; Los servos actúan con un pulso de control que va entre 0,5 ms y 2,5 ms.
; En el bloque que sigue se inicia en 1 el pulso de control y se espera un
; retardo fijo de aproximadamente 0,5 ms, que es el valor mínimo del pulso.
; Con este valor de longitud de pulso y una longitud cero en la parte variable,
; el servo está parado al máximo hacia la izquierda (sentido antihorario).
bsf SERVO1 ; pone la señal de servo en 1
bcf INTCON,T0IF ; borra el flag de timer
movlw d'192' ; (256-192 = 64) 64 * 8 us = 0,512 ms
movwf TMR0 ; valor al registro de timer
btfss INTCON,T0IF ; espera por timer = ff -> 00
goto $-1
bcf INTCON,T0IF ; borra el flag de timer
; A continuación, comienza el tiempo variable del pulso. Esto permite
; que el recorrido completo, de 180 grados (valores de pulso entre 0,5 ms
; y 2,5 ms), se divida en 256 segmentos (256 * 8 us = 2,048 ms).
; La parte variable del pulso de control varía entre 0 y 2 ms
movf Posic,w ; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5 ms
movwf TMR0 ; valor al registro de timer
btfss INTCON,T0IF ; espera por timer = ff -> 00
goto $-1
bcf SERVO1 ; pone la señal de servo en 0
bcf INTCON,T0IF ; borra el flag de timer
; Retardo de 20 ms, que es el tiempo estándar que debe separar los pulsos
; de control para los servos comunes de RC
movlw d'9' ; cantidad de veces: 9 x 2 ms = 18 ms + 2 ms
movwf acum_A
retardo bcf INTCON,T0IF ; borra el flag de timer
movlw d'6' ; (256-6 = 250) 250 * 8 us = 2 ms
movwf TMR0 ; valor al registro de timer
btfss INTCON,T0IF ; espera por timer = ff -> 00
goto $-1
decfsz acum_A ; decrementa cantidad de veces
goto retardo
pulsadores ; lee órdenes a través de pulsadores
btfss PULSADOR1
goto iniciaPos ; servo en posición central
btfss PULSADOR2
goto incPos ; incrementa Posic
btfss PULSADOR3
goto decPos ; decrementa Posic
goto lazo
iniciaPos movlw d'133' ; 256-133 = 123, 123 * 8 us = 984 us + 512 us
movwf Posic ; posición central en esta disposición
goto lazo ; y sale
decPos movf Posic,f ; se fija si Posic ya es cero
bz sale1 ; si es cero no decrementa
decf Posic,f ; si no es cero, decrementa
sale1 goto lazo ; y sale
incPos movlw 0xFF ; se fija si Posic no es 0xFF
xorwf Posic,w ; que es el valor máximo
bz sale2 ; si es el valor máximo, no incrementa
incf Posic,f ; si no es el valor máx, incrementa
sale2 goto lazo ; y sale
END
|
Bajar el programa en formato ASM (puede usar el botón derecho de su mouse)
Bajar el programa en formato HEX (puede usar el botón derecho de su mouse)
Por las dudas, el archivo incluido P16f628a.inc (puede usar el botón derecho de su mouse)
Diagrama de flujo del programa de control de un servo RC
Espero que en este programa se pueda ver con claridad la manera de
generar el pulso con los tiempos correctos. De hecho, lo hemos escrito lo más simple
posible por esta razón. Pero la verdad es que esta forma de hacerlo tiene el defecto
de que mientras se producen los retardos, el microcontrolador está en un lazo
cerrado, dedicado exclusivamente a esperar que se cumplan los tiempos.
¿Cómo se soluciona esto? Haciendo que los retardos se produzcan mientras
el microcontrolador está haciendo otra cosa. Y para hacer esto se debe utilizar una de las
herramientas más potentes y necesarias en un sistema que debe ser sensible a sucesos
producidos en el mundo real: las interrupciones.
Los invito, entonces, a continuar esta prueba de laboratorio en la
segunda parte de este trabajo: Control de servos con
interrupciones.
Algunas cosas que observé en la parte 1
- En algunas posiciones el servo queda temblando en lugar de quedar firme en su posición. Supongo que se debe a imprecisión en el contacto de su potenciómetro de posicionamiento más que a un pulso de control irregular.
- Importante: el temblor y el calentamiento del servo crecen mucho si se supera el retardo de 20 ms entre pulsos de control.
- Al pulsar los controles para mover continuamente el servo en uno u otro sentido, tal como está hecho el programa, el pulsador es leído cada 20 ms, es decir, unas 50 veces por segundo, lo que da una velocidad razonable de actualización y el servo se mueve con suficiente lentitud.
Datos adicionales:
Microcontrolador PIC16F628A
El PIC16F628A se puede comprar en
Cika.
Servo de modelismo o RC
Utilizamos el servo Hitec HS-311 porque era el más barato disponible en ese tipo al
momento de encarar el proyecto.
Recomendamos ver, para completar esta información -> Servos, Características básicas
|