Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
badgie/simplebadge.py
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
227 lines (178 sloc)
5.83 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import badger2040 | |
import machine | |
import time | |
import random | |
import os | |
import sys | |
badger = badger2040.Badger2040() | |
# Faye's badger badge code | |
# We'll have three modes as follows - | |
# - Adventurous (button a) with cool wacky stuff | |
# - Business (button b) just the standard Cov name badge | |
# - Combined (button c) which has the Cov name badge, but some dynamically changing updates to welcome people, etc | |
# | |
# For modes a & c, up/down will change the rate of update, for mode b, it will just toggle the QR code and Pheonix | |
# Let's set up some constants | |
MODE_A = 1 | |
MODE_B = 2 | |
MODE_C = 3 | |
PHEONIX=0 | |
QR=1 | |
NAME = "Dr Faye Mitchell" | |
SCHOOL1 = "Computing, Electronics" | |
SCHOOL2 = "and Mathematics" | |
ROLE = "Acting Head of School" | |
WIDTH = badger2040.WIDTH | |
HEIGHT = badger2040.HEIGHT | |
IMAGE_WIDTH = 104 | |
COMPANY_HEIGHT = 30 | |
DETAILS_HEIGHT = 20 | |
NAME_HEIGHT = HEIGHT - COMPANY_HEIGHT - (DETAILS_HEIGHT * 2) - 2 | |
TEXT_WIDTH = WIDTH - IMAGE_WIDTH - 1 | |
NAME_PADDING = 10 | |
ROLE_TEXT_SIZE = 0.6 | |
SCHOOL_TEXT_SIZE = 0.5 | |
BADGE_IMAGE = bytearray(int(IMAGE_WIDTH * HEIGHT / 8)) | |
QR_IMAGE = bytearray(int(IMAGE_WIDTH * HEIGHT / 8)) | |
SPEED_MULTIPLIER = 60 | |
# Let's set up some defaults | |
cmode = MODE_A | |
cimage = PHEONIX | |
speed = 5 | |
changed = False | |
display = badger2040.Badger2040() | |
display.update_speed(badger2040.UPDATE_NORMAL) | |
# This is to set up the buttons | |
button_a = machine.Pin(badger2040.BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN) | |
button_b = machine.Pin(badger2040.BUTTON_B, machine.Pin.IN, machine.Pin.PULL_DOWN) | |
button_c = machine.Pin(badger2040.BUTTON_C, machine.Pin.IN, machine.Pin.PULL_DOWN) | |
button_up = machine.Pin(badger2040.BUTTON_UP, machine.Pin.IN, machine.Pin.PULL_DOWN) | |
button_down = machine.Pin(badger2040.BUTTON_DOWN, machine.Pin.IN, machine.Pin.PULL_DOWN) | |
def button(pin): | |
global cmode | |
global speed | |
global changed | |
changed = True | |
if pin == button_a: | |
cmode = MODE_A | |
return | |
if pin == button_b: | |
cmode=MODE_B | |
return | |
if pin == button_c: | |
cmode=MODE_C | |
return | |
if pin == button_up: | |
speed = speed + 5 | |
if (speed > 300) : | |
speed = 300 | |
return | |
if pin == button_down: | |
speed = speed - 5 | |
if (speed < 0) : | |
speed = 0 | |
return | |
button_a.irq(trigger=machine.Pin.IRQ_RISING, handler=button) | |
button_b.irq(trigger=machine.Pin.IRQ_RISING, handler=button) | |
button_c.irq(trigger=machine.Pin.IRQ_RISING, handler=button) | |
button_up.irq(trigger=machine.Pin.IRQ_RISING, handler=button) | |
button_down.irq(trigger=machine.Pin.IRQ_RISING, handler=button) | |
# This is to load in the Pheonix and the QR code | |
try: | |
open("pheonix.bin", "rb").readinto(BADGE_IMAGE) | |
except OSError: | |
try: | |
import badge_image | |
BADGE_IMAGE = bytearray(badge_image.data()) | |
del badge_image | |
except ImportError: | |
pass | |
try: | |
open("qr.bin", "rb").readinto(QR_IMAGE) | |
except OSError: | |
try: | |
import badge_image | |
QR_IMAGE = bytearray(badge_image.data()) | |
del badge_image | |
except ImportError: | |
pass | |
# Reduce the size of a string until it fits within a given width | |
def truncatestring(text, text_size, width): | |
while True: | |
length = display.measure_text(text, text_size) | |
if length > 0 and length > width: | |
text = text[:-1] | |
else: | |
text += "" | |
return text | |
def fitstring(text, text_size, width): | |
ret = [""] | |
length = display.measure_text(text, text_size) | |
if length < width: | |
ret = [text] | |
return ret | |
else: | |
splitstring = text.split() | |
pos = 0 | |
for c in splitstring: | |
length = display.measure_text(ret[pos]+" "+c, text_size) | |
if length > width: | |
pos = pos + 1 | |
ret.append(c) | |
else: | |
ret[pos] = ret[pos]+" "+c | |
return ret | |
# This is business mode, it's the simplest of all of them | |
def modeb(): | |
display.pen(15) | |
display.clear() | |
cimage = speed % 2 | |
if cimage == PHEONIX : | |
display.image(BADGE_IMAGE, IMAGE_WIDTH, HEIGHT, WIDTH - IMAGE_WIDTH, 0) | |
if cimage == QR : | |
display.image(QR_IMAGE, IMAGE_WIDTH, HEIGHT, WIDTH - IMAGE_WIDTH, 0) | |
display.pen(0) | |
display.font("sans") | |
display.thickness(3) | |
name_size = 2.0 # A sensible starting scale | |
while True: | |
name_length = display.measure_text(NAME, name_size) | |
if name_length >= (TEXT_WIDTH - NAME_PADDING) and name_size >= 0.1: | |
name_size -= 0.01 | |
else: | |
display.text(NAME, (TEXT_WIDTH - name_length) // 2, 20, name_size) | |
break | |
display.pen(0) | |
display.font("sans") | |
display.thickness(2) | |
name_size = ROLE_TEXT_SIZE # A sensible starting scale | |
while True: | |
name_length = display.measure_text(ROLE, name_size) | |
if name_length >= (TEXT_WIDTH - NAME_PADDING) and name_size >= 0.1: | |
name_size -= 0.01 | |
else: | |
display.text(ROLE, (TEXT_WIDTH - name_length) // 2, 40, name_size) | |
break | |
display.pen(0) | |
display.font("sans") | |
display.thickness(2) | |
name_size = SCHOOL_TEXT_SIZE # A sensible starting scale | |
while True: | |
name_length = display.measure_text(SCHOOL1, name_size) | |
if name_length >= (TEXT_WIDTH - NAME_PADDING) and name_size >= 0.1: | |
name_size -= 0.01 | |
else: | |
display.text(SCHOOL1, (TEXT_WIDTH - name_length) // 2, 80, name_size) | |
break | |
while True: | |
name_length = display.measure_text(SCHOOL2, name_size) | |
if name_length >= (TEXT_WIDTH - NAME_PADDING) and name_size >= 0.1: | |
name_size -= 0.01 | |
else: | |
display.text(SCHOOL2, (TEXT_WIDTH - name_length) // 2, 100, name_size) | |
break | |
display.update() | |
# This is a dynamic mode that has welcome messages and the QR code version of the name | |
# This is the main loop | |
modeb() | |
display.halt() |