Toggle Navigation
Hatchery
Eggs
picview
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
#!/usr/bin/env python3 import buttons import display import os import struct import utime MODES = [ "single", # show single picture, switch with buttons on the right "rotate", # rotate pictures ] BTN_LISTEN = buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT def draw_bmp(filename): with open(filename, "rb+") as bmpfile: header, filesize, _, _, data_offset = struct.unpack("<HIHHI", bmpfile.read(14)) if header != 0x4D42: raise ValueError("Only Windows BMP supported") bmpinfo = bmpfile.read(data_offset - 14) width, height, _, bpp, compr = struct.unpack("<IIHHI", bmpinfo[4:20]) if bpp != 24: raise ValueError("Only 24 bpp BMP supported") if compr != 0: raise ValueError("CompressValueError not supported") pad = (width * -3) % 4 if width > 161: raise ValueError("Maximum width 161 supported") if height > 81: raise ValueError("Maximum height 81 supported") pressed = 0 data = bmpfile.read(512) i = 2 with display.open() as d: d.clear() for y in range(height - 1, -1, -1): for x in range(width): if i >= len(data): i = 2 + (i - len(data)) data = data[-2:] + bmpfile.read(512) d.pixel(x, y, col=(data[i], data[i - 1], data[i - 2])) i += 3 i += pad # skip padding pressed = buttons.read(BTN_LISTEN) or pressed if pressed: break d.update() return pressed def message(msg, delay=0): with display.open() as disp: disp.clear() posy = 0 while msg and posy < 75: cur, msg = msg[:11], msg[11:] disp.print(cur, posx=0, posy=posy) posy += 18 disp.update() return utime.time_ms() + int(delay * 1000) def main(): if "pics" not in os.listdir("/"): message("No pics dir found") utime.sleep(5) return pics = list( sorted( [ "/pics/{}".format(fn) for fn in os.listdir("/pics") if fn.lower().endswith(".bmp") ], key=lambda x: x.lower(), ) ) if not pics: message("No BMP images found in /pics") utime.sleep(5) return pic_i = 0 # current picture index pic_dirty = True # whether a new picture should be drawn on screen mode = MODES[0] # show single picture delay = 5.0 # delay between pictures in rotate mode last_update = 0 # last time a new picture was displayed last_press = 0 # last time a button press was acted upon # used when the screen should not be updated for a while, except when # responding to button presses: sleep_until = 0 pressed = 0 while True: # Listen for buttons and change state as needed pressed = pressed or buttons.read(BTN_LISTEN) if pressed: if utime.time_ms() - last_press < 500: pressed = 0 # only accept key press every half second else: last_press = utime.time_ms() else: last_press = 0 if pressed == buttons.BOTTOM_LEFT: # bottom left: switch mode if mode == MODES[0]: mode = MODES[1] else: mode = MODES[0] pic_dirty = True sleep_until = message("Mode:{}".format(mode), 0.5) elif pressed == buttons.BOTTOM_RIGHT: if mode == MODES[0]: pic_i = (pic_i + 1) % len(pics) pic_dirty = True sleep_until = message(pics[pic_i][6:-4], 0.5) else: delay = delay * 1.5 sleep_until = message("Delay:{:.1f} seconds".format(delay), 1) elif pressed == buttons.TOP_RIGHT: if mode == MODES[0]: pic_i = (pic_i - 1) % len(pics) pic_dirty = True sleep_until = message(pics[pic_i][6:-4], 0.5) else: delay = max(0.1, delay / 1.5) sleep_until = message("Delay:{:.1f} seconds".format(delay), 0.5) pressed = 0 if mode == MODES[1]: if utime.time_ms() - last_update > int(delay * 1000): pic_i = (pic_i + 1) % len(pics) pic_dirty = True if pic_dirty and sleep_until < utime.time_ms(): pic_dirty = False last_update = utime.time_ms() try: pressed = draw_bmp(pics[pic_i]) except Exception as e: message("{}: {}".format(pics[pic_i], str(e))) utime.sleep(0.1) main()