#Código para controlar el giro de un servomotor de 0-180° de forma continua
#con un microcontrolador ESP32
#CÓDIGO N AQUINO UNIR
#Librerias a utilizar
from machine import Pin, PWM ##Funciones especificas relacionadas al hardware en una tarjeta. Pin es usado para controlar I/O de propósito general, asociado a un pin físico.
#PWM esta clase nos da la salida de modulación por ancho de pulsos, la señal es una onda cuadrada.
from time import sleep #Este módulo proporciona funciones para obtener el tiempo y fecha real, mide intervalos de tiempo y retrasos.
#Configuramos el pin para el servo, en este caso puede ser del 0-15 para la tarjeta ESP32
pinservo = 2 #Pin al cual está conectado el servo
servo = PWM(Pin(pinservo), freq=50) #creamos un objeto PWM tomando pinservo y asignamos la frecuencia, en la mayoria de casos es 50Hz. señal de servomotor típica de 20ms.
#Definimos los valores mínimos y máximos del ciclo de trabajo del servo "Duty cycle"
#Para ello realizamos los siguientes cálculos, el pulso mínimo en ms correspondiente a 0 grados, por default es 544 y el pulso máximo en ms es 180 grados que por default es 2400
# 0.5ms/20ms = 0.025 es decir 2.5% ciclo de trabajo
# 2.4ms/20ms = 0.12 es decir 12% ciclo de trabajo
#Proviene de la fórmula D=100(TH/TW) TH:tiempo activo y TW:periodo de la señal.
#Convertimos los porcentajes del ciclo de trabajo a valores absolutos con los que trabaja el PWM, el rango de valores discretos es de 0 a 1023.
#Tenemos por tanto 0.025*1024 = 25.6 y 0.12*1024 = 122.88
MIN_CICLO = 25.6 #0 grados
MAX_CICLO = 122.8 #180 grados
def angle_to_duty(angle): #Función para mapear el rango de los ángulos al rango del ciclo de trabajo
return int(MIN_CICLO + (angle / 180) *(MAX_CICLO-MIN_CICLO) ) #Valor del ángulo a ciclo PWM
try: #Bloque para manejar excepciones que pueden ocurrir en el programa, se usará para ejecutar la acción del giro antes de que el programa termine
while True: #Mientras sea verdadero
#Le indica al servo que debe rotar a un ángulo especifico
for angle in range(0, 181): # Mover el servo de 0 a 180 grados
duty = angle_to_duty(angle) #Resultado de la función angle_to_duty almacenado en la variable ciclo
servo.duty(duty) #Envia el valor de la variable ciclo al objeto servo para asignar su posición
sleep(0.02) #Retraso de 20ms para suavizar el movimiento
# Mover el servo de 180 a 0 grados
for angle in range(180, -1, -1): #Estructura de range(inicio, final y paso), en este caso stop no se incluye en el rango, por el que el ciclo for termina en el 0, paso = -1 es el decremento en cada iteración
duty = angle_to_duty(angle) #Resultado de la función angle_to_duty almacenado en la variable ciclo
servo.duty(duty) #Envia el valor de la variable ciclo al objeto servo para asignar su posición
sleep(0.02) #Retraso de 20ms para suavizar el movimiento
except KeyboardInterrupt: #Excepción que ocurre cuando se hay una interrupción en el programa usando una acción del teclado.
servo.deinit() #Detiene la señal PWM