The files for this project just barely fit on the MagTag. To make sure you have enough space, you'll have to clear the MagTag filesystem which requires you to enter the REPL over a serial console. To do that, read through the three pages linked below.

Now that you have done that, enter the following two lines and it will erase all the files on your MagTag.

import storage
storage.erase_filesystem()

Installing the Project Code

To use with CircuitPython, you need to first install a few libraries, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.

Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory MagTag_Project_Selector/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.

Your CIRCUITPY drive should now contain the following files and directories:

CIRCUITPY
# SPDX-FileCopyrightText: 2020 Eva Herrada for Adafruit Industries
#
# SPDX-License-Identifier: MIT

# 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

projects = [
    "weather",
    "spacex",
    "covid",
    "showerthoughts",
    "tides",
    "year",
    "showtimes",
    "slideshow",
]

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

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

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)

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

btnA.deinit()
btnB.deinit()
btnC.deinit()
btnD.deinit()

print("Starting ", projects[int(alarm.sleep_memory[0])])
__import__("/projects/" + projects[int(alarm.sleep_memory[0])])

At this point, I would recommend going through the other guides that this project makes use of, which are linked below. For most of the projects, you can copy all of their contents to the CIRCUITPY drive. However, for the MagTag Progress Displays guide, only the epilogue18.bdf font and year_progress_percent.py should be copied over.

All the .py files for the individual projects need to be put in a new directory on the CIRCUITPY drive named projects/ and renamed

As far as the secrets.py file goes, one with all the necessary fields has been included in the project zip that you can just fill out as you go through each guide.

Be sure you have the libraries and secrets.py file complete and loaded onto the CIRCUITPY drive also or the code will not run properly.

Code Behavior

So, now that everything's all set up, it'd probably be a good idea to actually know how to use it. Basically, when the MagTag restarts or resets (from the slide switch, reset button, or through the serial terminal), you've got the option of going into a simple UI that will let you choose a project to load. You can enter this UI by pressing any of the four buttons when the MagTag is reloading and holding it down until the screen shows eight boxes with little pictures inside them. 

Once you're in the UI, use the four buttons to navigate it. Each button has an arrow on it, and pressing that button will move the cursor one square in that direction. Once the cursor (a black outline on the selected picture) is on the project you want, press and hold both the first and last buttons for five seconds. The MagTag can only update the screen once every five seconds, so keep that in mind while navigating the UI.

If you don't press a button when the code is restarting, it will automatically run the last run project. However, due to the constraints of the alarm library used to accomplish this, it only works during a soft reset (i.e. through the REPL or automatically) and not when the RESET button is pressed or the slide switch is turned off and on. If there isn't one, it will choose the first project and run that one.

This guide was first published on Dec 30, 2020. It was last updated on Jul 20, 2024.

This page (Code the MagTag Project Selector) was last updated on Jul 20, 2024.

Text editor powered by tinymce.