print("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=")
print("\n\t Donation Box with Monitoring")
print("\t and Alarm System for the Poor")
print("\n\t\t\tBy:\n")
print("\t[Muhammad Irfan Bin Mohd Fardaus]")
print("\t\t (22/11/2024)\n")
print("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=")
# Import required libraries
from machine import Pin, SoftI2C, PWM
from utime import sleep
from mpu6050 import MPU6050
import ssd1306
from hcsr04 import HCSR04
# Pin declaration
led_pins = [Pin(pin, Pin.OUT) for pin in [26, 27, 14, 12, 13]]
rows_keys = [Pin(x, Pin.OUT) for x in (19, 18, 5, 17)]
cols_keys = [Pin(x, Pin.IN, Pin.PULL_UP) for x in (16, 4, 0)]
servo_pin = Pin(15, Pin.OUT)
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
buzzer = PWM(Pin(23, Pin.OUT))
sensor = HCSR04(trigger_pin=33, echo_pin=32)
# Parameter Declaration
keys = [ # Keypad Parameter
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['*', '0', '#']
]
secret_password = "24002" # Secret password for the system
display_delay = 2 # Delay for OLED messages
# Object declaration
oled = ssd1306.SSD1306_I2C(width=128, height=64, i2c=i2c)
servo = PWM(servo_pin, freq=50)
mpu = MPU6050()
# Main program
def scan_keypad(): # Function to scan keypad for input
for i, row in enumerate(rows_keys):
row.value(0)
for j, col in enumerate(cols_keys):
if col.value() == 0:
row.value(1)
return keys[i][j]
row.value(1)
return None
def monitoring_system(): # Function for sensor operations and monitoring
try:
while True:
depth = sensor.distance_cm() # Get distance from ultrasonic sensor
key = scan_keypad() # Scan keypad
# Read accelerometer and gyroscope data
accel_data = mpu.read_accel_data()
gyro_data = mpu.read_gyro_data()
# Check accelerometer conditions for triggering alarm
if abs(accel_data["x"]) > 5 or abs(accel_data["y"]) > 5 or abs(accel_data["z"]) > 5:
alarm_security()
# Check gyroscope conditions for triggering alarm
elif abs(gyro_data["x"]) > 20 or abs(gyro_data["y"]) > 20 or abs(gyro_data["z"]) > 20:
alarm_security()
if key == '#': # Exit condition
stop_password_input()
# Update OLED display and LED bar graph
print(f"Depth is: {depth:.2f}cm")
depth = int(depth) # Convert depth to integer
if depth < 10:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("Full", 50, 30)
oled.show()
elif 10 <= depth < 20:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("Almost Full", 20, 30)
oled.show()
elif 20 <= depth < 30:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("Half Full", 31, 30)
oled.show()
elif 30 <= depth < 40:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("A quarter full", 8, 30)
oled.show()
elif 40 <= depth < 50:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("Nearly empty", 16, 30)
oled.show()
else:
oled.fill(0)
oled.text("This box is:", 16, 15)
oled.text("Empty", 45, 30)
oled.show()
num_leds = min(int(depth / 10), len(led_pins)) # LEDs to light up based on depth
for i in range(len(led_pins)): # Update LEDs
if i >= num_leds:
led_pins[i].value(1)
else:
led_pins[i].value(0)
sleep(0.1)
except Exception as e:
# Handle sensor errors
oled.fill(0)
oled.text("Sensor Error:", 0, 0)
oled.text(str(e), 0, 20)
oled.show()
def display_password(password): # Function to display password on OLED
oled.fill(0) # Clear the display
oled.text("Password Input:", 5, 20)
oled.text(password, 5, 40)
oled.show()
sleep(0.2)
def alarm_security(): # Function to handle alarm security
oled.fill(1) # Clear the display
oled.text("Alarm Triggered!", 1, 25, 0)
oled.text("Press # to stop", 1, 35, 0)
oled.show()
while True:
key = scan_keypad()
buzzer.init(freq=1000, duty=10) # Trigger buzzer
if key == '#': # Stop alarm
stop_password_input()
def move_servo(angle): # Function to move the servo motor to a specified angle
try:
# Convert the angle to a duty cycle (based on 50Hz PWM)
duty = int((angle / 180) * 102 + 26)
servo.duty(duty) # Set the servo duty cycle
except Exception as e:
print(f"Error moving servo: {e}")
def stop_password_input(): # Function to handle stopping the system via password input
password = "" # Initialize the password input
display_password(password) # Display an empty password initially
while True:
key = scan_keypad() # Scan keypad for input
if key:
if key == '#':
print("Password entered:", password)
if password == secret_password:
buzzer.init(freq=1000, duty=0)
oled.fill(0)
oled.text("System Stopped!", 1, 30)
oled.show()
sleep(display_delay)
main() # Return to the main menu
else: # Incorrect password
oled.fill(0)
oled.text("Incorrect", 5, 20)
oled.text("Password!", 5, 40)
oled.show()
sleep(display_delay)
monitoring_system() # Restart monitoring
password = ""
elif key == '*': # '*' removes the last character
password = password[:-1]
else:
password += key # Append the new key to the password
display_password(password) # Update the display with the new password
def door_password_input(): # Function to unlock the door with password input
password = ""
display_password(password) # Display an empty password initially
angle = 0 # Initial servo angle
while True:
key = scan_keypad() # Scan keypad for input
if key:
if key == '#': # If '#' is pressed, validate the password
print("Password entered:", password)
if password == secret_password: # Correct password
oled.fill(0)
oled.text("Door Unlocked!", 1, 30)
oled.show()
angle = 0 # Set servo angle to 0 to unlock
move_servo(angle)
sleep(display_delay)
oled.fill(0)
oled.text("Press # to lock", 1, 30)
oled.show()
while True:
key = scan_keypad()
if key == "#":
angle = 90 # Set servo angle to 90 to lock
move_servo(angle)
sleep(0.5) # Debounce delay
oled.fill(0)
oled.text("Door Locked", 1, 30)
oled.show()
sleep(display_delay)
main() # Return to the main menu
else: # Incorrect password
oled.fill(0)
oled.text("Incorrect", 5, 20)
oled.text("Password!", 5, 40)
oled.show()
sleep(display_delay)
main() # Return to the main menu
password = "" # Reset the password after validation
elif key == '*':
password = password[:-1]
else:
password += key # Append the new key to the password
display_password(password) # Update the display with the new password
def main():
buzzer.init(freq=1000, duty=0) # Initialize the buzzer (off state)
oled.fill(0)
oled.text("Donation Box", 15, 3)
oled.text("Menu", 45, 13)
oled.text("1.Run Monitoring", 1, 30)
oled.text("2.Open Door", 1, 50)
oled.show()
while True:
key = scan_keypad() # Scan keypad for input
if key == "1": # Run monitoring option
oled.fill(0)
oled.text("Press #", 1, 20)
oled.text("to back to Menu", 1, 30)
oled.show()
sleep(display_delay)
monitoring_system() # Start monitoring
elif key == "2": # Open door option
door_password_input() # Handle door password input
break
sleep(0.2) # Debounce delay
# Run the main program
if __name__ == "__main__":
main()