print("Adjustable Fan Speed")
print("By: Nik")
print("Date: 29/4/2024")
# Import libraries
from machine import Pin, PWM, SoftI2C
import library_oled
import ultrasonic_library
from utime import sleep
import dht
# Pin declaration
sensor = dht.DHT22(Pin(15))
pwm = PWM(Pin(18), freq=50, duty=0) # Initialize servo motor on pin 18
button_0 = Pin(12, Pin.IN, Pin.PULL_UP) # Initialize push button on pin 12 (Stop Button)
button_1 = Pin(14, Pin.IN, Pin.PULL_UP) # Initialize push button on pin 14 (Rotate Slow)
button_2 = Pin(27, Pin.IN, Pin.PULL_UP) # Initialize push button on pin 27 (Rotate Medium)
button_3 = Pin(26, Pin.IN, Pin.PULL_UP) # Initialize push button on pin 26 (Rotate Fast)
oled_pin = SoftI2C(scl=Pin(22), sda=Pin(21))
led1 = Pin(2, Pin.OUT) # Initialize red LED
led2 = Pin(4, Pin.OUT) # Initialize green LED
TRIG = Pin(25, Pin.OUT)
ECHO = Pin(33, Pin.IN)
# Create an object name for component with library
display = library_oled.SSD1306_I2C(width=128, height=64, i2c=oled_pin, external_vcc=False)
sensor_person = ultrasonic_library.HCSR04(trigger_pin=TRIG, echo_pin=ECHO, echo_timeout_us=500*2*30)
# Variable to track servo state and speed
servo_running = False
speed_factor = 1 # Default speed factor
# Function to control servo motor
def Servo(angle, speed_factor):
# Calculate duty cycle corresponding to the given angle and speed factor
duty_cycle = int(((angle) / 180 * 2 + 0.5) / 20 * 1023 * speed_factor)
# Set duty cycle
pwm.duty(duty_cycle)
# Interrupt callback function for button press
def button_callback(pin):
global servo_running, speed_factor
if pin == button_0: # Stop Button
servo_running = False
elif pin == button_1: # Rotate Slow
speed_factor = 0.5
servo_running = True
elif pin == button_2: # Rotate Medium
speed_factor = 1
servo_running = True
elif pin == button_3: # Rotate Fast
speed_factor = 2
servo_running = True
# Register button interrupts
button_0.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
button_1.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
button_2.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
button_3.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
# Main Program
while True:
# Measure distance using ultrasonic sensor
distance = sensor_person.distance_cm()
# Check if the distance is within the specified range or if the stop button is pressed
if (0 < distance <= 350 and servo_running) or not button_0.value():
servo_running = True
else:
servo_running = False
# Check if any button for speed control is pressed
if not button_1.value() or not button_2.value() or not button_3.value():
servo_running = True
# Check if the servo should run
if servo_running:
# Rotate servo motor based on speed factor
for angle in range(0, 181, 1):
Servo(angle, speed_factor) # Rotate from 0 to 180
sleep(0.01)
for angle in range(180, -1, -1):
Servo(angle, speed_factor) # Rotate from 180 to 0
sleep(0.01)
# Display speed status on OLED when fan is running
print("------------------")
print("Fan is running")
print("\n")
display.fill(0) # Clear display (0 is usually black)
display.text("Fan is running", 13, 20, 1) # Default text
display.text("Speed: ", 13, 30, 1) # Show speed text
if speed_factor == 0.5:
display.text("Slow", 70, 30, 1)
elif speed_factor == 1:
display.text("Moderate", 70, 30, 1)
elif speed_factor == 2:
display.text("High", 70, 30, 1)
display.show()
# Turn on green LED and turn off red LED
led1.off()
led2.on()
else:
pwm.duty(0) # Stop the servo motor
print("------------------")
print("Fan is stopped")
print("\n")
display.fill(0) # Clear display (0 is usually black)
display.text("Fan is stopped", 13, 20, 1) # Show text (1 is white)
display.show()
sleep(1)
# Turn on red LED and turn off green LED
led1.on()
led2.off()