from machine import Pin, PWM, I2C
import time
#-----------PINS----------
SDA_PIN = 4 # Pins to connect the DS3231 we must make sure that if they are SDA and SCL
SCL_PIN = 5
DS3231_ADDR = 0x68
SERVO_PIN = 14 # Pin to connect the servo
BUZZER_PIN = 13 # Pin to connect the buzzer
BOTON_PIN = 19 # Pin to connect the button
# ================== I2C RTC ==================
i2c = I2C(0, scl=Pin(SCL_PIN), sda=Pin(SDA_PIN), freq=100000)
# With this part of the code we convert from binary to decimal.
# The watch stores the data in two parts that are a binary number and a binary number.
# For example, 25 looks like this: 0010 (2) 0101 (5) Then it becomes val >> 4: Move everything to the right to keep only the 2.
# Then multiply it by 10 (20).
# And val & 0x0F: Delete the left side to keep only the 5. then add it and there are 25.
def bcd_to_dec(val):
return ((val >> 4) * 10) + (val & 0x0F)
def leer_hora():
data = i2c.readfrom_mem(DS3231_ADDR, 0x00, 3) # Timer registration
segundos = bcd_to_dec(data[0])
minutos = bcd_to_dec(data[1])
horas = bcd_to_dec(data[2] & 0x3F)
return horas, minutos, segundos
# ================== SERVO ==================
servo = PWM(Pin(SERVO_PIN)) # configure the pin for the servo with PWM
servo.freq(50)
def set_servo_position(deg):
# Limit safe range
if deg < 0:
deg = 0
if deg > 180:
deg = 180
# Function that helps us map the servo position from degrees to PWM units
duty = int(1638 + (deg / 180) * 6553)
servo.duty_u16(duty)
# ================== BUZZER ==================
buzzer = PWM(Pin(BUZZER_PIN))
def set_buzzer_freq(freq): # give it specific sound commands.
if freq == 0:
buzzer.duty_u16(0) # Line to prevent our buzzer from sounding
else:
buzzer.freq(freq)
# This line calculates how long a clock cycle needs to be to fit exactly the amount of "vibrations" (freq) you want to hear in one second.
buzzer.duty_u16(32768) # 50%
# ================== BUTTON ==================
boton = Pin(BOTON_PIN, Pin.IN, Pin.PULL_UP) # We initialize our pin as input
# ================== ALARM CONFIG ==================
# For the user to enter the time
print("Hamster Alarm Configuration")
h_alarma = int(input("Hour (0-23): "))
m_alarma = int(input("Minute (0-59): "))
print(f"Alarm set at {h_alarma:02d}:{m_alarma:02d}")
alarma_disparada = False
# ================== MAIN LOOP ==================
pos_izq = 20
pos_der = 160
while True:
# Read the RTC
horas, minutos, _ = leer_hora()
# activate the alarm at the time the user logged in
if horas == h_alarma and minutos == m_alarma and not alarma_disparada:
alarma_disparada = True
print("Alarm activated!")
if alarma_disparada:
# if the alarm is activate the buzzer and the servo are activated
set_servo_position(pos_izq)
set_buzzer_freq(1000)
time.sleep(0.2)
set_servo_position(pos_der)
set_buzzer_freq(1500)
time.sleep(0.2)
# if the button is activated the buzzer and the servo are desactivated
if boton.value() == 0:
alarma_disparada = False
set_buzzer_freq(0)
set_servo_position(90)
print("Hamster caught! Alarm off.")
time.sleep(60)
else:
print(f"Current time: {horas:02d}:{minutos:02d}")
time.sleep(1)