Raspberry Pi

Controlar un servo motor con Rasperry Pi

En el tutorial de hoy vamos a ver los conceptos básicos para controlar un pequeño servo con nuestra Raspberry Pi. ¿No sabes qué es un servo? Mira nuestro artículo sobre motores servo para tener una idea de qué son estos motores  y cómo funcionan, pues serán muy útiles en futuros proyectos en los que pensemos mover cosas.

Contenidos

¿Qué necesitamos?

Utilizaremos una Raspberry Pi (con sus accesorios básicos como el teclado y el ratón, el cable HDMI y la alimentación por USB) con Python, una placa de prototipado, una fuente de alimentación externa, un motor servo y unos cuantos cables. La fuente de alimentación externa la emplearemos para alimentar el motor. Si bien podemos alimentar un pequeño dispositivo/sensor con la Pi, no es recomendable emplearla para darle corriente directamente a los servos y los motores en general, pues consumen mucha corriente y pueden hacer que nuestro sistema sea inestable (e incluso cargarse alguno de los pines de nuestra pi). Por ello, el único cable que conectaremos desde la Raspberry al servo será el cable que llevará la señal de control.

 

 

Realizar las conexiones

Ya vale de teoría, ¿cuándo empezamos? Vamos a mostraros las conexiones del circuito. Lo mejor será ilustrarlo con una fotografía.

Rpi servo connection En la imagen adjunta, puedes ver las conexiones a la Raspberry Pi y al servo motor. Hemos conectado el pin 3 (GPIO2) de la Pi a la señal de control del servo, mientras que utlizaremos una fuente de alimentación externa para alimentar el servo. En la imagen puedes observar también que hemos utilizado el pin 9 (GND) y lo hemos conectado al negativo (GND) de nuestra fuente de alimentación. Este último paso es importante, de lo contrario el servo no interpretará correctamente la señal que le enviamos. Mira los pines en nuestra página de conexiones.

Tabla de conexiones:

PIN Destino
GPIO2 (pin 3) Señal de control del servo (naranja)
GND (pin 9) GND de nuestra fuente
V+ fuente 5V Positivo del servo (rojo)
V- fuente 5V Negativo del servo (marrón)

Instalar la librería pigpio

Para instalar esta librería (que posiblemente ya tengas instalada), bastan los dos siguientes comandos:

$ sudo apt-get update
$ sudo apt-get install pigpio python-pigpio python3-pigpio

Puedes leer algo más sobre esta librería en el siguiente enlace: http://abyz.me.uk/rpi/pigpio/index.html

Lanzar el programa de ejemplo

Primero tendrás que editar el siguiente código en un fichero de nombre testservo.py.

#!/usr/bin/env python

# testservo.py

import time

import pigpio

pi = pigpio.pi() # Connect to local Pi.

# set gpio modes
pi.set_mode(2, pigpio.OUTPUT)


# start 1500 us servo pulses on gpio2
pi.set_servo_pulsewidth(2, 1500)
time.sleep(1)
for _i in range(5): #loop between -90 and 90 degrees
pi.set_servo_pulsewidth(2,2500)
time.sleep(1)
pi.set_servo_pulsewidth(2,600)
time.sleep(1)
pi.set_servo_pulsewidth(2, 1500)
time.sleep(1)

pi.set_servo_pulsewidth(2, 0) # stop servo pulses

pi.stop() # terminate connection and release resources

A continuación, le damos permisos de ejecución al código

pi@raspberrypi:~/pantiltproject $ chmod +x testservo.py

Lanzamos el demonio pigpio

Siempre que vayas a utilizar la librería, tendrás que ejecutar el demonio pigpiod (cada vez que reinicies tu raspberry pi, salvo que lo tengas automatizado en el inicio). Se trata de un programa que escuchará las peticiones de nuestro código y las ejecutará, de modo que podamos controlar los pines usando la librería. Comprobarás que tu programa se queja si no lo haces.

pi@raspberrypi:~/pantiltproject $ sudo pigpiod

Ejecutamos el código

pi@raspberrypi:~/pantiltproject $ ./testservo.py

Si lo hemos hecho todo bien, nuestro servo se centrará y oscilará entre 90º y -90º durante cinco ciclos, para acabar centrado.

¡Enhorabuena! Ya sabes cómo trabajar con servos en la Raspberry Pi.

 

Información adicional

¿No utilizabas antes la librería RPIO?

Cierto, en ejemplos antiguos empleábamos la librería RPIO. Sin embargo, a día de hoy la versión oficial es la 0.10.0, y esta es incapaz de reconocer la raspberry pi 3, fíjate lo que nos dice cuando ejecutamos en una Rpi3:

pi@raspberrypi:~/pantiltproject $ sudo python testservo.py
Traceback (most recent call last):
File "testservo.py", line 1, in <module>
from RPIO import PWM #import the library for PWM
File "build/bdist.linux-armv7l/egg/RPIO/__init__.py", line 115, in <module>
File "build/bdist.linux-armv7l/egg/RPIO/_GPIO.py", line 7, in <module>
File "build/bdist.linux-armv7l/egg/RPIO/_GPIO.py", line 6, in __bootstrap__
SystemError: This module can only be run on a Raspberry Pi!

En su repositorio github tienen abierto un issue sobre el asunto. Parece ser que se resuelve clonando una versión posterior, pero que no es la que se encuentra en los repositorios oficiales. Aun así, no nos parece bien que dos años después no se haya resuelto el problema, así que hemos buscado una alternativa que también trabaje con DMA y nos permita concentrarnos en nuestros proyectos.

¿Qué es RPIO.PWM? ¿Y DMA?

Durante mucho tiempo (aún ahora), para controlar los pines de la Pi se ha empleado una librería llamada RPi.GPIO, que nos da acceso a las entradas y salidas GPIO (General Purpose Input Output). El problema viene cuando nos damos cuenta de que esta librería utiliza algunos recursos de la CPU y no es tan rápida como queríamos. Para solventar el problema se creó RPIO.PWM, que nos permite escribir los valores usando los canales DMA (Direct Memory Access) y no consume casi ningún ciclo de CPU, por lo que será la librería que emplearemos en nuestros proyectos hemos buscado una librería con estas características para nuestro proyectos.

Otro detalle de la librería es que no necesitamos un canal DMA para cada servo (podemos controlar varios servos con distintos pines de salida de la GPIO), sino que asignamos un canal a la librería y luego podemos trabajar con varios servos en simultáneo.

Instalar la librería RPIO

Si bien ya no utilizamos esta librería, te dejamos aquí la instalación y el código que se empleaba anteriormente. La instalación, tal como se describe en la documentación es como sigue:

$ sudo apt-get install python-setuptools
$ sudo easy_install -U RPIO

Código para mover el servo motor con RPIO

Nota: este código utiliza librerías que acceden internamente al hardware. Por lo tanto, tendrás que ejecutarlo en modo root (sudo python testservo.py).

El siguiente código escrito en Python sirve para realizar unos sencillos movimiento con el servo. Primero que nada una pequeña dosis de realidad: las especificaciones de los motores servo no son perfectas, especialmente si son tan económicos como el que empleamos en estas pruebas. Si bien en el datasheet se indicaba uqe con una señal de 2ms se alanzarían los 90 grados, en la práctica esa señal sólo mueve el servo hasta los 45º, haciendo necesario enviar una señal de 2.5ms para colocarlo en 90º. Tras varias pruebas, la señal que necesitamos para mover el servo a -90º es de 0.6ms, frente al 1 ms que indica el datasheet.

(nota: habrás notado que la señal de 2.5ms excede el ciclo de control de 2ms, y nos resulta muy curioso, pero en este momento no disponemos de otro modelo de servo para comprobar si el problema radica en la librería PWM o en el servo, así que lo dejaremos para otro momento.)

El código importa la librería PWM y time (sólo para hacer delays), y hace una llamada de inicialización de la librería. A partir de ahí, le mandamos una señal de 1.5ms para colocarlo en 0 grados, y entramos en un bucle que se repetirá 10 veces en el que movemos alternativamente el servo entre 90º y -90º. Este código, bastante sencillo, es todo lo que se necesita para trabajar con un servo. Nótese que podríamos mandar una señal a cualquier otra GPIO y mover varios servos simultáneamente. La librería para el servo al finalizar el programa, pero si tenemos un programa largo y queremos dejar de mandarle una señal, podemos hacer servo.stop_servo(2), donde el número indica la salida GPIO a parar.

from RPIO import PWM          #import the library for PWM
import time                   #import time for pauses
servo=PWM.Servo()             #initialize the servo library
servo.set_servo(2,1500)       #center the MG90S
time.sleep(1)
for _i in range(10):          #loop between -90 and 90 degrees
    servo.set_servo(2,2500)
    time.sleep(1)
    servo.set_servo(2,600)
    time.sleep(1)
servo.set_servo(2,1500)
time.sleep(1)

Sobre canales DMA.

Los canales DMA permiten al hardware de control de los GPIO acceder directamente a la memoria sin necesidad de la intervención de la CPU. Existen 15 canales DMA en nuestra RPi que podemos utilizar con nuestra librería. Hay que tener en cuenta, sin embargo, qué canales pueden estar ocupados, porque de lo contrario no conseguiremos trabajar con ellos. El canal 0 está ocupado con el frame buffer, los canales 1,3,6 y 7 por la GPU, el 2 está reservado para la tarjeta SD, y el 15 lo pusieron en otro lado (la explicación es algo complicada y la dejamos para otro día). Por lo tanto, hay que tener cuidado en nuestro código para emplear otro canal de los que acabamos de mencionar.

 

fuentes: foro de raspberry pi, raspberry pi exchange, muestras de código de RPIO

¿Tienes alguna duda sobre este mini proyecto? ¿Has aplicado lo que has aprendido en un proyecto interesante? ¡Te esperamos en los comentarios!

(Visto 14.693 vecess, 1 visitas hoy)
¡Comparte este articulo!

13 comentarios en «Controlar un servo motor con Rasperry Pi»

  • Hola , tengo una duda
    hay muchas maneras de mover servos pero en ninguna encuentro la manera de que por ejemplo de 0 a 180º vaya a una velocidad deseada.
    Alguien sabe como aumentar el tiempo de pulso?
    Gracias
    saludos

    Respuesta
  • Pingback: Control de cámara IP usando servos y un servidor web en Raspberry pi - Nociones.de

  • Buen día amigo, se puede utilizar la librería pigpio para controlar un servo por DMA?, no he logrado instalar la lib RPIO.PWM en mi Raspberry pi3 B+ y necesito ser muy exacto con la señal enviada al servo. Agradezco cualquier ayuda al respecto.

    Respuesta
    • Hola Weimar,
      si, la librería pigpio también utiliza DMA. Ya comentábamos en el artículo que hay un problema con la RPIO y la raspberry PI 3B+.
      Respecto a la exactitud, la señal será justo la que tú le indicas. Si te refieres a la velocidad de cambio a la hora de enviar una nueva señal, no hemos realizado pruebas, pero en nuestro próximo artículo mostraremos cómo mover una cámara con servos y no apreciamos ningún retraso para esta utilidad. Habría que evaluar el proyecto y si necesitas otra placa, como Arduino, en caso de que necesites más velocidad.
      Un saludo,
      Admin.

      Respuesta
      • Muchas gracias por tu respuesta, efectivamente me toco utilizar pigpio para hacer uso de DMA. Sin embargo tengo otro problema; tengo que controlar 4 servomotores, mas o menos tienen que cambiar de posición simultáneamente cada 300ms (con estoy no hay problema), estoy conectando los servos a los 4 pines PWM de la raspberry (GPIO 12,13,18 y 19), sin embargo al enviar la instrucción pi.hardware_PWM(18, 50, 75000) se mueven los servos del GPIO 18 y 12 porque comparten el channel 0; de igual manera al tratar de controlar el GPIO 13 o 19. Hay alguna forma de independizar o asignar un canal a cada GPIO para evitar que realicen el mismo movimiento?, en mi proyecto los servos nunca comparten la posición y no puedo dejar de utilizar DMA por la precisión requerida. Agradezco cualquier ayuda.

        Respuesta
  • tengo una duda, se puede usar cualquier pin de GPIO? ejemplo, puedo usar más de un servo para esto?

    Respuesta
    • Claro que si :-). Justo tenemos un artículo hace más de un mes en el tintero en el que describimos cómo mover una cámara con este sistema. A ver si nuestro admin se sienta y lo termina…

      Respuesta
  • que tal, estoy tratando de correr tu programa en mi raspberry, ya realice la parte de la instalacion de la libreria RPIO, pero al momento de ejecutar el programa, obtengo el error: ImportError: No module named ‘RPIO’, no se si estoy realizando mal la instalacion de la libreria, podrias ayudarme?

    Respuesta
    • Hola,
      pues sí, es posible que no tengas instalada la librería correctamente, ¿estás ejecutando tu código con sudo? Es necesario usar sudo con esta librería, pues necesita permiso para acceder al hardware. De todas formas, acabamos de probar el ejemplo en nuestra Raspberry pi 3 y la versión actual de RPIO parece que no la detecta (existe una rama de desarrollo que sí, pero no es la versión publicada).
      Como solución: hemos cambiado de librería. En breve actualizaremos el artículo con nuevos ejemplos y podrás comprobar si el nuevo código se te ejecuta correctamente. Sólo un poco de paciencia, estamos justo ahora trabajando en ello ;-).
      ¡Un saludo!

      Respuesta
      • Hola Luis,
        ya hemos actualizado el artículo con la librería pigpio. Acabamos de probarlo con una RPi3 y funciona perfectamente, ¡Espero que te sirva!
        Un saludo,
        admin.

        Respuesta
  • Hola que tal amigo , tengo un problema al instalar la libreria , hay algun sistemas operativo que tenga ya libreria aprte del raspbian ????

    Respuesta
    • ¿Qué problema tenías exactamente? En realidad cualquier sistema operativo basado en debian (ubuntu, por ejemplo) puede instalar esa librería, pero esta librería es para los pines de la Raspberry Pi, así que te recomendaría que siguieras con raspbian. Si me dices qué sistema operativo quieres probar, igual puedo ayudarte. ¡Un saludo!

      Respuesta

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *