First, the code imports the required libraries.
# Based on code written by @DavidGlaude on Twitter # https://twitter.com/DavidGlaude/status/1340365817138044933 # https://gist.github.com/dglaude/4bf8d0a13c9c8ca8b05d6c0e9176bd20 import time import alarm import displayio import board import adafruit_imageload from adafruit_display_shapes.rect import Rect from adafruit_magtag.magtag import Graphics from digitalio import DigitalInOut, Direction, Pull
Next, a list of the projects to choose from is declared. The names in this list should match the name of the .bmp
used in the selection screen and the .py
file in the projects/ directory, so weather
has /bmps/weather.bmp and /projects/weather.py.
projects = [ "weather", "spacex", "covid", "showerthoughts", "tides", "year", "showtimes", "slideshow", ]
Then, the four buttons that will be used to navigate the UI are initialized.
btnA = DigitalInOut(board.D15) btnA.direction = Direction.INPUT btnA.pull = Pull.UP btnB = DigitalInOut(board.D14) btnB.direction = Direction.INPUT btnB.pull = Pull.UP btnC = DigitalInOut(board.D12) btnC.direction = Direction.INPUT btnC.pull = Pull.UP btnD = DigitalInOut(board.D11) btnD.direction = Direction.INPUT btnD.pull = Pull.UP
After that, the display is set up and the code checks to see if any buttons are pressed down. If any of them are, that means that the code will let the user choose a project to load. If none of them are, then the most recently loaded project will be loaded (if no project has been previously loaded, it defaults to the first one).
graphics = Graphics(auto_refresh=False) display = graphics.display group = displayio.Group() selector = False if not btnA.value or not btnB.value or not btnC.value or not btnD.value: selector = True
The code now checks to see if it should run the UI to let the user select the project to load. If it should, it then sets up the display with a white background and all the background images.
The MagTag is rather particular about what bmps it supports, so if you want to make your own bmps, click the link below. Just remember that for the MagTag, you need to use 8-bit indexed color.
The colors that I used are: 0x000000, 0xb1afad, 0x70696b, and 0xffffff
if selector: background = Rect(0, 0, 296, 128, fill=0xFFFFFF) group.append(background) for i in range(8): sprite_sheet, palette = adafruit_imageload.load( f"/bmps/{projects[i]}.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette, ) sprite = displayio.TileGrid( sprite_sheet, pixel_shader=palette, width=1, height=1, tile_width=62, tile_height=54, x=6 + 74 * (i % 4), y=6 + 62 * (i // 4), ) group.append(sprite)
Before the main loop is started, there's still some more display setup to do. A hollow rectangle is added that will be used as a sort of cursor to show what project is currently selected, and then the whole display group is displayed. The code then waits a few seconds and sets selected
, which is used to track the currently selected project, to 0
.
[...] rect = Rect(4, 4, 66, 58, outline=0x000000, stroke=2) group.append(rect) display.root_group = group display.refresh() time.sleep(5) print("Ready") selected = 0
The code now enters the main loop. It first checks if the first and last buttons are selected. If they are, it makes the first item in alarm.sleep_memory
the selected
variable. If another button is selected, it moves the cursor rectangle in the direction indicated by the arrows on the MagTag buttons (first is left, second is up, third is down, fourth is right), refreshes the display, and changes the selected
variable to reflect where the cursor is.
[...] while True: if not btnA.value and not btnD.value: alarm.sleep_memory[0] = selected break if not btnA.value and selected != 0 and selected != 4: selected -= 1 rect.x -= 74 display.refresh() print("left") time.sleep(5) continue if not btnB.value and selected > 3: selected -= 4 rect.y -= 62 display.refresh() print("up") time.sleep(5) continue if not btnC.value and selected < 4: selected += 4 rect.y += 62 display.refresh() print("down") time.sleep(5) continue if not btnD.value and selected != 3 and selected != 7: selected += 1 rect.x += 74 display.refresh() print("right") time.sleep(5) continue
Now that the main loop is done, the buttons can be deinitialized so that they don't conflict with any buttons used in the chosen project.
btnA.deinit() btnB.deinit() btnC.deinit() btnD.deinit()
Finally, the first item in alarm.sleep_memory
is used as an index of the projects
list to get the project to import. When something is imported like at the top of this file, it is usually a class, so it usually doesn't run anything but imports until it is initialized. In this case, a script is being imported so it is run just like if it was code.py
or if it was run with python file.py
on a computer.
print("Starting ", projects[int(alarm.sleep_memory[0])]) __import__("/projects/" + projects[int(alarm.sleep_memory[0])])
Page last edited March 08, 2024
Text editor powered by tinymce.