4.3 Servo Oscilante

Un Servo es un tipo de dispositivo basado en la posición conocido por su capacidad para mantener ángulos específicos y proporcionar una rotación precisa. Esto lo hace altamente deseable para sistemas de control que demandan ajustes de ángulo consistentes. No es sorprendente que los Servos se hayan utilizado ampliamente en juguetes controlados remotamente de alta gama, desde modelos de aviones hasta réplicas de submarinos y robots controlados remotamente sofisticados.

En esta aventura intrigante, nos desafiaremos a manipular el Servo de una manera única: ¡haciéndolo balancearse! Este proyecto ofrece una brillante oportunidad para profundizar en la dinámica de los Servos, afilando tus habilidades en sistemas de control precisos y ofreciendo una comprensión más profunda de su operación.

¿Estás listo para hacer bailar al Servo a tu ritmo? ¡Embarquémonos en este emocionante viaje!

Componentes Requeridos

Para este proyecto, necesitaremos los siguientes componentes.

Es definitivamente conveniente comprar un kit completo, aquí está el enlace:

Nombre

ELEMENTOS EN ESTE KIT

ENLACE

Kit de Inicio ESP32

320+

ESP32 Starter Kit

También puedes comprarlos por separado en los enlaces a continuación.

INTRODUCCIÓN AL COMPONENTE

ENLACE DE COMPRA

ESP32 WROOM 32E

BUY

Extensión de Cámara ESP32

-

Cables Puente

BUY

Servo

BUY

Pines Disponibles

Aquí hay una lista de pines disponibles en la placa ESP32 para este proyecto.

Pines Disponibles

IO13, IO12, IO14, IO27, IO26, IO25, IO33, IO32, IO15, IO2, IO0, IO4, IO5, IO18, IO19, IO21, IO22, IO23

Esquemático

../../_images/circuit_4.3_servo.png

Conexión

  • El cable naranja es de señal y se conecta a IO25.

  • El cable rojo es VCC y se conecta a 5V.

  • El cable marrón es GND y se conecta a GND.

../../_images/4.3_swinging_servo_bb.png

Código

Nota

  • Abre el archivo 4.3_swinging_servo.py ubicado en el camino esp32-starter-kit-main\micropython\codes o copia y pega el código en Thonny. Luego, haz clic en «Ejecutar Script Actual» o presiona F5 para ejecutarlo.

  • Asegúrate de seleccionar el intérprete «MicroPython (ESP32).COMxx» en la esquina inferior derecha.

import machine
import time

# Create a PWM (Pulse Width Modulation) object on Pin 25
servo = machine.PWM(machine.Pin(25))

# Set the frequency of the PWM signal to 50 Hz, common for servos
servo.freq(50)

# Define a function for interval mapping
def interval_mapping(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

# Define a function to write an angle to the servo
def servo_write(pin, angle):

    pulse_width = interval_mapping(angle, 0, 180, 0.5, 2.5) # Calculate the pulse width
    duty = int(interval_mapping(pulse_width, 0, 20, 0, 1023))     # Calculate the duty cycle
    pin.duty(duty) # Set the duty cycle of the PWM signal

# Create an infinite loop
while True:
    # Loop through angles from 0 to 180 degrees
    for angle in range(180):
        servo_write(servo, angle)
        time.sleep_ms(20)

    # Loop through angles from 180 to 0 degrees in reverse
    for angle in range(180, -1, -1):
        servo_write(servo, angle)
        time.sleep_ms(20)

Al ejecutar este código, el servo oscilará continuamente de ida y vuelta entre 0 y 180 grados.

¿Cómo funciona?

  1. Importar las bibliotecas necesarias: machine para controlar el hardware del microcontrolador, y time para agregar retrasos.

    import machine
    import time
    
  2. Crear un objeto PWM (Modulación por Ancho de Pulso) en el Pin 25 y establecer su frecuencia a 50 Hz, que es común para servo.

    # Create a PWM (Pulse Width Modulation) object on Pin 25
    servo = machine.PWM(machine.Pin(25))
    
    # Set the frequency of the PWM signal to 50 Hz, common for servos
    servo.freq(50)
    
  3. Definir una función interval_mapping para mapear valores de un rango a otro. Esto se usará para convertir el ángulo al ancho de pulso y ciclo de trabajo apropiados.

    def interval_mapping(x, in_min, in_max, out_min, out_max):
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
    
  4. Definir una función servo_write que toma un objeto PWM y un ángulo como entradas. Calcula el ancho de pulso y ciclo de trabajo basado en el ángulo dado, y luego establece la salida PWM en consecuencia.

    def servo_write(pin, angle):
    
        pulse_width = interval_mapping(angle, 0, 180, 0.5, 2.5) # Calculate the pulse width
        duty = int(interval_mapping(pulse_width, 0, 20, 0, 1023))     # Calculate the duty cycle
        pin.duty(duty) # Set the duty cycle of the PWM signal
    
    • En esta función, se llama a interval_mapping() para mapear el rango de ángulo 0 ~ 180 al rango de ancho de pulso 0.5 ~ 2.5ms.

    • ¿Por qué es 0.5~2.5? Esto está determinado por el modo de trabajo del Servo.

    • Luego, convertir el ancho de pulso de período a ciclo de trabajo.

    • Dado que duty() no puede tener decimales cuando se usa (el valor no puede ser de tipo flotante), usamos int() para forzar que el ciclo de trabajo se convierta a tipo entero.

  5. Crear un bucle infinito con dos bucles anidados.

    while True:
        # Loop through angles from 0 to 180 degrees
        for angle in range(180):
            servo_write(servo, angle)
            time.sleep_ms(20)
    
        # Loop through angles from 180 to 0 degrees in reverse
        for angle in range(180, -1, -1):
            servo_write(servo, angle)
            time.sleep_ms(20)
    
    • El primer bucle anidado itera a través de ángulos de 0 a 180 grados, y el segundo bucle anidado itera a través de ángulos de 180 a 0 grados en reversa.

    • En cada iteración, se llama a la función servo_write con el ángulo actual, y se añade un retraso de 20 milisegundos.