# Final Project ITCS2875 Computer Architecture & Organization
#
# Description: "Solve a humanitarian issue using electrical
# components and a Raspberry Pi"
#
# Using a Servo-Motor, LED, and a button,
# this program is used to rotate the top plate
# of a custom design circular pill container. The user is to
# interact with the box by simply pressing a button and
# referring to the LED as an indicator of whether the medication
# was taken or not. With each button press, the box rotates
# through each day of the week and runs until the user either
# disconnects the power from the pi or can manage to end the
# program through the GUI of the IDE. No monitor output is
# required to use this box as the simplicity is what makes it
# most user friendly for people of all ages and abilities.
#
#
# INPUT: The program seeks input from the GPIO ports on the pi
# along with waiting for the user to interact with the button.
#
# PROCESSING: Upon button press, the LED indicator is turned off
# and the timer is set until the user has to be reminded to take
# their medication again given a set sleep window embedded into
# code from there, the LED will turn back on and wait for the user
# to interact with the button.
#
# OUTPUT: The outputs of this program are the power state of
# the LED being on or off and the rotational positioning of
# the servo-motor revealing or concelaing the sections of the
# container/box.
#
#
# Created by: Jared Young
# Date Edited: 04/27/2024
#
import RPi.GPIO as GPIO # Importing GPIO functionality
from gpiozero import LED # Importing LED funcitonality
from gpiozero import Button # Importing Button functionality
import time # Importing the time module for the sleep function
GPIO.setwarnings(False) # Set up for the GPIO
servoPIN = 17 # Initializes the Servo Motor with the GPIO Location on Pi
rled = LED(22) # Initializes the LED with the GPIO Location on Pi
button = Button(21) # Initializes the Button with GPIO Location on Pi
#dayOfWeek = [2, 3.78, 5.56, 7.34, 9.12, 10.9, 12.5]
GPIO.setmode(GPIO.BCM) # Sets up the Servo Motor
GPIO.setup(servoPIN, GPIO.OUT) # Sets up the Servo Motor
sleep = 0.5 # Sets the time in seconds in between reminders for the LED to toggle
p = GPIO.PWM(servoPIN, 50) # GPIO 17 for PWM with 50Hz
p.start(0) # Starts the servo at the initial position
try: # Exception handling from Assignment 7 w/ Servo motor
while True: # Always true
p.ChangeDutyCycle(2) # Sets box to Sunday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
p.ChangeDutyCycle(4.1) # Sets box to Monday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
p.ChangeDutyCycle(6) # Sets box to Tuesday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
p.ChangeDutyCycle(7.34) # Sets box to Wednesday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off()# Turns off the LED indicator
p.ChangeDutyCycle(8.75) # Sets box to Thursday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
p.ChangeDutyCycle(10.9) # Sets box to Friday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
p.ChangeDutyCycle(12.5) # Sets box to Saturday
time.sleep(sleep) # Rest for period after the medication was taken
rled.on() # Turns on the LED indicator
# Waiting for the User to remember taking their meds
# End of the week so reset back to the beginning of the week
button.wait_for_press() # Wait for the user to press the button before moving on
rled.off() # Turns off the LED indicator
# END OF WHILE LOOP --> Resets Back to Sunday
except KeyboardInterrupt: # Exception handling from Assignment 7 w/ Servo motor
p.stop() # Stops the motor
GPIO.cleanup() # Cleans up GPIO