Tabla de contenido:

Control de servo múltiple Pan-Tilt: 11 pasos (con imágenes)
Control de servo múltiple Pan-Tilt: 11 pasos (con imágenes)

Video: Control de servo múltiple Pan-Tilt: 11 pasos (con imágenes)

Video: Control de servo múltiple Pan-Tilt: 11 pasos (con imágenes)
Video: Robotica - Control de Sistema Pan & Tilt con Servomotores - Crea tu Propia APP - Arduino 2024, Noviembre
Anonim
Control de servo múltiple Pan-Tilt
Control de servo múltiple Pan-Tilt

En este tutorial, exploraremos cómo controlar múltiples servos usando Python en una Raspberry Pi. Nuestro objetivo será un mecanismo PAN / TILT para colocar una cámara (una PiCam).

Aquí puedes ver cómo funcionará nuestro proyecto final:

Prueba de lazo de control de servocontrol:

Imagen
Imagen

Paso 1: BoM - Lista de materiales

Partes principales:

  1. Raspberry Pi V3 - US $ 32,00
  2. 5 megapíxeles 1080p Sensor OV5647 Mini módulo de video de cámara - US $ 13.00
  3. TowerPro SG90 9G 180 grados Micro Servo (2 X) - US $ 4,00
  4. Soporte de cámara antivibración con plataforma de cámara mini panorámica / inclinación con 2 servos (*) - US $ 8.00
  5. Resistencia 1K ohmios (2X) - Opcional
  6. Varios: piezas metálicas, bandas, etc. (en caso de que construya su mecanismo Pan / Tilt)

(*) puedes comprar una plataforma Pan / Tilt completa con los servos o construir la tuya propia.

Paso 2: Cómo funciona PWM

La Raspberry Pi no tiene salida analógica, pero podemos simular esto usando un enfoque PWM (Modulación de ancho de pulso). Lo que haremos es generar una señal digital con una frecuencia fija, donde cambiaremos el ancho del tren de pulsos, lo que se "traducirá" como un nivel de voltaje de salida "promedio" como se muestra a continuación:

Imagen
Imagen

Podemos usar este nivel de voltaje "promedio" para controlar el brillo de un LED, por ejemplo:

Imagen
Imagen

Tenga en cuenta que lo que importa aquí no es la frecuencia en sí, sino el "ciclo de trabajo", que es la relación entre el tiempo en que el pulso es "alto" dividido por el período de onda. Por ejemplo, supongamos que generaremos una frecuencia de pulso de 50 Hz en uno de nuestros Raspberry Pi GPIO. El período (p) será el inverso de la frecuencia o 20 ms (1 / f). Si queremos que nuestro LED tenga un "medio" brillante, debemos tener un Ciclo de Trabajo del 50%, eso significa un "pulso" que será "Alto" durante 10ms.

Este principio será muy importante para nosotros, para controlar la posición de nuestro servo, una vez que el "Duty Cycle" definirá la posición del servo como se muestra a continuación:

Servo

Paso 3: Instalación del Hw

Instalación del Hw
Instalación del Hw
Instalación del Hw
Instalación del Hw

Los servos se conectarán a una fuente externa de 5V, teniendo su pin de datos (en mi caso, su cableado amarillo) conectado a Raspberry Pi GPIO como se muestra a continuación:

  • GPIO 17 ==> Servo de inclinación
  • GPIO 27 ==> Pan Servo

No olvide conectar los GND juntos ==> Raspberry Pi - Servos - Fuente de alimentación externa)

Puede tener como opción, una resistencia de 1K ohmios entre Raspberry Pi GPIO y pin de entrada de datos del servidor. Esto protegería su RPi en caso de un problema con el servo.

Paso 4: Calibración de servos

Calibración de servos
Calibración de servos
Calibración de servos
Calibración de servos
Calibración de servos
Calibración de servos

Lo primero que debes hacer es confirmar las principales características de tus servos. En mi caso, estoy usando un Power Pro SG90.

De su hoja de datos, podemos considerar:

  • Rango: 180o
  • Fuente de alimentación: 4.8V (5VDC externo como fuente de alimentación USB funciona bien)
  • Frecuencia de trabajo: 50 Hz (período: 20 ms)
  • Ancho de pulso: de 1 ms a 2 ms

En teoría, el servo estará en su

  • Posición inicial (0 grados) cuando se aplica un pulso de 1 ms a su terminal de datos
  • Posición neutra (90 grados) cuando se aplica un pulso de 1,5 ms a su terminal de datos
  • Posición final (180 grados) cuando se aplica un pulso de 2 ms a su terminal de datos

Para programar una posición de servo usando Python será muy importante conocer el "Ciclo de trabajo" correspondiente para las posiciones anteriores, hagamos algunos cálculos:

  • Posición inicial ==> (0 grados) Ancho de pulso ==> 1ms ==> Ciclo de trabajo = 1ms / 20ms ==> 2.0%
  • Posición neutra (90 grados) Ancho de pulso de 1.5 ms ==> Ciclo de trabajo = 1.5ms / 20ms ==> 7.5%
  • Posición final (180 grados) Ancho de pulso de 2 ms ==> Ciclo de trabajo = 2ms / 20ms ==> 10%

Por lo tanto, el ciclo de trabajo debe variar en un rango de 2 a 10%.

Probemos los servos individualmente. Para eso, abra su terminal Raspberry e inicie su editor de shell Python 3 como "sudo" (debido a que debe ser un "superusuario" para manejar con GPIO):

sudo python3

En Python Shell

>>

Importe el módulo RPI. GPIO y llámelo GPIO:

importar RPi. GPIO como GPIO

Defina qué esquemas de numeración de pines desea utilizar (BCM o BOARD). Hice esta prueba con BOARD, por lo que los pines que usé fueron los pines físicos (GPIO 17 = Pin 11 y GPIO 27 Pin 13). Me fue fácil identificarlos y no cometer errores durante la prueba (En el programa final usaré BCM). Elija el de su preferencia:

GPIO.setmode (GPIO. BOARD)

Defina el pin del servo que está utilizando:

tiltPin = 11

Si, en cambio, ha utilizado el esquema BCM, los últimos 2 comandos deben reemplazarse por:

GPIO.setmode (GPIO. BCM)

tiltPin = 17

Ahora, debemos especificar que este pin será una "salida"

Configuración de GPIO (tiltPin, GPIO. OUT)

Y cuál será la frecuencia generada en este pin, que para nuestro servo será de 50Hz:

inclinación = GPIO. PWM (tiltPin, 50)

Ahora, comencemos a generar una señal PWM en el pin con un ciclo de trabajo inicial (lo mantendremos en "0"):

inclinación = inicio (0)

Ahora, puede ingresar diferentes valores de ciclo de trabajo, observando el movimiento de su servo. Comencemos con el 2% y veamos qué sucede (esperamos que el servo vaya a la "posición cero"):

tilt. ChangeDutyCycle (2)

En mi caso, el servo fue a la posición cero pero cuando cambié el ciclo de trabajo al 3% observé que el servo permanecía en la misma posición, comenzando a moverse con ciclos de trabajo mayores al 3%. Entonces, el 3% es mi posición inicial (o grados). Lo mismo sucedió con el 10%, mi servo superó este valor, superando su final en el 13%. Entonces, para este servo en particular, el resultado fue:

  • 0 grados ==> ciclo de trabajo del 3%
  • 90 grados ==> ciclo de trabajo del 8%
  • 180 grados ==> ciclo de trabajo del 13%

Una vez que termine sus pruebas, debe detener el PWM y limpiar los GPIO:

inclinación = parada ()

GPIO.cleanup ()

La pantalla de impresión de Terminal anterior muestra el resultado de mis dos servos (que tiene resultados similares). Tu rango puede ser diferente.

Paso 5: creación de una secuencia de comandos de Python

Crear una secuencia de comandos de Python
Crear una secuencia de comandos de Python

Los comandos PWM que se enviarán a nuestro servo están en "ciclos de trabajo" como vimos en el último paso. Pero por lo general, debemos usar "ángulo" en grados como parámetro para controlar un servo. Por lo tanto, debemos convertir el "ángulo" que es una medida más natural para nosotros en el ciclo de trabajo como lo puede entender nuestro Pi.

¿Cómo hacerlo? ¡Muy simple! Sabemos que el rango del ciclo de trabajo va del 3% al 13% y que esto equivale a ángulos que oscilarán entre 0 y 180 grados. Además, sabemos que esas variaciones son lineales, por lo que podemos construir un esquema proporcional como se muestra arriba. entonces, dado un ángulo, podemos tener un ciclo de trabajo correspondiente:

ciclo de trabajo = ángulo / 18 + 3

Conserva esta fórmula. Lo usaremos en el siguiente código.

Creemos un script de Python para ejecutar las pruebas. Básicamente, repetiremos lo que hicimos antes en Python Shell:

desde el momento de importar el sueño

importar RPi. GPIO como GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) def setServoAngle (servo, ángulo): pwm = GPIO. PWM (servo, 50) pwm.start (8) dutyCycle = angle / 18. + 3. pwm. ChangeDutyCycle (dutyCycle) sleep (0.3) pwm.stop () if _name_ == '_main_': import sys servo = int (sys.argv [1]) GPIO.setup (servo, GPIO. OUT) setServoAngle (servo, int (sys.argv [2])) GPIO.cleanup ()

El núcleo del código anterior es la función setServoAngle (servo, angle). Esta función recibe como argumentos, un número GPIO de servo y un valor de ángulo al que debe colocarse el servo. Una vez que la entrada de esta función es "ángulo", debemos convertirlo a ciclo de trabajo en porcentaje, utilizando la fórmula desarrollada anteriormente.

Cuando se ejecuta el script, debe ingresar como parámetros, servo GPIO y ángulo.

Por ejemplo:

sudo python3 angleServoCtrl.py 17 45

El comando anterior posicionará el servo conectado en GPIO 17 con 45 grados en "elevación". Se podría usar un comando similar para el control Pan Servo (posición a 45 grados en "azimut"):

sudo python angleServoCtrl.py 27 45

El archivo angleServoCtrl.py se puede descargar desde mi GitHub

Paso 6: el mecanismo de giro e inclinación

El mecanismo de giro e inclinación
El mecanismo de giro e inclinación

El servo "Pan" moverá "horizontalmente" nuestra cámara ("ángulo azimutal") y nuestro servo "Tilt" lo moverá "verticalmente" (ángulo de elevación).

La siguiente imagen muestra cómo funciona el mecanismo Pan / Tilt:

Imagen
Imagen

Durante nuestro desarrollo no iremos a "extremos" y usaremos nuestro mecanismo Pan / Tilt solo de 30 a 150 grados. Este rango será suficiente para ser utilizado con una cámara.

Paso 7: El mecanismo de giro e inclinación: construcción mecánica

El mecanismo de giro e inclinación: construcción mecánica
El mecanismo de giro e inclinación: construcción mecánica
El mecanismo de giro e inclinación: construcción mecánica
El mecanismo de giro e inclinación: construcción mecánica
El mecanismo de giro e inclinación: construcción mecánica
El mecanismo de giro e inclinación: construcción mecánica

Vamos a montar nuestros 2 servos como mecanismo Pan / Tilt. Puedes hacer 2 cosas aquí. Compre un mecanismo de plataforma Pan-Tilt como el que se muestra en el último escalón o construya el suyo según sus necesidades.

Un ejemplo puede ser el que construí, solo atando los servos entre sí y usando pequeñas piezas de metal de juguetes viejos como se muestra en las fotos de arriba.

Paso 8: Ensamblaje eléctrico de giro / inclinación

Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación
Ensamblaje eléctrico de giro / inclinación

Una vez que haya ensamblado su mecanismo Pan / Tilt, siga las fotos para una conexión eléctrica completa.

  1. Apaga tu Pi.
  2. Realice todas las conexiones eléctricas.
  3. Compruébalo dos veces.
  4. Enciende tu Pi primero.
  5. Si todo está bien, encienda sus servos.

No exploraremos en este tutorial cómo configurar la cámara, esto se explicará en el siguiente tutorial.

Paso 9: el script de Python

Creemos un script de Python para controlar ambos servos simultáneamente:

desde el momento de importar el sueño

importar RPi. GPIO como GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) pan = 27 tilt = 17 GPIO.setup (tilt, GPIO. OUT) # white => TILT GPIO.setup (pan, GPIO. OUT)) # gray ==> PAN def setServoAngle (servo, angle): afirmar ángulo> = 30 y ángulo 90 (punto medio) ==> 150 setServoAngle (tilt, int (sys.argv [2])) # 30 ==> 90 (punto medio) ==> 150 GPIO.cleanup ()

Cuando se ejecuta el script, debe ingresar como parámetros, Ángulo de panorámica y Ángulo de inclinación. Por ejemplo:

sudo python3 servoCtrl.py 45120

El comando anterior colocará el mecanismo Pan / Tilt con 45 grados en "azimut" (ángulo de Pan) y 120 grados de "elevación" (ángulo de inclinación). Tenga en cuenta que si no se ingresan parámetros, el valor predeterminado será ambos ángulos de giro e inclinación configurados en 90 grados.

A continuación puedes ver algunas pruebas:

Imagen
Imagen

El archivo servoCtrl.py se puede descargar desde mi GitHub.

Paso 10: Prueba de bucle de servidores

Creemos ahora un script de Python para probar automáticamente la gama completa de servos:

desde el momento de importar el sueño

importar RPi. GPIO como GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) pan = 27 tilt = 17 GPIO.setup (tilt, GPIO. OUT) # white => TILT GPIO.setup (pan, GPIO. OUT)) # gray ==> PAN def setServoAngle (servo, angle): afirmar ángulo> = 30 y ángulo <= 150 pwm = GPIO. PWM (servo, 50) pwm.start (8) dutyCycle = ángulo / 18. + 3. pwm. ChangeDutyCycle (dutyCycle) sleep (0.3) pwm.stop () if _name_ == '_main_': for i in range (30, 160, 15): setServoAngle (pan, i) setServoAngle (tilt, i) for i in rango (150, 30, -15): setServoAngle (pan, i) setServoAngle (tilt, i) setServoAngle (pan, 100) setServoAngle (tilt, 90) GPIO.cleanup ()

El programa ejecutará automáticamente un bucle de 30 a 150 grados en ambos ángulos.

Debajo del resultado:

Conecté un osciloscopio solo para ilustrar la teoría PWM como se explicó antes.

Imagen
Imagen

El código anterior, servoTest.py se puede descargar desde mi GitHub.

Paso 11: Conclusión

Conclusión
Conclusión

Como siempre, espero que este proyecto pueda ayudar a otros a encontrar su camino hacia el apasionante mundo de la electrónica.

Para obtener detalles y el código final, visite mi depósito de GitHub: RPi-Pan-Tilt-Servo-Control

Para más proyectos, visite mi blog: MJRoBot.org

A continuación, un vistazo a mi próximo tutorial:

Imagen
Imagen

¡Saludos desde el sur del mundo!

¡Nos vemos en mi próximo instructable!

Gracias, Marcelo

Recomendado: