Once you've finished setting up your Matrix Portal S3 with CircuitPython and have connected to the Internet, you can download the Project Bundle to access the code and necessary libraries.
To do this, click the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: Copyright (c) 2024 Trevor Beaton for Adafruit Industries # # SPDX-License-Identifier: MIT import time import board import terminalio import displayio from adafruit_matrixportal.matrixportal import MatrixPortal from adafruit_display_text import label # --- Display setup --- matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL, debug=True, width=64, height=64) # Use the built-in font font = terminalio.FONT # Define colors ORANGE = 0xFFA500 WHITE = 0xFFFFFF RED = 0xFF0000 # Create a Group to hold all the text areas and the heart group = displayio.Group() # Create a small heart bitmap heart_bitmap = displayio.Bitmap(7, 7, 2) heart_palette = displayio.Palette(2) heart_palette[0] = 0x000000 # Black (transparent) heart_palette[1] = RED # Red heart # Draw the heart heart_pixels = [ 0,1,1,0,1,1,0, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 0,1,1,1,1,1,0, 0,0,1,1,1,0,0, 0,0,0,1,0,0,0, ] for heart_idx, pixel in enumerate(heart_pixels): heart_bitmap[heart_idx % 7, heart_idx // 7] = pixel # Create a TileGrid using the heart bitmap and palette heart_tile = displayio.TileGrid(heart_bitmap, pixel_shader=heart_palette, x=56, y=1) group.append(heart_tile) # Add text labels for titles and values for label_idx in range(3): # Title title_label = label.Label(font, text="", color=ORANGE, x=2, y=7 + label_idx*21) group.append(title_label) # Value value_label = label.Label(font, text="", color=WHITE, x=2, y=17 + label_idx*21) group.append(value_label) # Add the group to the display matrixportal.display.show(group) # Define feed keys for your data TITLES = ["STEPS", "WORKOUTS", "MILES"] VALUE_FEEDS = ["stepcount", "numofworkouts", "distance"] UPDATE_DELAY = 1800 # Update every 30 minutes def get_feed_data(feed_key): try: data = matrixportal.get_io_data(feed_key) if data: return data[0]["value"] except (ValueError, RuntimeError) as feed_error: print(f"Error fetching data from feed {feed_key}: {feed_error}") return None def update_display(): for display_idx, (title, value_feed) in enumerate(zip(TITLES, VALUE_FEEDS)): value = get_feed_data(value_feed) or "N/A" group[display_idx*2 + 1].text = title # Update title group[display_idx*2 + 2].text = str(value) # Update value # Initial display update update_display() # Main loop while True: try: time.sleep(UPDATE_DELAY) update_display() except (ValueError, RuntimeError) as loop_error: print("Some error occurred, retrying! -", loop_error) continue
Upload the Code and Libraries
After downloading the Project Bundle, plug your Matrix Portal S3 into the computer's USB port with a known good USB data + power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the CIRCUITPY drive.
- lib folder
- Images folder
- code.py
The CIRCUITPY drive should look like this after copying the lib folder, images folder, and the code.py file.
Display Setup
This line initializes the MatrixPortal with a 64x64 LED matrix. The status_neopixel
parameter allows for using the onboard NeoPixel for status indication. The width
and height
sets the parameters for the display.
matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL, debug=True, width=64, height=64)
Adding Text Labels
This loop creates three pairs of labels: one pair each for steps, workouts, and miles. Each pair has a title label (in orange) and a value label (in white).
for label_idx in range(3): title_label = label.Label(font, text="", color=ORANGE, x=2, y=7 + label_idx*21) group.append(title_label) value_label = label.Label(font, text="", color=WHITE, x=2, y=17 + label_idx*21) group.append(value_label)
Fetching Data
This function attempts to retrieve the latest value from a specified Adafruit IO feed. It uses the Using matrixportal.get_io_data
returns a list of data points.
def get_feed_data(feed_key): try: data = matrixportal.get_io_data(feed_key) if data: return data[0]["value"] except (ValueError, RuntimeError) as feed_error: print(f"Error fetching data from feed {feed_key}: {feed_error}") return None
Updating the Display
This function updates the display with new data for each fitness metric. It iterates through the TITLES
and VALUE_FEEDS
lists using zip()
.
def update_display(): for display_idx, (title, value_feed) in enumerate(zip(TITLES, VALUE_FEEDS)): value = get_feed_data(value_feed) or "N/A" group[display_idx*2 + 1].text = title # Update title group[display_idx*2 + 2].text = str(value) # Update value
Main loop
The main loop runs, updating the display every 30 minutes (1800 seconds, as defined by UPDATE_DELAY
). If an error occurs during the update process, it's caught, printed, and the loop continues, ensuring the program doesn't crash due to temporary issues like network problems.
while True: try: time.sleep(UPDATE_DELAY) update_display() except (ValueError, RuntimeError) as loop_error: print("Some error occurred, retrying! -", loop_error) continue
Page last edited February 24, 2025
Text editor powered by tinymce.