Jack J. Beale

Jack J. BealeJack J. BealeJack J. Beale
Root
C.V.
Projects
  • C++ / Arduino
  • Python/Micro-Python
  • Robots/Drones
  • Photography Portfolio
Server Login

Jack J. Beale

Jack J. BealeJack J. BealeJack J. Beale
Root
C.V.
Projects
  • C++ / Arduino
  • Python/Micro-Python
  • Robots/Drones
  • Photography Portfolio
Server Login
More
  • Root
  • C.V.
  • Projects
    • C++ / Arduino
    • Python/Micro-Python
    • Robots/Drones
    • Photography Portfolio
  • Server Login
  • Sign In
  • Create Account

  • My Account
  • Signed in as:

  • filler@godaddy.com


  • My Account
  • Sign out


Signed in as:

filler@godaddy.com

  • Root
  • C.V.
  • Projects
    • C++ / Arduino
    • Python/Micro-Python
    • Robots/Drones
    • Photography Portfolio
  • Server Login

Account


  • My Account
  • Sign out


  • Sign In
  • My Account

Badger Config Files

Custom Code to be used on the Badger2040 E-ink platform by  Pimoroni 

Code includes:

Launcher Modifications

Custom QR codes for this website

Custom Badge for JBeale


*please note*

This code is meant to replace parts of the original Badger2040 code.

It will not work standalone - you will need to replace the original sections with the corresponding headings below.

Downloads

Badger Config Files (zip)Download

Code/Build

Download contains the Code Changes:

Badge.py:


import badger2040

import jpegdec



# Global Constants

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


COMPANY_TEXT_SIZE = 0.6

DETAILS_TEXT_SIZE = 0.5


LEFT_PADDING = 5

NAME_PADDING = 20

DETAIL_SPACING = 10


BADGE_PATH = "/badges/badge.txt"


DEFAULT_TEXT = """System 404

Jack Beale

me@jackbeale.com


/badges/badge.jpg

"""


# ------------------------------

#      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 the badge, including user text

def draw_badge():

    display.set_pen(0)

    display.clear()


    # Draw badge image

    jpeg.open_file(badge_image)

    jpeg.decode(WIDTH - IMAGE_WIDTH, 0)


    # Draw a border around the image

    display.set_pen(0)

    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.set_pen(15)

    # display.rectangle(1, 1, TEXT_WIDTH, COMPANY_HEIGHT - 1)


    # Draw the company

    display.set_pen(15)  # Change this to 0 if a white background is used

    display.set_font("serif")

    display.text(company, LEFT_PADDING, (COMPANY_HEIGHT // 2) + 1, WIDTH, COMPANY_TEXT_SIZE)


    # Draw a white background behind the name

    display.set_pen(15)

    display.rectangle(1, COMPANY_HEIGHT + 1, TEXT_WIDTH, NAME_HEIGHT)


    # Draw the name, scaling it based on the available width

    display.set_pen(0)

    display.set_font("sans")

    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, WIDTH, name_size)

            break


    # Draw a white backgrounds behind the details

    display.set_pen(15)

    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.set_pen(0)

    display.set_font("sans")

    name_length = display.measure_text(detail1_title, DETAILS_TEXT_SIZE)

    display.text(detail1_title, LEFT_PADDING, HEIGHT - ((DETAILS_HEIGHT * 3) // 2), WIDTH, DETAILS_TEXT_SIZE)

    display.text(detail1_text, 5 + name_length + DETAIL_SPACING, HEIGHT - ((DETAILS_HEIGHT * 3) // 2), WIDTH, DETAILS_TEXT_SIZE)


    # Draw the second detail's title and text

    name_length = display.measure_text(detail2_title, DETAILS_TEXT_SIZE)

    display.text(detail2_title, LEFT_PADDING, HEIGHT - (DETAILS_HEIGHT // 2), WIDTH, DETAILS_TEXT_SIZE)

    display.text(detail2_text, LEFT_PADDING + name_length + DETAIL_SPACING, HEIGHT - (DETAILS_HEIGHT // 2), WIDTH, DETAILS_TEXT_SIZE)


    display.update()



# ------------------------------

#        Program setup

# ------------------------------


# Create a new Badger and set it to update NORMAL

display = badger2040.Badger2040()

display.led(128)

display.set_update_speed(badger2040.UPDATE_NORMAL)

display.set_thickness(2)


jpeg = jpegdec.JPEG(display.display)


# Open the badge file

try:

    badge = open(BADGE_PATH, "r")

except OSError:

    with open(BADGE_PATH, "w") as f:

        f.write(DEFAULT_TEXT)

        f.flush()

    badge = open(BADGE_PATH, "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"

badge_image = badge.readline()    # /badges/badge.jpg


# 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))



# ------------------------------

#       Main program

# ------------------------------


draw_badge()


while True:

    # Sometimes a button press or hold will keep the system

    # powered *through* HALT, so latch the power back on.

    display.keepalive()


    # If on battery, halt the Badger to save power, it will wake up if any of the front buttons are pressed

    display.halt()

















qrgen.py:



import badger2040

import qrcode

import time

import os

import badger_os


# Check that the qrcodes directory exists, if not, make it

try:

    os.mkdir("/qrcodes")

except OSError:

    pass


# Check that there is a qrcode.txt, if not preload

try:

    text = open("/qrcodes/qrcode.txt", "r")

except OSError:

    text = open("/qrcodes/qrcode.txt", "w")

    if badger2040.is_wireless():

        text.write("""https://jackbeale.com

Jack Beale

* Senior Systems Specialist

* Data Center Engineer

* me@jackbeale.com

*


Scan this code to learn

more about me and what I do.


Loaded on BADGER 2040W

""")

    else:

        text.write("""https://jackbeale.com

Jack Beale

* Senior Systems Specialist

* Data Center Engineer

* me@jackbeale.com

* 


Scan this code to learn

more about me and what I do.


Loaded on BADGER 2040

""")

    text.flush()

    text.seek(0)


# Load all available QR Code Files

try:

    CODES = [f for f in os.listdir("/qrcodes") if f.endswith(".txt")]

    TOTAL_CODES = len(CODES)

except OSError:

    pass



print(f'There are {TOTAL_CODES} QR Codes available:')

for codename in CODES:

    print(f'File: {codename}')


display = badger2040.Badger2040()


code = qrcode.QRCode()


state = {

    "current_qr": 0

}



def measure_qr_code(size, code):

    w, h = code.get_size()

    module_size = int(size / w)

    return module_size * w, module_size



def draw_qr_code(ox, oy, size, code):

    size, module_size = measure_qr_code(size, code)

    display.set_pen(15)

    display.rectangle(ox, oy, size, size)

    display.set_pen(0)

    for x in range(size):

        for y in range(size):

            if code.get_module(x, y):

                display.rectangle(ox + x * module_size, oy + y * module_size, module_size, module_size)



def draw_qr_file(n):

    display.led(128)

    file = CODES[n]

    codetext = open("/qrcodes/{}".format(file), "r")


    lines = codetext.read().strip().split("\n")

    code_text = lines.pop(0)

    title_text = lines.pop(0)

    detail_text = lines


    # Clear the Display

    display.set_pen(15)  # Change this to 0 if a white background is used

    display.clear()

    display.set_pen(0)


    code.set_text(code_text)

    size, _ = measure_qr_code(128, code)

    left = top = int((badger2040.HEIGHT / 2) - (size / 2))

    draw_qr_code(left, top, 128, code)


    left = 128 + 5


    display.text(title_text, left, 20, badger2040.WIDTH, 2)


    top = 40

    for line in detail_text:

        display.text(line, left, top, badger2040.WIDTH, 1)

        top += 10


    if TOTAL_CODES > 1:

        for i in range(TOTAL_CODES):

            x = 286

            y = int((128 / 2) - (TOTAL_CODES * 10 / 2) + (i * 10))

            display.set_pen(0)

            display.rectangle(x, y, 8, 8)

            if state["current_qr"] != i:

                display.set_pen(15)

                display.rectangle(x + 1, y + 1, 6, 6)

    display.update()



badger_os.state_load("qrcodes", state)

changed = True


while True:

    # Sometimes a button press or hold will keep the system

    # powered *through* HALT, so latch the power back on.

    display.keepalive()


    if TOTAL_CODES > 1:

        if display.pressed(badger2040.BUTTON_UP):

            if state["current_qr"] > 0:

                state["current_qr"] -= 1

                changed = True


        if display.pressed(badger2040.BUTTON_DOWN):

            if state["current_qr"] < TOTAL_CODES - 1:

                state["current_qr"] += 1

                changed = True


    if display.pressed(badger2040.BUTTON_B) or display.pressed(badger2040.BUTTON_C):

        display.set_pen(15)

        display.clear()

        badger_os.warning(display, "To add QR codes, connect Badger 2040 W to a PC, load up Thonny, and add files to /qrcodes directory.")

        time.sleep(4)

        changed = True


    if changed:

        draw_qr_file(state["current_qr"])

        badger_os.state_save("qrcodes", state)

        changed = False


    # Halt the Badger to save power, it will wake up if any of the front buttons are pressed

    display.halt()




Copyright © 2025 Jack Jeremy Beale - All Rights Reserved.

  • Root
  • Contact Me
  • C.V.
  • Photography Portfolio

Powered by

This website uses cookies.

We use cookies to analyze website traffic and optimize your website experience. By accepting our use of cookies, your data will be aggregated with all other user data.

DeclineAccept