Next, we will create a complete program that implements a clock with
manual time setting using the three buttons. This is a great practical
example that teaches state management and user input handling.
importtm1637frommachineimportPin,RTCfromutimeimportsleep,localtime,ticks_ms# Initialize display and RTCtm=tm1637.TM1637(clk=Pin(0),dio=Pin(1))rtc=RTC()# Initialize buttons with pull-up resistorsmode_btn=Pin(2,Pin.IN,Pin.PULL_UP)next_btn=Pin(3,Pin.IN,Pin.PULL_UP)prev_btn=Pin(4,Pin.IN,Pin.PULL_UP)# Clock modesRUNNING=0SET_HOUR=1SET_MINUTE=2SET_AMPM=3classClock:def__init__(self):self.mode=RUNNINGself.hours=12self.minutes=0self.is_pm=Falseself.colon_on=Trueself.last_button_time=ticks_ms()self.button_debounce=200# millisecondsself.load_time_from_rtc()defload_time_from_rtc(self):"""Get current time from RTC"""_,_,_,_,hours,minutes,_,_=rtc.datetime()self.hours=hours%12ifself.hours==0:self.hours=12self.is_pm=hours>=12self.minutes=minutesdefsave_time_to_rtc(self):"""Save current time to RTC"""current_time=list(rtc.datetime())hours=self.hoursifself.is_pmandhours!=12:hours+=12elifnotself.is_pmandhours==12:hours=0current_time[4]=hours# Set hourscurrent_time[5]=self.minutes# Set minutesrtc.datetime(tuple(current_time))defdebounce(self):"""Handle button debouncing"""current_time=ticks_ms()ifcurrent_time-self.last_button_time<self.button_debounce:returnFalseself.last_button_time=current_timereturnTruedefhandle_buttons(self):"""Process button inputs"""ifnotself.debounce():return# Mode button cycles through modesifmode_btn.value()==0:# Button pressed (active low)self.mode=(self.mode+1)%4ifself.mode==RUNNING:self.save_time_to_rtc()# Next/Previous buttons modify current settingelifnext_btn.value()==0orprev_btn.value()==0:increment=-1ifprev_btn.value()==0else1ifself.mode==SET_HOUR:self.hours=((self.hours+increment-1)%12)+1elifself.mode==SET_MINUTE:self.minutes=(self.minutes+increment)%60elifself.mode==SET_AMPM:self.is_pm=notself.is_pmdefupdate_display(self):"""Update the TM1637 display based on current mode and time"""ifself.mode==RUNNING:# Normal time display with blinking colonself.colon_on=notself.colon_onelse:# Setting mode - flash the active componentflash_on=(ticks_ms()//500)%2==0ifself.mode==SET_HOUR:ifnotflash_on:tm.show(' ')returnelifself.mode==SET_MINUTE:ifnotflash_on:tm.numbers(self.hours,0)returnelifself.mode==SET_AMPM:ifflash_on:tm.show(' '+('P'ifself.is_pmelse'A')+' ')return# Update displaytm.numbers(self.hours,self.minutes,colon=self.colon_on)defrun(self):"""Main clock loop"""tm.brightness(2)# Set initial brightnesswhileTrue:self.handle_buttons()ifself.mode==RUNNING:self.load_time_from_rtc()self.update_display()sleep(0.1)# Small delay to prevent display flicker# Create and run the clockif__name__=='__main__':clock=Clock()print("Starting clock... Use buttons to set time:")print("Mode: Switch between run/set hour/set minute/set AM,PM")print("Next/Prev: Adjust current setting")clock.run()
Key concepts and features of this implementation:
Button Handling
Uses pull-up resistors (buttons connect to ground when pressed)
Implements debouncing to prevent multiple triggers
Buttons are active-low (0 when pressed, 1 when released)
Mode System
RUNNING: Normal clock operation
SET_HOUR: Adjust hours (1-12)
SET_MINUTE: Adjust minutes (0-59)
SET_AMPM: Toggle between AM and PM
Visual Feedback
Selected component flashes when being set
Colon blinks in running mode
Special AM/PM display during setting
Time Management
Maintains time in 12-hour format internally
Converts to/from 24-hour format for RTC
Handles midnight/noon edge cases
State Management
Uses a class to organize state and behavior
Separates display, button handling, and time management
Common challenges students might encounter:
Button Debouncing
Understanding why debouncing is necessary
Adjusting debounce timing for reliable operation
Time Format Conversion
Converting between 12/24 hour formats
Handling edge cases (12 AM/PM)
Display Updates
Managing display refresh rate
Creating smooth visual feedback
Suggested exercises for students:
Add a temperature display mode
Implement a brightness adjustment feature
Add an alarm setting mode
Save settings to flash memory
Add a battery backup indicator
Would you like me to explain any part in more detail or provide examples of these extensions?