import machine
import utime as time
from machine import Pin, PWM
import micropython
class Rotary:
ROT_CW = 1
ROT_CCW = 2
SW_PRESS = 4
SW_RELEASE = 8
def __init__(self, dt, clk, sw):
self.dt_pin = Pin(dt, Pin.IN, Pin.PULL_DOWN)
self.clk_pin = Pin(clk, Pin.IN, Pin.PULL_DOWN)
self.sw_pin = Pin(sw, Pin.IN, Pin.PULL_UP)
self.last_status = (self.dt_pin.value() << 1) | self.clk_pin.value()
self.dt_pin.irq(handler=self.rotary_change, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)
self.clk_pin.irq(handler=self.rotary_change, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)
self.sw_pin.irq(handler=self.switch_detect, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)
self.handlers = []
self.last_button_status = self.sw_pin.value()
def rotary_change(self, pin):
new_status = (self.dt_pin.value() << 1) | self.clk_pin.value()
if new_status == self.last_status:
return
transition = (self.last_status << 2) | new_status
if transition == 0b1110:
micropython.schedule(self.call_handlers, Rotary.ROT_CW)
elif transition == 0b1101:
micropython.schedule(self.call_handlers, Rotary.ROT_CCW)
self.last_status = new_status
def switch_detect(self, pin):
if self.last_button_status == self.sw_pin.value():
return
self.last_button_status = self.sw_pin.value()
if self.sw_pin.value():
micropython.schedule(self.call_handlers, Rotary.SW_RELEASE)
else:
micropython.schedule(self.call_handlers, Rotary.SW_PRESS)
def add_handler(self, handler):
self.handlers.append(handler)
def call_handlers(self, type):
for handler in self.handlers:
handler(type)
# Initialize components
pir_sensor = Pin(15, Pin.IN) # PIR sensor connected to GPIO 15
servo1 = PWM(Pin(16)) # Servo 1 connected to GPIO 16
servo2 = PWM(Pin(17)) # Servo 2 connected to GPIO 17
# Set PWM frequency for servos
servo1.freq(50)
servo2.freq(50)
# Function to move servos
def set_servo_angle(servo, angle):
duty = int((angle / 180.0 * 2 + 0.5) * 1023 / 20) # Convert angle to duty cycle
servo.duty_u16(duty)
# Rotary encoder initialization
rotary = Rotary(18, 19, 20) # GPIO 18 = DT, GPIO 19 = CLK, GPIO 20 = SW
# Handler for rotary encoder
def rotary_handler(event):
global door_speed
if event == Rotary.ROT_CW:
print("Rotary CW: Increasing speed")
door_speed = min(door_speed + 1, 10) # Increase speed
elif event == Rotary.ROT_CCW:
print("Rotary CCW: Decreasing speed")
door_speed = max(door_speed - 1, 1) # Decrease speed
elif event == Rotary.SW_PRESS:
print("Rotary Button Pressed")
elif event == Rotary.SW_RELEASE:
print("Rotary Button Released")
rotary.add_handler(rotary_handler)
# Default speed for door movement
door_speed = 5
# Main loop
while True:
if pir_sensor.value(): # Motion detected
print("Motion detected! Opening door...")
set_servo_angle(servo1, 90) # Open door
set_servo_angle(servo2, 90)
time.sleep(door_speed / 10) # Adjust speed based on rotary encoder
else: # No motion detected
print("No motion detected. Closing door...")
set_servo_angle(servo1, 0) # Close door
set_servo_angle(servo2, 180)
time.sleep(door_speed / 10) # Adjust speed based on rotary encoder