2022-02-23 20:05:46 +00:00
import badger2040
import machine
import time
import sys
# Global Constants
WIDTH = badger2040 . WIDTH
HEIGHT = badger2040 . HEIGHT
IMAGE_WIDTH = 110
COMPANY_HEIGHT = 30
DETAILS_HEIGHT = 20
NAME_HEIGHT = HEIGHT - COMPANY_HEIGHT - ( DETAILS_HEIGHT * 2 ) - 2
TEXT_WIDTH = WIDTH - IMAGE_WIDTH - 1
COMPANY_TEXT_SIZE = 0.6
DETAILS_TEXT_SIZE = 0.5
LEFT_PADDING = 5
NAME_PADDING = 20
DETAIL_SPACING = 10
OVERLAY_BORDER = 40
OVERLAY_SPACING = 20
OVERLAY_TEXT_SIZE = 0.6
# ------------------------------
# Utility functions
# ------------------------------
# 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
# ------------------------------
# Drawing functions
# ------------------------------
# Draw an overlay box with a given message within it
def draw_overlay ( message , width , height , line_spacing , text_size ) :
# Draw a light grey background
display . pen ( 12 )
display . rectangle ( ( WIDTH - width ) / / 2 , ( HEIGHT - height ) / / 2 , width , height )
# Take the provided message and split it up into
# lines that fit within the specified width
words = message . split ( " " )
lines = [ ]
line = " "
appended_line = " "
for word in words :
if len ( word ) > 0 :
appended_line + = " "
appended_line + = word
if display . measure_text ( appended_line , text_size ) > = width :
lines . append ( line )
appended_line = word
else :
line = appended_line
if len ( line ) != 0 :
lines . append ( line )
display . pen ( 0 )
display . thickness ( 2 )
# Display each line of text from the message, centre-aligned
num_lines = len ( lines )
for i in range ( num_lines ) :
length = display . measure_text ( lines [ i ] , text_size )
current_line = ( i * line_spacing ) - ( ( num_lines - 1 ) * line_spacing ) / / 2
display . text ( lines [ i ] , ( WIDTH - length ) / / 2 , ( HEIGHT / / 2 ) + current_line , text_size )
# Draw the badge, including user text
def draw_badge ( ) :
display . pen ( 0 )
display . clear ( )
# Replace with drawing an image
display . pen ( 15 )
2022-02-23 20:14:57 +00:00
display . thickness ( 1 )
2022-02-23 20:05:46 +00:00
display . rectangle ( WIDTH - IMAGE_WIDTH , 0 , IMAGE_WIDTH , HEIGHT )
# Draw a border around the image
display . pen ( 0 )
display . thickness ( 1 )
display . line ( WIDTH - IMAGE_WIDTH , 0 , WIDTH - 1 , 0 )
display . line ( WIDTH - IMAGE_WIDTH , 0 , WIDTH - IMAGE_WIDTH , HEIGHT - 1 )
display . line ( WIDTH - IMAGE_WIDTH , HEIGHT - 1 , WIDTH - 1 , HEIGHT - 1 )
display . line ( WIDTH - 1 , 0 , WIDTH - 1 , HEIGHT - 1 )
# Uncomment this if a white background is wanted behind the company
# display.pen(15)
# display.rectangle(1, 1, TEXT_WIDTH, COMPANY_HEIGHT - 1)
# Draw the company
display . pen ( 15 ) # Change this to 0 if a white background is used
display . font ( " serif " )
display . thickness ( 3 )
display . text ( company , LEFT_PADDING , ( COMPANY_HEIGHT / / 2 ) + 1 , COMPANY_TEXT_SIZE )
# Draw a white background behind the name
display . pen ( 15 )
display . thickness ( 1 )
display . rectangle ( 1 , COMPANY_HEIGHT + 1 , TEXT_WIDTH , NAME_HEIGHT )
# Draw the name, scaling it based on the available width
display . pen ( 0 )
display . font ( " sans " )
display . thickness ( 4 )
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 , ( NAME_HEIGHT / / 2 ) + COMPANY_HEIGHT + 1 , name_size )
break
# Draw a white backgrounds behind the details
display . pen ( 15 )
display . thickness ( 1 )
display . rectangle ( 1 , HEIGHT - DETAILS_HEIGHT * 2 , TEXT_WIDTH , DETAILS_HEIGHT - 1 )
display . rectangle ( 1 , HEIGHT - DETAILS_HEIGHT , TEXT_WIDTH , DETAILS_HEIGHT - 1 )
# Draw the first detail's title and text
display . pen ( 0 )
display . font ( " sans " )
display . thickness ( 3 )
name_length = display . measure_text ( detail1_title , DETAILS_TEXT_SIZE )
display . text ( detail1_title , LEFT_PADDING , HEIGHT - ( ( DETAILS_HEIGHT * 3 ) / / 2 ) , DETAILS_TEXT_SIZE )
display . thickness ( 2 )
display . text ( detail1_text , 5 + name_length + DETAIL_SPACING , HEIGHT - ( ( DETAILS_HEIGHT * 3 ) / / 2 ) , DETAILS_TEXT_SIZE )
# Draw the second detail's title and text
display . thickness ( 3 )
name_length = display . measure_text ( detail2_title , DETAILS_TEXT_SIZE )
display . text ( detail2_title , LEFT_PADDING , HEIGHT - ( DETAILS_HEIGHT / / 2 ) , DETAILS_TEXT_SIZE )
display . thickness ( 2 )
display . text ( detail2_text , LEFT_PADDING + name_length + DETAIL_SPACING , HEIGHT - ( DETAILS_HEIGHT / / 2 ) , DETAILS_TEXT_SIZE )
# ------------------------------
# Program setup
# ------------------------------
# Global variables
show_overlay = False
# Create a new Badger and set it to update NORMAL
display = badger2040 . Badger2040 ( )
display . update_speed ( badger2040 . UPDATE_NORMAL )
try :
open ( " badge.txt " , " r " )
except OSError :
display . pen ( 15 )
display . clear ( )
draw_overlay ( " To run this Badge demo, make sure there is a badge.txt file on your MicroPython device. " , WIDTH - OVERLAY_BORDER , HEIGHT - OVERLAY_BORDER , OVERLAY_SPACING , OVERLAY_TEXT_SIZE )
display . update ( )
sys . exit ( )
# Open the badge file
badge = open ( " badge.txt " , " r " )
# Read in the next 6 lines
company = badge . readline ( ) # "mustelid inc"
name = badge . readline ( ) # "H. Badger"
detail1_title = badge . readline ( ) # "RP2040"
detail1_text = badge . readline ( ) # "2MB Flash"
detail2_title = badge . readline ( ) # "E ink"
detail2_text = badge . readline ( ) # "296x128px"
# Truncate all of the text (except for the name as that is scaled)
company = truncatestring ( company , COMPANY_TEXT_SIZE , TEXT_WIDTH )
detail1_title = truncatestring ( detail1_title , DETAILS_TEXT_SIZE , TEXT_WIDTH )
detail1_text = truncatestring ( detail1_text , DETAILS_TEXT_SIZE ,
TEXT_WIDTH - DETAIL_SPACING - display . measure_text ( detail1_title , DETAILS_TEXT_SIZE ) )
detail2_title = truncatestring ( detail2_title , DETAILS_TEXT_SIZE , TEXT_WIDTH )
detail2_text = truncatestring ( detail2_text , DETAILS_TEXT_SIZE ,
TEXT_WIDTH - DETAIL_SPACING - display . measure_text ( detail2_title , DETAILS_TEXT_SIZE ) )
# 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 )
# Button handling function
def button ( pin ) :
global show_overlay
if pin == button_a :
show_overlay = True
return
if pin == button_b :
show_overlay = True
return
if pin == button_c :
show_overlay = True
return
if pin == button_up :
show_overlay = True
return
if pin == button_down :
show_overlay = True
return
# Register the button handling function with the buttons
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 )
# ------------------------------
# Main program loop
# ------------------------------
draw_badge ( )
display . update ( )
while True :
if show_overlay :
draw_overlay ( " To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt " ,
WIDTH - OVERLAY_BORDER , HEIGHT - OVERLAY_BORDER , OVERLAY_SPACING , OVERLAY_TEXT_SIZE )
display . update ( )
time . sleep ( 4 )
draw_badge ( )
display . update ( )
show_overlay = False
time . sleep ( 0.1 )