I have added some print statements to set_alarm
Here is the output.
set_alarm_time Start
alarm_time=20:15:00,Saturday,2024-03-30
SSMMHHDD
S=Second, M=Minute, H=Hour, D=Day of Month
now_time=00152030
The odd part is only the day part of the date is included.
This is the line that outputs the alarm to the DS3231
self.bus.writeto_mem(int(self.address),int(self.alarm1_reg),now_time)
Now if I give it a time in the future nothing happens
I’d expect it to print a message based on this line
# set alarm irq
self.alarm_pin.irq(lambda pin: print("alarm1 time is up"), Pin.IRQ_FALLING)
# enable the alarm1 reg
self.bus.writeto_mem(int(self.address),int(self.control_reg),b'\x05')
Any ideas what I’m missing?
Here is the full code
from machine import Pin, I2C, RTC
import time
import binascii
# the first version use i2c1
#I2C_PORT = 1
#I2C_SDA = 6
#I2C_SCL = 7
# the new version use i2c0,if it dont work,try to uncomment the line 14 and comment line 17
# it should solder the R3 with 0R resistor if want to use alarm function,please refer to the Sch file on waveshare Pico-RTC-DS3231 wiki
# https://www.waveshare.net/w/upload/0/08/Pico-RTC-DS3231_Sch.pdf
I2C_PORT = 0
I2C_SDA = 20
I2C_SCL = 21
ALARM_PIN = 3
class ds3231(object):
# 13:45:00 Mon 24 May 2021
# the register value is the binary-coded decimal (BCD) format
# sec min hour week day month year
NowTime = b'\x00\x45\x13\x02\x24\x05\x21'
w = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
address = 0x68
start_reg = 0x00
alarm1_reg = 0x07
control_reg = 0x0e
status_reg = 0x0f
def __init__(self,i2c_port,i2c_scl,i2c_sda):
self.bus = I2C(i2c_port,scl=Pin(i2c_scl),sda=Pin(i2c_sda))
def set_time(self,new_time):
hour = new_time[0] + new_time[1]
minute = new_time[3] + new_time[4]
second = new_time[6] + new_time[7]
week = "0" + str(self.w.index(new_time.split(",",2)[1])+1)
year = new_time.split(",",2)[2][2] + new_time.split(",",2)[2][3]
month = new_time.split(",",2)[2][5] + new_time.split(",",2)[2][6]
day = new_time.split(",",2)[2][8] + new_time.split(",",2)[2][9]
now_time = binascii.unhexlify((second + " " + minute + " " + hour + " " + week + " " + day + " " + month + " " + year).replace(' ',''))
self.bus.writeto_mem(int(self.address),int(self.start_reg),now_time)
def read_time(self):
t = self.bus.readfrom_mem(int(self.address),int(self.start_reg),7)
a = t[0]&0x7F #second
b = t[1]&0x7F #minute
c = t[2]&0x3F #hour
d = t[3]&0x07 #week
e = t[4]&0x3F #day
f = t[5]&0x1F #month
#print("%02x:%02x:%02x,%s,20%x-%02x-%02x" %(t[2],t[1],t[0],self.w[t[3]-1],t[6],t[5],t[4]))
return("%02x:%02x:%02x,%s,20%x-%02x-%02x" %(t[2],t[1],t[0],self.w[t[3]-1],t[6],t[5],t[4]))
def set_alarm_time(self,alarm_time):
print("set_alarm_time Start")
# init the alarm pin
self.alarm_pin = Pin(ALARM_PIN,Pin.IN,Pin.PULL_UP)
#print("alarm_pin=" + str(ALARM_PIN))
# set alarm irq
self.alarm_pin.irq(lambda pin: print("alarm1 time is up"), Pin.IRQ_FALLING)
# enable the alarm1 reg
self.bus.writeto_mem(int(self.address),int(self.control_reg),b'\x05')
# convert to the BCD format
print("alarm_time="+ str(alarm_time))
hour = alarm_time[0] + alarm_time[1]
minute = alarm_time[3] + alarm_time[4]
second = alarm_time[6] + alarm_time[7]
date = alarm_time.split(",",2)[2][8] + alarm_time.split(",",2)[2][9]
#### Testing ####
now_time= second + " " + minute + " " + hour + " " + date
now_time=now_time.replace(' ','')
print("SSMMHHDD")
print("S=Second, M=Minute, H=Hour, D=Day of Month")
print("now_time=" + now_time)
#### End ####
now_time = binascii.unhexlify((second + " " + minute + " " + hour + " " + date).replace(' ',''))
# write alarm time to alarm1 reg
self.bus.writeto_mem(int(self.address),int(self.alarm1_reg),now_time)
def formattedDate(inputTuple):
dateString=zfl(str(inputTuple[0]),2) + "-" + zfl(str(inputTuple[1]),2) + "-" + zfl(str(inputTuple[2]),2)
return dateString
# Zero pad the "imputString" with zeroes up to "width"
def zfl(inputString, width):
padded = '{:0>{w}}'.format(inputString, w=width)
return padded
def formattedTime(inputTuple):
timeString=zfl(str(inputTuple[3]),2) + ":" + zfl(str(inputTuple[4]),2) + ":" + zfl(str(inputTuple[5]),2)
return timeString
def dayOfWeek(inputTuple):
w = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
#Time Tuple Format (year, month, mday, hour, minute, second, weekday, yearday)
dayNumber=inputTuple[6]
dayName=w[dayNumber]
return dayName
def setPicoTime():
# Set the Pico Internal Clock from the DS3231 Clock
print("setPicoTime()")
print("Pico Time Before" + str(time.localtime()))
pico_rtc = RTC()
ds3231DateTime = DS_rtc.read_time()
DateTimeList=ds3231DateTime.split(",")
DateList=DateTimeList[2].split("-")
TimeList=DateTimeList[0].split(":")
year=int(DateList[0])
month=int(DateList[1])
day=int(DateList[2])
weekday=DateTimeList[1]
hour=int(TimeList[0])
minute=int(TimeList[1])
second=int(TimeList[2])
pico_rtc.datetime((year,month,day,weekday,hour,minute,second,0))
print("Pico Time After" + str(time.localtime()))
print("End setPicoTime()")
def setDS3231Time():
# Set DS3231 Date Time From the Pico Internal Clock
# Format Required Date Time Values
print("setDS3231Time()")
dateTimeTuple = time.localtime()
formattedDateString = formattedDate(dateTimeTuple)
formattedTimeString = formattedTime(dateTimeTuple)
dayName = dayOfWeek(dateTimeTuple)
picoDateTimeString=formattedTimeString+','+ dayName + ','+ formattedDateString
print("pico Time Before=" + picoDateTimeString)
# Set DS3231 From Pico Clock
#DS_rtc = ds3231(I2C_PORT,I2C_SCL,I2C_SDA)
print("Rs2321 Time Before=" + DS_rtc.read_time())
DS_rtc.set_time(picoDateTimeString)
print("Rs2321 Time After=" + DS_rtc.read_time())
print("End setDS3231Time()")
if __name__ == '__main__':
DS_rtc = ds3231(I2C_PORT,I2C_SCL,I2C_SDA)
setDS3231Time() # Set DS3231 Time from Pico Time
print()
#setPicoTime() # Set Pico Time from DS2321 Time
# Test Alarm <TODO>
# Set alarm and put the pico to sleep
# Allow the alarm to wake the pico up.
# Test alarm 2 also.
# setAlarm(hours,minutes,seconds,days)
DS_rtc.set_alarm_time('20:15:00,Saturday,2024-03-30')
# DS_rtc.set_alarm_time('13:45:55,Monday,2021-05-24')
Thanks
David