Practica 7 Servo
Introducción:
En esta práctica vamos a controlar un servomotor mediante
programación en Python. El objetivo es mover
el servo una cantidad de grados, introducida mediante teclado, entre 0 y
180 grados. Haremos esta práctica en la RaspBerry Pi para poder usar sus pines GPIO.
Desarrollo:
Los servos son un tipo especial de
motor de c.c. que se caracterizan por su capacidad para posicionarse de forma
inmediata en cualquier posición dentro de su intervalo de operación. Están
generalmente formados por un amplificador, un motor, un sistema reductor
formado por ruedas dentadas y un circuito de realimentación, todo en un misma
caja de pequeñas dimensiones. El resultado es un servo de posición con un
margen de operación de 180° aproximadamente.
En nuestro caso vamos a utilizar
un servo Tower Pro SG90, cuyas características son las siguientes:
-Torque:
1.8 Kg*cm
-Tensión:
4.8 V (5 V aprox.)
-Velocidad
de operación: 0.1sg/60 grados
Posee tres cables, rojo, marrón y
naranja. Los dos primeros corresponde a la tensión de alimentación y GND
respectivamente y el ultimo corresponde al cable que lleva la señal codificada.
Este tipo de motores funciona con modulación de ancho de pulsos (PWM),
consisten básicamente en enviar una onda cuadrada en la que se varía el tiempo
en el que se mantiene el nivel alto del pulso. Los servos generalmente
funcionan con un tiempo del pulso alto de entre 1ms y 2 ms, siendo el 1ms 0
grados y 2 ms 180. Por lo que por ejemplo 90 grados sería un pulso de nivel
alto en PWM de 1.5 ms de duración y así para todos los grados. Para este servo
el tiempo de pulso completo (nivel alto y bajo), es de 20 ms. Al tiempo del
nivel alto es lo que conocemos por Duty Cycle.
Esto sería en teoría,
empíricamente se ha tenido que sacar una tabla para saber cuántos milisegundos
corresponden a cada grado.
Milisegundos
(ms)
|
Grados(º)
|
Porcentaje PWM
(%)
|
1
|
0
|
2.25
|
1.1
|
20
|
3
|
1.2
|
40
|
4.05
|
1.3
|
60
|
4.95
|
1.4
|
80
|
5.85
|
1.5
|
90
|
6.3
|
1.6
|
100
|
6.75
|
1.7
|
120
|
7.65
|
1.8
|
140
|
8.83
|
1.9
|
160
|
10.25
|
2
|
180
|
10.98
|
El porcentaje es lo que se
introduce en el programa de Python para la instrucción “ChangeDutyCycle”, ya
que en la librería está definido así. Como podemos observar es algo diferente
al plano teórico, ya que en porcentaje, 1 ms que correspondería a 0 grados, sería
un 5 %, ya que es 1 ms sobre 20 ms que dura el pulso completo, y empíricamente
es 2.25 %. Y el porcentaje correspondiente a 180 grados siguiendo la misma
regla, sería del 10 % y es de 10.98%.
A continuación se muestra el
programa utilizado en Python con comentarios de las instrucciones utilizadas.
También adjunto un enlace en el
que viene muy bien explicado el funcionamiento de los servomotores:
Programa:
### Autor: Guillermo Cayetano
Espejo Fecha: 09/12/2016
### Version: 1.0 Dispositivo:
Raspberry Pi 3
#############################
# Programa mediante el cual
controlaremos un servo a través de la Raspberry Pi, #introduciendo el número de
grados por teclado.
#############################
import RPI.GPIO as GPIO #Importamos la librería RPI.GPIO con la que
controlaremos los pines #GPIO de la Raspi.
import time # Importamos la librería time ya que
utilizaremos la función sleep de ella que es #en Python la que utilizaremos
para hacer un delay.
#### Configuracion ####
GPIO.setmode(GPIO.BOARD) # Ponemos
los pines en modo Board.
GPIO.setup(13.GPIO.OUT) #Ponemos
el pin 13 como salida.
GPIO.setwarnings(False) #
Desactiva los avisos.
p=GPIO.PWM(13.50) #Ponemos el pin
13 en modo PWM y le mandamos 50 pulsos por #segundo ya que un pulso es de 20 ms
en el servo.
p.start(6.3) # Enviamos un pulso
de 6.3 para centrar el servo, al pin 13 que es donde #conectaremos el cable de
señal del servo.
grados=0 #Inicializamos la
variable grados
posición =6.3 # Inicializamos la
variable posición y le ponemos la misma variable que la que le #hemos puesto
previamente.
print(‘Pulse control+c cuando
quiera salir’) # Mensaje que avisa del modo de salir del programa
opción=1 # Inicializo la variable
en 1
try:
while opción!=0
# Iniciamos el loop del programa ya que opción vale 1 pr lo que #siempre va a
entrar en este loop.
grados=int(input(‘Introduce
el numero de grados , entre 0 y 180’)) # Introducimos por #teclado el numero de
grados que queremos que se gire el servo y se guarda en la #variable grados.
if
grados<=20 and grados >=0:
posición=2.4+(grados*0.375)/10
#0.375 es la media ponderada de los #incrementos del dutycycle en incrementos de grados de 10 en 10, esta #medición se ha hecho experimentalmente. Se multiplica por los grados #introducidos y se divide entre 10 que corresponde a los grados de cada #intervalo, después se le suma el porcentaje inicial (el que corresponde a grados).
#0.375 es la media ponderada de los #incrementos del dutycycle en incrementos de grados de 10 en 10, esta #medición se ha hecho experimentalmente. Se multiplica por los grados #introducidos y se divide entre 10 que corresponde a los grados de cada #intervalo, después se le suma el porcentaje inicial (el que corresponde a grados).
p.ChangeDutyCycle(posición)
# Esta instrucción mueve el servo, pero en vez de #introducirle los
milisegundos que corresponden a los grados, le introducimos #como paramento el
porcentaje correspondiste a esos milisegundos, teniendo #en cuenta que el 100% sería
el pulso PWM completo es decir 20 ms, como #nuestro nivel alto de dicho pulso
solo va a ser de 1 ms (entre 1 ms y 2 ms) #nuestros porcentajes se moverán aproximadamente
entre el 5 y el 10 %
time.sleep(0.5)
# Damos un retardo de medio segundo para mover el servo antes de dirigirlo a
otra poscion.
if
grados<=40 and grados >=20:
posición=2.25+(grados*0.45)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=60 and grados >=40:
posición=2.25+(grados*0.45)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=80 and grados >=60:
posición=2.25+(grados*0.45)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=100 and grados >=80:
posición=2.25+(grados*0.45)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=120 and grados >=100:
posición=2.25+(grados*0.45)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=140 and grados >=120:
posición=2.25+(grados*0.47)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=160 and grados >=140:
posición=2.25+(grados*0.5)/10
p.ChangeDutyCycle(posición)
time.sleep(0.5)
if
grados<=180 and grados >=160:
posición=2.25+(grados*0.485)/10
p.ChangeDutyCycle(posición)
No hay comentarios:
Publicar un comentario