Servo

Servo

Hoy vamos a hablar  un poco de los servos, y veremos como utilizarlos con la Raspberry Pi.

Un servo o servomotor es un dispositivo que contiene un eje que pude ubicarse y permanecer estable, es posiciones angulares concretas al enviarle un señal codificada a su entrada de control.

Básicamente es un motor eléctrico que incorpora un sistema de regulación de la posición.

Cuando la señal codificada cambia el ancho de su pulso, la posición angular del eje del servo cambia. Es decir, modulando el ancho del pulso de la señal (PWM), indicamos la posición donde queremos que permanezca el eje del servo.

Ejemplo-Servo

Funcionamiento:

El motor del servo tiene algunos circuitos de control y un potenciómetro conectado al eje del servo. Este potenciómetro permite a la circuitería de control, supervisar el ángulo actual del servo motor. Si el eje está en el ángulo correcto, entonces el motor está apagado. Si el circuito detecta que el ángulo no es el correcto, el motor girará en la dirección adecuada hasta llegar al ángulo correcto. El eje del servo es capaz de girar en un rango de 0 a 180 grados normalmente, en algunos puede llegar hasta los 210. Varía según el fabricante.

El voltaje aplicado al motor es proporcional a la distancia que éste necesite recorrer. Si el eje necesita variar su posición un número elevado de grados, el motor girará a toda velocidad, mientras que si necesita desplazarse un ángulo pequeño, se moverá a una velocidad más lenta. A esto se le llama control proporcional.

SG90

En este caso, vamos a utilizar servos SG90, cuyas características son las siguientes:

Peso: 9g Dimensiones: 22,2 x 11,8 x 31 mm Par de bloqueo: 1,8 Kgf*cm Velocidad de giro: 0,1s/60º Vcc = 4.8 V (≈ 5 V)

En cuanto al servo, tiene 3 cables:

Cables_SG90

En nuestro caso, usando 2 servos, hemos conectado el cable naranja  (PWM) de uno de ellos al pin 17 de la Raspberry pi, y el cable naranja del otro al pin 18. Para evitar ruido podemos añadirle a esta conexión una resistencia de 1kΩ.

En el caso de las alimentaciones, conectamos los cables rojos al pin de 5V de la Raspberry Pi, y los cables marrones del servo a la masa (GND) de la Raspberry.

Utilizando un programa en python similar al siguiente, podemos controlar el movimiento de los servos:

#!/usr/bin/python
# -*- coding: utf-8 -*-
#################################################
#                                               #
# Servos control module                         #
# Authors: Ismael Tobar and Raquel Muñoz        #
#                                               #
#################################################
#----Libraries
import RPi.GPIO as GPIO
import threading from time
import sleep
# Constants:
T = 20 #signal period (ms).
STEPS = 50 #Number of iteration that the signal is repeated. This is necesary to the servo has time to change.
MIN_PULSE = 0.83 #Min width of pulse. (ms)
MAX_PULSE = 2.2 #Max width of pulse. (ms) #2.6
MIN_DEGREE = 0 MAX_DEGREE = 180 DEGREE_MS = (MAX_PULSE-MIN_PULSE)/180 #Transform the degree to applicate into a time (in ms) variable
INITIAL_PULSE = 1.74

#Variables
servo_stopped = True
#Servos' pins
S1 = 17
S2 = 18
# Raspberry Pi GPIO Configuration:
def setup():
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(S1,GPIO.OUT)
  GPIO.setup(S2,GPIO.OUT)
  GPIO.output(S1, False)
  GPIO.output(S2, False)
  print('Servo: Setup')

def thread_servo(d,s): #The pwm signal is done through Software global servo_stopped
  h = d/1000
  l = (T-d)/1000
  if MIN_PULSE <= d <= MAX_PULSE:
    for i in range (0,STEPS):
      GPIO.output(s, True)
      sleep(h)
      GPIO.output(s, False)
      sleep(l)
      servo_stopped = True
  clean()
  #Each time you finish moving the servo is necessary to clean the pins so they do not move with noise

  #move the selected servo (n=1 or n=2) to the degree indicated (between 0 and 180)
def moveServo(degree,n):
  print('moveServo',degree,n)
  global servo_stopped
  try:
    if servo_stopped:
      if MIN_DEGREE <= degree <= MAX_DEGREE:
        setup()
        print(degree)
        if n == 1:
          thread_s = threading.Thread(target=thread_servo, args=((degree * DEGREE_MS) + MIN_PULSE, S1, ))
          servo_stopped = False
          thread_s.start()
        elif n == 2:
          thread_s = threading.Thread(target=thread_servo, args=((degree * DEGREE_MS) + MIN_PULSE, S2, ))
          servo_stopped = False
          thread_s.start()
  except Exception as e:
    print("Servo: Error starting servo thread")
    print(e)

def clean():
  GPIO.cleanup(S1)
  GPIO.cleanup(S2)

def stop_servo():
  global servo_stopped
  servo_stopped = True

if __name__ == "__main__":
  terminate = False #finish the while()
  # if run directly we'll just create an instance of the class and output
  setup()
  ser = 3
  while terminate == False:
    sleep(0.1)
    ser = 3
    ser = input('Enter servo 1 or 2: (0 to exit) : ')
    if ser == 0:
      terminate = True
    else:
      deg = input('Enter degree (0 to 180) : ') #The degrees are asked
      if 1<= ser <= 2:
        moveServo(deg,ser)
  GPIO.cleanup() print('Servo: Exit servo')

Si te ha interesado esta entrada, puedes ver aquí para que hemos utilizado estos servos.