"""
A continuación se presenta el código para hacer girar un servomotor 180°de manera intermitente.
Se tomó como fuentes de apoyo las páginas: https://peppe8o.com/sg90-servo-motor-with-raspberry-pi-pico-and-micropython/
https://controlautomaticoeducacion.com/micropython/servomotor-raspberry-pi-pico-esp/
"""
from machine import Pin, PWM # Desde el módulo de máquina, se importan las clases para usar los pines y lo de PWM
# (modulación por ancho de pulso) para simular señal analógica.
from time import sleep # Del módulo time, se importa la clase sleep.
import network
import time
import dht
import ujson
from umqtt.simple import MQTTClient
""" Configuración de entrada y frecuencia del PWM """
servo_pin = PWM(Pin(2)) #configuración del pin 2 para conectar la señal del servomotor.
servo_pin.freq(50) # El PWM trabajará con frecuencia de 50Hz para emular señal análoga y garantizar recorrido de 0°-180°.
# Parámetros para inicio de sesión y conexión con el servidor)
MQTT_CLIENT_ID = "micropython-weather-demo"
MQTT_BROKER = "broker.mqttdashboard.com"
MQTT_USER = ""
MQTT_PASSWORD = ""
MQTT_TOPIC = "wokwi-weather"
# Variable sensor para guardar info del DHT22 y conectarlo al Pin 15
sensor = dht.DHT22(Pin(15))
# A partir del ángulo de trabajo requerido, se calcula el output o salida necesaria, para que el servomotor se mueva
# correctamente.
def servo(degrees): # Se crea la función servo que requiere como entrada, el ángulo de posición a alcanzar
# y permite verificar que la entrada esté entre 0° y 180° que es el rango de trabajo.Esta función permite pasar el ángulo de giro deseado
#al servomotor, como PWM equivalente.
# Se Chequea si el ángulo buscado está dentro del rango de trabajo:
if degrees > 180: degrees=180
if degrees < 0: degrees=0
# Se establece límites (Valores min y max) de su ciclo de trabajo.
#El servomotor realiza todos los ángulos disponibles entre 1 y 9 ms considerando el período típico del servo que es de 20 ms
maxDuty=9000
minDuty=1000
#Fórmula para pasar de grados a PWM/duty cycle
#El valor de grados (0-180) se proporciona al rango de 1000-9000 con la siguiente fórmula
#Duty Cycle = minimo + rango * proporción de ángulo
newDuty=minDuty+(maxDuty-minDuty)*(degrees/180)
# Comando que pasa el valor de duty al servo
servo_pin.duty_u16(int(newDuty)) # Esta instrucción se encarga de configurar el ciclo de trabajo de la señal PWM.
# La función duty_u16 establece el nuevo valor en el pin PWM. La función int() convierte el valor flotante a entero.
print("Connecting to WiFi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')
while not sta_if.isconnected():#Inicio de Ciclo While para comprobar si la conexión a WiFi está establecida
print(".", end="") # (Muestre puntos cada 0.1 s, mientras no esté conectado a la red WiFi y lo próximo que muestre esté en la misma línea.
time.sleep(0.1)
print(" Connected!") # Al confirmar conexión, luego del espacio en blanco muestre "Connected"
print("Connecting to MQTT server... ", end="") # Muestra el mensaje "Connecting to MQTT server... " y finaliza dejando espacio
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD) # Envía por parámetro todos los datos recopilados en celdas 35-38 y se
# Conecta al servidor.
client.connect() # Comando utilizado para establecer la conexión con el servidor MQTT
print("Connected!") # Se muestra el mensaje "Connected!"
prev_weather = ""
# Ciclo infinito while que hace girar el servo en todo su rango hasta que se detenga manualmente.
while True:
print("Measuring weather conditions... ", end="")
sensor.measure()
message = ujson.dumps({ #Se crea la variable message, en donde en un archivo tipo json, se va a guardar lo que capte el sensor en temperatura y humedad.
"temp": sensor.temperature(), #Lo que capte el sensor en temperatura se mostrará luego de mostrar "temp"
"humidity": sensor.humidity(), #Lo que capte el sensor en humedad se mostrará luego de mostrar "humidity"
})
if message != prev_weather: #Con este if se pregunta: Si lo almacenado en la variable message es diferente a lo que tiene la variable de lectura: "prev_weather"
print("Updated!") #Si la pregunta anterior es cierta, es decir, hay cambio en los datos climáticos, muestra "Updated"
print("Reporting to MQTT topic {}: {}".format(MQTT_TOPIC, message)) # Se muestra el mensaje para indicar que los datos sensados se envían al servidor MQTT.
# se muestra lo almacenado en el parámetro MQTT_TOPIC: "wokwi-weather" y va a anexar lo que se capturó en message.
client.publish(MQTT_TOPIC, message) #publicación en el servidor, de lo capturado.
prev_weather = message #actualización de la variable con el nuevo message para nuevas comparaciones.
else:
print("No change") #Si no hay cambios en los datos climáticos se muestra "No change"
time.sleep(1)
if sensor.temperature()>30:
for degree in range(0,180,1): #Este bucle "para" prueba el servomotor con una valor creciente en grados de 0 a 180 aumentando
# grado a grado.
servo(degree) # El valor que guarde, lo coloca en la función servo
sleep(0.05) #Tiempo de espera de 0.05 s
#print("increasing -- "+str(degree))
for degree in range(180, 0, -1): #Este 2do bucle "para" hace la misma prueba anterior pero en dirección inversa.
servo(degree) # El valor que guarde, lo coloca en la función servo
sleep(0.05) #Tiempo de espera de 0.05 s
#print("decreasing -- "+str(degree)) #muestra por consola lo que se está ejecutando
else:
servo(0)
# Fin del programa