Toggle Navigation
Hatchery
Eggs
FullDigi
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
# by @monkeydom (@monkeydom@mastodon.technology) # font by Daniel Linnsen ( https://managore.itch.io/m3x6 ) import display import os import utime import leds import buttons import bme680 import light_sensor WIDTH = 160 HEIGHT = 80 DEBUG = False class SmallType: def __init__(self, display, position_x = 0, position_y = 0, color = (255,255,255)): self.display = display self.position_x = position_x self.position_y = position_y self.scale = 1 self.color = color self.toLeft = False def char_spec(self, character): return { "" " ":(4,(-1,-1)), ".":(4,(1,5)), "=":(4,(1,2),(0,2),(2,2),(1,4),(0,4),(2,4)), "<":(4,(2,1),(1,2),(0,3),(1,4),(2,5)), ">":(4,(0,1),(1,2),(2,3),(1,4),(0,5)), ":":(4,(1,2),(1,5)), ";":(4,(1,2),(1,5),(1,6)), ",":(4,(1,5),(1,6)), "!":(4,(1,0),(1,1),(1,2),(1,3),(1,5)), '"':(4,(0,0),(0,1),(2,0),(2,1)), "'":(4,(1,0),(1,1)), "|":(4,(1,0),(1,1),(1,2),(1,3),(1,4),(1,5)), "/":(4,(2,0),(2,1),(1,2),(1,3),(0,4),(0,5)), "\\":(4,(0,0),(0,1),(1,2),(1,3),(2,4),(2,5)), "%":(4,(0,1),(2,2),(1,3),(0,4),(2,5)), "*":(4,(0,1),(2,1),(1,2),(0,3),(2,3)), "+":(4,(1,2),(0,3),(1,3),(2,3),(1,4)), "^":(4,(1,0),(0,1),(2,1)), "-":(4,(0,3),(1,3),(2,3)), "_":(4,(0,5),(1,5),(2,5)), "@":(6,(1,0),(2,0),(3,0),(0,1),(3,1),(4,1),(0,2),(2,2),(4,2),(0,3),(2,3),(3,3),(4,3),(0,4),(1,5),(2,5),(3,5),(4,5)), "$":(4,(1,0),(1,1),(2,1),(0,2),(0,3),(1,3),(2,3),(2,4),(0,5),(1,5),(1,6)), "{":(4,(2,0),(1,1),(1,2),(0,3),(1,4),(1,5),(2,6)), "}":(4,(0,0),(1,1),(1,2),(2,3),(1,4),(1,5),(0,6)), "(":(4,(1,0),(0,1),(0,2),(0,3),(0,4),(1,5)), ")":(4,(1,0),(2,1),(2,2),(2,3),(2,4),(1,5)), "[":(4,(0,0),(1,0),(0,1),(0,2),(0,3),(0,4),(0,5),(1,5)), "]":(4,(2,0),(1,0),(2,1),(2,2),(2,3),(2,4),(2,5),(1,5)), '#':(6,(1,0),(3,0),(0,1),(1,1),(2,1),(3,1),(4,1),(1,2),(3,2),(1,3),(3,3),(0,4),(1,4),(2,4),(3,4),(4,4),(1,5),(3,5)), '0':(4,(1,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(0,5)), '1':(4,(1,0),(0,1),(1,1),(1,2),(1,3),(1,4),(0,5),(1,5),(2,5)), '2':(4,(0,0),(1,0),(2,1),(2,2),(1,3),(0,4),(0,5),(1,5),(2,5)), '3':(4,(0,0),(1,0),(2,1),(0,2),(1,2),(2,3),(2,4),(0,5),(1,5)), '4':(4,(0,0),(2,0),(0,1),(2,1),(1,2),(2,2),(2,3),(2,4),(2,5)), '5':(4,(0,0),(1,0),(2,0),(0,1),(0,2),(1,2),(2,3),(2,4),(0,5),(1,5)), '6':(4,(1,0),(2,0),(0,1),(0,2),(1,2),(0,3),(2,3),(0,4),(2,4),(1,5),(2,5)), '7':(4,(0,0),(1,0),(2,0),(2,1),(1,2),(1,3),(1,4),(1,5)), '8':(4,(1,0),(2,0),(0,1),(2,1),(1,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5)), '9':(4,(0,0),(1,0),(0,1),(2,1),(0,2),(2,2),(1,3),(2,3),(2,4),(0,5),(1,5)), 'A':(4,(1,0),(2,0),(0,1),(2,1),(0,2),(1,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'B':(4,(0,0),(1,0),(0,1),(2,1),(0,2),(1,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'C':(4,(1,0),(2,0),(0,1),(0,2),(0,3),(0,4),(0,5),(1,5),(2,5)), 'D':(4,(0,0),(1,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(2,5)), 'E':(4,(0,0),(1,0),(2,0),(0,1),(0,2),(1,2),(0,3),(0,4),(0,5),(1,5),(2,5)), 'F':(4,(1,0),(2,0),(0,1),(0,2),(1,2),(0,3),(0,4),(0,5)), 'G':(4,(1,0),(2,0),(0,1),(0,2),(0,3),(2,4),(0,4),(2,4),(0,5),(1,5),(2,5)), 'H':(4,(0,0),(2,0),(0,1),(2,1),(0,2),(1,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'I':(4,(0,0),(1,0),(2,0),(1,1),(1,2),(1,3),(1,4),(0,5),(1,5),(2,5)), 'J':(4,(0,0),(1,0),(2,0),(2,1),(2,2),(2,3),(2,4),(0,5),(1,5)), 'K':(4,(0,0),(2,0),(0,1),(2,1),(0,2),(1,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'L':(4,(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(1,5),(2,5)), 'M':(6,(0,0),(1,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(4,5),(4,4),(4,3),(4,2),(4,1),(3,0)), 'N':(4,(0,0),(1,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'O':(4,(1,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(0,5)), 'P':(4,(0,0),(1,0),(2,0),(0,1),(2,1),(0,2),(1,2),(0,3),(0,4),(0,5)), 'Q':(4,(1,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(2,5),(2,6)), 'R':(4,(0,0),(1,0),(2,0),(0,1),(2,1),(0,2),(1,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'S':(4,(1,0),(2,0),(0,1),(0,2),(1,2),(2,2),(2,3),(2,4),(0,5),(1,5)), 'T':(4,(0,0),(1,0),(2,0),(1,1),(1,2),(1,3),(1,4),(1,5)), 'U':(4,(0,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'V':(4,(0,0),(2,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5)), 'W':(6,(0,0),(4,0),(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(3,5),(4,1),(4,2),(4,3),(4,4)), 'X':(4,(0,0),(2,0),(0,1),(2,1),(1,2),(1,3),(0,4),(2,4),(0,5),(2,5)), 'Y':(4,(0,0),(2,0),(0,1),(2,1),(0,2),(2,2),(1,3),(1,4),(1,5)), 'Z':(4,(0,0),(1,0),(2,0),(2,1),(1,2),(1,3),(0,4),(0,5),(1,5),(2,5)), 'a':(4,(0,1),(1,1),(2,2),(1,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'b':(4,(0,0),(0,1),(1,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'c':(4,(2,1),(1,1),(0,2),(0,3),(0,4),(0,5),(1,5),(2,5)), 'd':(4,(2,0),(2,1),(1,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'e':(4,(1,1),(2,1),(0,2),(2,2),(0,3),(1,3),(2,3),(0,4),(1,5),(2,5)), 'f':(4,(2,0),(1,1),(1,2),(0,3),(1,3),(2,3),(1,4),(1,5)), 'g':(4,(1,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(1,4),(2,4),(2,5),(0,6),(1,6)), 'h':(4,(0,0),(0,1),(1,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'i':(4,(1,0),(1,2),(1,3),(1,4),(1,5)), 'j':(4,(1,0),(1,2),(1,3),(1,4),(1,5),(0,6)), 'k':(4,(0,0),(0,1),(2,1),(0,2),(1,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'l':(4,(1,0),(1,1),(1,2),(1,3),(1,4),(2,5)), 'n':(4,(0,1),(1,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5)), 'm':(6,(0,1),(1,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(2,5),(3,1),(4,2),(4,3),(4,4),(4,5)), 'o':(4,(1,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5)), 'p':(4,(0,1),(1,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(0,6),(0,7)), 'q':(4,(1,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5),(2,6),(2,7)), 'r':(4,(1,1),(2,1),(0,2),(0,3),(0,4),(0,5)), 's':(4,(1,1),(2,1),(0,2),(0,3),(1,3),(2,3),(2,4),(0,5),(1,5)), 't':(4,(1,0),(1,1),(1,2),(0,2),(1,3),(2,2),(1,4),(1,5)), 'u':(4,(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(0,5),(1,5),(2,5)), 'v':(4,(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5)), 'w':(6,(0,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(3,5),(4,1),(4,2),(4,3),(4,4)), 'x':(4,(0,1),(2,1),(0,2),(2,2),(1,3),(0,4),(2,4),(0,5),(2,5)), 'y':(4,(0,1),(2,1),(0,2),(2,2),(0,3),(2,3),(0,4),(2,4),(1,5),(2,5),(2,6),(0,7),(1,7)), 'z':(4,(0,1),(1,1),(2,1),(2,2),(1,3),(0,4),(0,5),(1,5),(2,5)), '°':(4,(1,0),(0,1),(2,1),(1,3)), }.get(character, (4,(0,0),(1,0),(2,1),(2,2),(1,3),(1,5)) ) def print_char(self, character): disp = self.display color = self.color (x_advance, *pixels) = self.char_spec(character) scale = self.scale x_advance *= scale if self.toLeft: self.position_x -= x_advance x = self.position_x y = self.position_y if scale != 1: gap = 1 if scale > 2 else 0 plot = lambda dx,dy: disp.rect(x+dx*scale,y+dy*scale,x+(dx+1)*scale-gap,y+(dy+1)*scale-gap,col=color) else: plot = lambda dx,dy: disp.pixel(x+dx,y+dy,col=color) for (dx, dy) in pixels: if dx != -1: plot(dx, dy) if not self.toLeft: self.position_x += x_advance def advance_if_needed(self): if self.position_x > WIDTH - 3: self.position_x = 0 self.position_y += 9 def width(self, string): result = 0 for character in string: (x_advance, *pixels) = self.char_spec(character) result += x_advance return result * self.scale def print_string(self, string): start_x = self.position_x def advance(): self.position_x = start_x self.position_y += 9 * self.scale for character in string: if character == "\n": advance() else: advancement = self.char_spec(character)[0] if (self.toLeft and (self.position_x - advancement) < 0) or (not(self.toLeft) and (self.position_x + advancement) > WIDTH): advance() self.print_char(character) class DigiClock: def __init__(self, display): # sensors bme680.init() light_sensor.start() self.display = display self.small_type = SmallType(display) self.brightness = 70 self.mode = 5 self.button_bottom_right = False self.button_bottom_left = False self.button_top_right = False self.color_background = (0,0,0) self.color_foreground = (255,255,255) self.color_secondary = (128,128,128) self.color_adjust = (205,10,10) self.color_sensor = (128,255,128) def draw_sensordata(self): disp = self.display st = self.small_type temperature, humidity, pressure, resistance = bme680.get_data() sensor_string = "{0:2.1f}C {1:1.0f}%rh {2:1.1f}hPA {3:.0f}l {4:1.2f}V {5:3.0f}b".format(temperature, humidity, pressure, resistance, os.read_battery(), light_sensor.get_reading()) disp.rect(0,55,WIDTH,55+7,col=self.color_background) st.color = self.color_sensor st.toLeft = False st.scale = 1 st.position_x = 0 st.position_y = 55 st.print_string(sensor_string) def draw_statics(self): disp = self.display st = self.small_type disp.clear() if self.mode==6: st.color = self.color_foreground nick = load_nick().get("nick","") st.scale = 2 st.position_x = int((WIDTH - st.width(nick))/ 2) st.position_y = 55 st.print_string(nick) elif self.mode==5: pass else: text = "adjust" st.color = self.color_adjust st.scale = 2 st.position_x = int((WIDTH - st.width(text))/ 2) st.position_y = 55 st.print_string(text) st.color = self.color_secondary # button labels st.scale = 1 st.position_x = 0 st.position_y = HEIGHT - 8 st.print_string("MODE") st.scale = 2 st.toLeft = True st.position_y = HEIGHT - 8 st.position_x = WIDTH-1 st.print_string("-") st.position_y = HEIGHT-20 st.position_x = WIDTH-1 st.print_string("+") def draw(self): disp = self.display st = self.small_type disp.rect(0,0,WIDTH,50,col=self.color_background) (year, month, mday, hour, min, sec, wday, yday) = utime.localtime(utime.time()) if self.mode<5: digit_width = 20 (x,y) = (WIDTH-digit_width,5) x -= digit_width * self.mode + int(self.mode/2) * digit_width + 3 disp.rect(x,y,x+digit_width-1,y+8*5,col=self.color_adjust) elif self.mode==5: self.draw_sensordata() else: rotate = utime.time() % 3 for i in range(3): leds.set_rocket(i, int(31 * self.brightness / 100) if (rotate == i) else 0) time_string = "%02d:%02d:%02d" % (hour,min,sec) st.color = self.color_foreground st.scale = 5 st.toLeft = False st.position_x = 0 st.position_y = 10 st.print_string(time_string) def loop(self): try: disp = self.display st = self.small_type self.draw_statics() while True: start_time = utime.time_ms() self.draw() disp.update() now = utime.time_ms() draw_time = now - start_time; if DEBUG: st.position_x = 0 st.position_y = 0 st.scale = 1 st.toLeft = False st.print_string(str(draw_time)) disp.update() now = utime.time_ms() self.handle_buttons(1000 - (now % 1000) + now) # if (now - start_time < 900): # utime.sleep_ms(1000 - (utime.time_ms() % 1000)) except KeyboardInterrupt: for i in range(11): leds.set(i, (0,0,0)) return def handle_buttons(self,until_time): needs_redraw = False while True: v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT) if v & buttons.TOP_RIGHT: if not self.button_top_right: needs_redraw = self.handle_top_right_down() self.button_top_right = True else: self.button_top_right = False if v & buttons.BOTTOM_RIGHT: if not self.button_bottom_right: needs_redraw = self.handle_bottom_right_down() self.button_bottom_right = True else: self.button_bottom_right = False if v & buttons.BOTTOM_LEFT: if not self.button_bottom_left: needs_redraw = self.handle_bottom_left_down() self.button_bottom_left = True else: self.button_bottom_left = False if utime.time_ms() > until_time or needs_redraw: return utime.sleep_ms(10) def adjust_brightness(self, change): def clamp(value): return min(100,max(0, value)) self.brightness = clamp(self.brightness + change) self.display.backlight(self.brightness) def handle_top_right_down(self): return self.handle_adjust(1) def handle_bottom_right_down(self): return self.handle_adjust(-1) def handle_bottom_left_down(self): def clamp(value): if value > 6: value = 0 return value self.mode = clamp(self.mode+1) self.draw_statics() return True def handle_adjust(self,change): if self.mode >= 5: self.adjust_brightness(10 * change) return False else: adjusted_change = {0: 1, 1: 10, 2: 60, 3: 60*10, 4: 60*60}.get(self.mode, 60) * change utime.set_time(utime.time() + adjusted_change) return True def load_nick(): filename = "nickname.txt" if filename in os.listdir("/"): with open("/" + filename, "r") as f: nick = f.read().strip() return {"nick": nick} return {} def main(): with display.open() as disp: if DEBUG: disp.clear((255,0,0)).update() disp.backlight(100) dc = DigiClock(disp) dc.loop() if DEBUG: def r(): os.reset() if __name__ == "__main__": main()