Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Ben's Clock v16 for PRESTO ===================== NOT WORKING ==============
- # Change colours via buttons - Press X to start
- # Author: Tony Goodhew - 30th Jan 2025 - Tonygo2 on Pimoroni Forum
- # Requirements: PRESTO with Qw/ST Pad fitted and library installed
- # Uses Vector fonts on hour elements
- # Press Y to set time and A to return and RUN on
- # L and R switch between Hours and Minutes
- # Press U and D to change value
- # RED is active value GREEN is inactive
- # 5 Minute positions emphasised
- # Uses Epoch time - OK until 2038
- # Ajusted to Ben's Roll-over sequence
- # Pad + and - turn visible numbers ON and OFF
- # X to start change colour section
- # U and D to cycle through colours
- # B to return to running clock
- # Will probably need to reset time
- # ========== To Do List =======
- # Remove Jump Flag line 369 approx to stop time jumps
- import gc
- import time
- from machine import I2C, Pin
- import math
- from qwstpad import QwSTPad
- from presto import Presto
- from picovector import ANTIALIAS_FAST, PicoVector, Polygon, Transform
- # Setup for the Presto display
- presto = Presto(full_res=True)
- display = presto.display
- touch = presto.touch # Activate touch
- i2c = I2C(id=0,scl=Pin(41), sda=Pin(40)) # PRESTO
- # Connect single default I2C address QwSTPad
- try:
- qwstpad = QwSTPad(i2c, 0x21)
- except OSError:
- print("QwSTPad: Not Connected ... Exiting")
- raise SystemExit
- # Turn of LED on qw/stpad
- qwstpad.set_leds(0)
- WIDTH, HEIGHT = display.get_bounds()
- #WIDTH = 200
- #HEIGHT = WIDTH
- display.set_font("bitmap8") # Change the font
- # Create some colours - not all used at the moment
- RED = display.create_pen(255,0,0)
- PINK = display.create_pen(250, 125, 180)
- PINK2 = display.create_pen(247,21,157)
- ORANGE = display.create_pen(245, 165, 4)
- CLEMENTINE = display.create_pen(255,89,0)
- YELLOW = display.create_pen(255, 255, 0)
- GREEN = display.create_pen(0,255,0)
- GREEN2 = display.create_pen(71, 225, 32)
- CYAN = display.create_pen(0,255,255)
- MAGENTA = display.create_pen(255,0,255)
- BLUE = display.create_pen(20,0,255)
- WHITE = display.create_pen(255, 255, 255)
- GREY = display.create_pen(75, 75, 75)
- DKGREY = display.create_pen(20,20,35)
- BLACK = display.create_pen(0, 0, 0)
- colours = [BLUE,RED,PINK,PINK2,ORANGE,CLEMENTINE,YELLOW,GREEN,GREEN2,CYAN,MAGENTA]
- col_leng = len(colours)
- # Pico Vector setup section
- vector = PicoVector(display)
- vector.set_antialiasing(ANTIALIAS_FAST)
- t = Transform()
- vector.set_font("Roboto-Medium.af", 54)
- vector.set_font_letter_spacing(100)
- vector.set_font_word_spacing(100)
- vector.set_transform(t)
- vector.set_font_size(20)
- # A few procedures to be used later
- def clean(): # Clear the screen to Black
- display.set_pen(BLACK)
- display.clear()
- def face(hours,mins,secs,hcol,mcol,scol): # This one majority of the work
- cx = int(WIDTH /2) # Centre of clock
- cy = int(HEIGHT /2)
- l = cy -1 # Max radius
- r1 = int(l * 0.62)
- r2 = int(l * 0.58) # minutes
- r3 = int(l * 0.44)
- r4 = int(l * 0.41) # hours
- r5 = int(l * 0.05)
- # SECONDS
- limit = secs * 6 + 1
- stop = 360
- if secs == 0: # Ben's adjustment
- limit = 999
- stop = 366
- for angle in range(0,stop,6):
- display.set_pen(minor)
- if (angle < limit) and (angle > 0):
- display.set_pen(scol)
- if thin :
- # Thin
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- display.line(cx,cy,cx+xx,cy+yy)
- else:
- # Thick
- yyp = -int(round(l * math.cos(math.radians(angle+st))))
- xxp = int(round(l * math.sin(math.radians(angle+st))))
- yym = -int(round(l * math.cos(math.radians(angle-st))))
- xxm = int(round(l * math.sin(math.radians(angle-st))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- if (secs == 0) and secspecial: # Special case
- display.set_pen(major)
- angle = 0
- if thin :
- # Thin
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- display.line(cx,cy,cx+xx,cy+yy)
- else:
- # Thick
- yyp = -int(round(l * math.cos(math.radians(angle+st))))
- xxp = int(round(l * math.sin(math.radians(angle+st))))
- yym = -int(round(l * math.cos(math.radians(angle-st))))
- xxm = int(round(l * math.sin(math.radians(angle-st))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- display.set_pen(BLACK)
- display.circle(cx,cy,r1)
- # MINUTES
- l = r2
- limit = mins * 6 + 1
- stop = 360
- if mins == 0 and (secs == 0): # Ben's adjustment
- limit = 999
- stop = 366
- for angle in range(0,stop,6):
- display.set_pen(minor)
- if (angle < limit) and (angle > 0):
- display.set_pen(mcol)
- if thin:
- # Thin
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- display.line(cx,cy,cx+xx,cy+yy)
- else:
- # Thick
- yyp = -int(round(l * math.cos(math.radians(angle+mt))))
- xxp = int(round(l * math.sin(math.radians(angle+mt))))
- yym = -int(round(l * math.cos(math.radians(angle-mt))))
- xxm = int(round(l * math.sin(math.radians(angle-mt))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- # Needed if you consider zero minutes need to be shown
- if (mins == 0) and minspecial and (secs == 0): # Special case
- display.set_pen(major)
- angle = 0
- if thin:
- # Thin
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- display.line(cx,cy,cx+xx,cy+yy)
- else:
- # Thick
- yyp = -int(round(l * math.cos(math.radians(angle+mt))))
- xxp = int(round(l * math.sin(math.radians(angle+mt))))
- yym = -int(round(l * math.cos(math.radians(angle-mt))))
- xxm = int(round(l * math.sin(math.radians(angle-mt))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- display.set_pen(BLACK)
- display.circle(cx,cy,r3)
- # HOURS
- l = r5
- lh = r4
- ht = 12
- display.set_pen(hcol)
- for h in range(1,13,1):
- angle = h * 30
- display.set_pen(minor)
- if h <= hours:
- display.set_pen(major)
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- yyp = -int(round(lh * math.cos(math.radians(angle+ht))))
- xxp = int(round(lh * math.sin(math.radians(angle+ht))))
- yym = -int(round(lh * math.cos(math.radians(angle-ht))))
- xxm = int(round(lh * math.sin(math.radians(angle-ht))))
- display.triangle(cx+xx,cy+yy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- if numbers: # TESTING and Learning "+" and "-" control on qwstpad
- display.set_pen(YELLOW)
- display.text("M: "+str(mins),5,5,90,3)
- display.text("S: "+str(secs),420,5,90,3)
- display.text("H: "+str(hours),5,50,100,3)
- display.set_pen(DKGREY)
- ''' # Using Crude font
- display.text("9",155,235,50,4)
- display.text("3",320,235,50,4)
- display.text("6",238,310,50,4)
- display.text("12",235,155,50,4)
- '''
- # Using vector font
- vector.set_font_size(40)
- # display.set_pen(RED) # for testing
- vector.text("9", 149,253) # ("Text", x,y)
- vector.text("3",313,253)
- vector.text("6",232,330)
- vector.set_font_size(32)
- vector.text("12",223,171)
- presto.update()
- # ============= SET TIME SECTION =================================
- def show_vals(cur,val):
- for i in range(2):
- xx = 20 + i * 60
- display.set_pen(RED)
- if cur == i:
- display.set_pen(YELLOW)
- display.text(str(val[i]),xx,400,200,3)
- def show_mins(m,c):
- cx = int(WIDTH /2) # Centre of clock
- cy = int(HEIGHT /2)
- l = cy # Max radius
- r1 = int(l * 0.62)
- r2 = int(l * 0.58) # minutes
- r3 = int(l * 0.44)
- r4 = int(l * 0.41) # hours
- r5 = int(l * 0.05)
- angle = m*6 + 1
- l = r2
- mt = 1.7 # minutes thickness
- st = 1.9 # seconds thickness
- # Empty minutes
- for angle2 in range(0,360,6):
- display.set_pen(minor)
- if angle2 % 5 == 0: # Indicate 5 min intervals
- display.set_pen(GREY)
- # Thick
- yyp = -int(round(l * math.cos(math.radians(angle2+mt))))
- xxp = int(round(l * math.sin(math.radians(angle2+mt))))
- yym = -int(round(l * math.cos(math.radians(angle2-mt))))
- xxm = int(round(l * math.sin(math.radians(angle2-mt))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- display.set_pen(c)
- yyp = -int(round(l * math.cos(math.radians(angle+mt))))
- xxp = int(round(l * math.sin(math.radians(angle+mt))))
- yym = -int(round(l * math.cos(math.radians(angle-mt))))
- xxm = int(round(l * math.sin(math.radians(angle-mt))))
- display.triangle(cx,cy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- display.set_pen(BLACK)
- display.circle(cx,cy,r3)
- def show_hours(h,c):
- cx = int(WIDTH /2) # Centre of clock
- cy = int(HEIGHT /2)
- l = cy # Max radius
- r1 = int(l * 0.62)
- r2 = int(l * 0.58)
- r3 = int(l * 0.44)
- r4 = int(l * 0.41)
- r5 = int(l * 0.05)
- l = r5
- lh = r4
- ht = 12
- display.set_pen(c)
- angle = h * 30
- yy = -int(round(l * math.cos(math.radians(angle))))
- xx = int(round(l * math.sin(math.radians(angle))))
- yyp = -int(round(lh * math.cos(math.radians(angle+ht))))
- xxp = int(round(lh * math.sin(math.radians(angle+ht))))
- yym = -int(round(lh * math.cos(math.radians(angle-ht))))
- xxm = int(round(lh * math.sin(math.radians(angle-ht))))
- display.triangle(cx+xx,cy+yy,cx+xxp,cy+yyp,cx+xxm,cy+yym)
- def set_time():
- qwstpad.set_leds(2) # qw/stpad LEDS off - set time indication
- p = 0
- show_vals(p,val)
- presto.update()
- buttons = qwstpad.read_buttons()
- while buttons["A"] == False: # HALT loop with button'A'
- clean()
- diff = 1
- # Read all the buttons from the qwstpad
- buttons = qwstpad.read_buttons()
- if buttons["U"] == True:
- val[p] = val[p] + diff
- if val[p] > maxx[p]:
- val[p] = minn[p]
- elif buttons["D"] == True:
- val[p] = val[p] - diff
- if val[p] < minn[p]:
- val[p] = maxx[p]
- elif (buttons["R"] == True) or (buttons["L"] == True):
- if p == 1:
- p = 0
- else:
- p = 1
- # Show the changed value
- if p == 0:
- mcol = GREEN
- hcol = RED
- else:
- mcol = RED
- hcol = GREEN
- show_mins(val[1],mcol)
- show_hours(val[0],hcol)
- show_vals(p,val)
- presto.update()
- # Wait for button release
- while (buttons["U"]) or (buttons["D"]) or (buttons["L"]) or (buttons["R"]):
- buttons = qwstpad.read_buttons()
- time.sleep(0.1)
- # "A" has been pressed - return the values
- clean()
- presto.update()
- h = val[0]
- m = val[1]
- s = 0
- qwstpad.set_leds(0) # qw/stpad LEDS off
- return (h,m,s)
- # ========== SET TIME SECTION END ==========================
- # ================ Change colour section ===================
- def get_col(p,cl ):
- delay = 0.15
- clean()
- display.set_pen(colours[p])
- display.clear()
- presto.update()
- running = True
- while running:
- buttons = qwstpad.read_buttons()
- if buttons["U"] == True:
- p = p + 1
- if p == cl:
- p = 0
- if buttons["D"] == True:
- p = p - 1
- if p < 0:
- p = cl -1
- display.set_pen(colours[p])
- print(p)
- display.clear()
- presto.update()
- if buttons["B"] == True:
- running = False
- # Wait for button release
- while (buttons["U"] == True) or (buttons["D"] == True):
- buttons = qwstpad.read_buttons()
- clean()
- return(p)
- # ========== END OF COLOUR CHANGE SECTION ============
- # ################# Clock running section #####################
- # Initial time and colours
- hours = 10
- mins =59
- secs = 55
- cp = 0
- major = colours[cp] # Major colour
- minor = DKGREY # Minor colour
- maxx = [12,59]
- minn = [1,0]
- val = [hours,mins]
- yy = 200
- mt = 1.7 # minutes thickness
- st = 1.9 # seconds thickness
- # TESTING FLAGS
- thin = False
- numbers = True
- jump = True
- # Show zero secs and mins - FLAGS
- minspecial = True
- secspecial = False
- last_second = None # Extra ======================
- # ################### Clock running loop ######################
- # Time control Extras ===============
- now = time.time()
- old_time = now
- while True:
- t_start = time.ticks_ms()
- now = time.time()
- old_time = now
- # year, month, day, hour, minute, second, _, _ = time.localtime()
- #end time control TOP========================================
- clean()
- face(hours,mins,secs,major,major,major)
- secs = secs + 1
- # Temp JUMP code ============= FOR TESTING =======================
- if jump:
- if secs == 7:
- secs = 55
- #============== =================================================
- if secs == 60:
- secs = 0
- mins = mins + 1
- if mins == 60:
- mins = 0
- hours = hours +1
- if hours == 13:
- hours = 1
- buttons = qwstpad.read_buttons()
- if buttons["Y"] == True: # Jump to SET TIME section
- val = [hours,mins] # Start from current time
- hours, mins,secs = set_time()
- if buttons["-"] == True:
- numbers = False
- if buttons["+"] == True:
- numbers = True
- if buttons["X"] == True:
- cp = get_col(cp,col_leng)
- major = colours[cp]
- gc.collect()
- # Time control - Wait for next second
- while old_time == now:
- time.sleep_ms(10)
- now = time.time()
- old_time = now
- t_end = time.ticks_ms()
- print(f"Took {t_end - t_start}ms")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement