Saltar al contenido
Control Automático Educación

Servomotor Raspberry Pi Pico – ESP

Hola controleros y controleras, en esta entrada aprenderemos a programar los SERVOMOTORES de 180° (control de posición) o de 360° (control de velocidad) con MicroPython y para eso usaremos la poderosa Raspberry Pi Pico o también el NodeMCU ESP8266, sin embargo notarás que puedes extender esta explicación y los códigos de programación a cualquier otra placa que soporte MicroPython.

Antes de comenzar, te hago la invitación que aprendas a programar microcontroladores con nuestro Curso Gratuito de MicroPython.

MicroPython

Y que te suscríbas al canal si te interesa la programación de microcontroladores o la teoría del control.

Servomotor con Micropython [Raspberry Pi Pico/ESP]

¿Que es un Servomotor?

Un servomotor es un motor con un mecanismo y algoritmo de control, es decir este dispositivo mecánico posee internamente un controlador que posiciona precisamente el rotor del motor en un ángulo especificado por la señal entrante de control. Sin embargo el servomotor que posee este controlador es el de 90 ° o el de 180°

Servomotor PIC C
Servo

Para entender esto, veamos que físicamente el servomotor se compone de tres cables: GND, Power (5v) y Control. Es decir que los dos primeros se usan como alimentación en cuanto el cable de control es usado para enviar la señal de posicionamiento del motor con una secuencia de pulsos PWM.

servomotor con PIC

Un servo con MicroPython implementado en una Raspberry Pi Pico o en un ESP8266 podrá tener una potencialidad tremenda, dado que la propia placa será la encargada de enviar esa señal PWM para posicionar el motor en una posición en grados en específico.

Servos de rotación continua

Los servo motores de 360° son servos Radio control estándar que se han modificado para ofrecer un control de velocidad en lazo abierto en lugar de su control habitual de posición de lazo cerrado, por lo tanto aquí ya no puedes especificar con tu raspberry pi pico la posición especifica que deseas mover el rotor del motor, sino que por el contrario estableces la velocidad de giro.

La modificación los convierte en motores con un sistema de motoreducción que le permite aumentar su fuerza y disminuir la velocidad, donde adicionalmente se puede controlar el sentido de giro, todo eso integrado en un paquete compacto y económico.

Se puede usar en ruedas de robots y controlarse mediante una señal RC o una simple conexión directa a una sola línea de E / S del microcontrolador (Raspberry Pi Pico/ NodeMCU ESP8266).

Señal de Control de un ServoMotor con MicroPython

El control de un servomotor lo podemos lograr de forma sencilla con nuestro microcontrolador RP2040 de la Raspberry Pi Pico o el ESP, usando los módulos PWM programados a través de MicroPython tal y como lo estudiamos en entradas pasadas.

Importamos el la clase Pin y PWM del módulo machine y el módulo utime.

from machine import Pin, PWM
import utime

Generalmente los servomotores comerciales procesan un pulso con un periodo de 20ms para conseguir efectuar todo el movimiento del servo adecuadamente bien sea de 90° o 180° para posición o de 360° para velocidad.

En otras palabras debemos establecer una frecuencia de 50Hz en nuestro servomotor en cualquiera de los Pines PWM de nuestro microcontrolador.

servo_180 = PWM(Pin(15))
servo_180.freq(50) #50 Hz para el servomotor

Con ese periodo de 20ms podemos desplazar todo el servomotor de 90°, 180°o 360° en los primeros 2ms por todo su recorrido.

Dependiendo del motor que tengas tendrás las siguientes medidas, si es para servomotores porgramados en MicroPython de 90°, 180° tendrás un control de posición, por otro lado si es un servomotor de 360° tendrás un control de velocidad con sentido de giro en dirección de las manesillas del reloj (CW) o contra las manesillas del reloj (CCW) o estático.

Servomotor con PIC

Para eso usamos la siguiente instrucción de configuración de PWM en MicroPython que nos permite establecer el periodo en encendido para el control de nuestros servomotores:

servo_180.duty_ns(100000) # 1ms -> 0 grados (180) o CW (360)
utime.sleep_ms(500)  #Tiempo para el movimiento
servo_180.duty_ns(150000) # 1.5ms -> 90 grados (180) o Center (360)
utime.sleep_ms(500)  #Tiempo para el movimiento
servo_180.duty_ns(200000) # 2ms -> 180 grados (180) o CCW (360)
utime.sleep_ms(500)  #Tiempo para el movimiento

Ejemplo Servomotor 180° y 360° Raspberry Pi Pico

A través de la shell de Thonny en MicroPython, vamos a pedirle al usuario el valor en grados al cual desea desplazar el servomotor y dicha señal vamos a aplicarla a un servomotor de 180° y también a un servomotor de giro completo de 360°. Este último deberá girar en sentido CW, CCW o detenerse.

Código:

from machine import Pin, PWM
import utime


def main():
    #Configura el Servo de 180
    servo_180 = PWM(Pin(15))
    servo_180.freq(50)
    
    #Configura el Servo de 360
    servo_360 = PWM(Pin(14))
    servo_360.freq(50)
    
    while True:
        angulo = float(input('Ingrese un ángulo: '))
        if angulo >= 0 and angulo <= 180:
            duty = int((12.346*angulo**2 + 7777.8*angulo + 700000))
            servo_180.duty_16(duty) 
            servo_360.duty_ns(duty)
        else:
            print('Digite un ángulo entre 0 y 180')
    
    
if __name__ == '__main__':
    main()

Ejemplo Servomotor 180° y 360° ESP8266

Repetiremos el mismo ejemplo pero ahora modificaremos el código para trabajar con la NodeMCU ESP8266. En este caso necesitamos configurar el PWM para trabajar con la función duty() y por lo tanto debemos transformar el ciclo de trabajo en bits de 0 – 1023 en el periodo de los 20ms.

Código:

from machine import Pin, PWM
import utime


def main():
    #Configura el Servo de 180
    servo_180 = PWM(Pin(15))
    servo_180.freq(50)
    
    #Configura el Servo de 360
    servo_360 = PWM(Pin(14))
    servo_360.freq(50)
    
    while True:
        angulo = float(input('Ingrese un ángulo: '))
        if angulo >= 0 and angulo <= 180:
            #nanosegundos
            duty = ((12.346*angulo**2 + 7777.8*angulo + 700000))
            #milisegundos
            duty /= 1000000
            #bits
            duty = int(duty*1023/20)
            
            servo_180.duty(duty) 
            servo_360.duty(duty)
        else:
            print('Digite un ángulo entre 0 y 180')
    
    
if __name__ == '__main__':
    main()

Listas y Tuplas

Entradas Analógicas

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.