Import Libraries

The code first imports the libraries it needs. The terminalio library is used for the built-in terminal-style font. The adafruit_matrixportal library handles the matrix portal's graphics and networking.

import time
import board
from random import randrange
import terminalio
from adafruit_matrixportal.matrixportal import MatrixPortal

Data Setup

The next chunk of code configures the data source displayed by the Matrix Portal. You can access the Adafruit Learning System's public API endpoint to display data about new guides by navigating to https://learn.adafruit.com/api/guides/new.json?count=5.

This API is unique in that the URL contains a count parameter at the end of it. You can increase/decrease this number and see how many guides are loaded on the webpage:

https://learn.adafruit.com/api/guides/new.json?count=5

The code stores the number of guides to display using the DISPLAY_NUM_GUIDES variable. The DATA_SOURCE variable contains the the URL along with the number of guides to display. The TITLE_DATA_LOCATION is list of json traversals used to obtain the data we'll want.

Finally, a new matrixportal object is created using the DATA_SOURCE and TITLE_DATA_LOCATION.

# --- Data Setup --- #
# Number of guides to fetch and display from the Adafruit Learning System
DISPLAY_NUM_GUIDES = 5
# Data source URL
DATA_SOURCE = (
    "https://learn.adafruit.com/api/guides/new.json?count=%d" % DISPLAY_NUM_GUIDES
)
TITLE_DATA_LOCATION = ["guides"]
 
matrixportal = MatrixPortal(
    url=DATA_SOURCE,
    json_path=TITLE_DATA_LOCATION,
    status_neopixel=board.NEOPIXEL,
)

Display Setup

The scrolling text displaying guide names changes colors as it scrolls by. Colors are defined by the colors list. Then, the scrolling delay measured in seconds is defined as SCROLL_DELAY and the path for the custom font is also defined here.

# Colors for guide name
colors = [0xffa500, 0xffff00,
          0x008000, 0x0000ff, 0x4b0082,
          0xee82ee]

# Delay for scrolling the text
SCROLL_DELAY = 0.03

FONT = "/IBMPlexMono-Medium-24_jep.bdf"

The matrix portal library includes handy functions to make controlling the graphics on the Matrix Portal easy. The add_text function adds text labels to the Matrix Portal's display. You can also pass it settings including the label's font, position, color, and animation.

The first label displays the number of guides currently in the Adafruit Learning system and uses the custom font defined earlier in the code. The preload_font function is used to pre-load the glyphs used by the custom font so it doesn't need to be rendered each time. Since the code is only displaying the number of guides in the learning system, the code preloads all the possible numbers glyphs which could be displayed.

The second label displays the learn guide title. Since this text label scrolls, the scrolling parameter is set to True.

# Learn guide count (ID = 0)
matrixportal.add_text(
    text_font=FONT,
    text_position=((matrixportal.graphics.display.width // 12) - 1, (matrixportal.graphics.display.height // 2) - 4),
    text_color=0x800000,
)
matrixportal.preload_font("0123456789")

# Learn guide title (ID = 1)
matrixportal.add_text(
    text_font=terminalio.FONT,
    text_position=(2, 25),
    text_color=0x000080,
    scrolling = True
)

Main Loop

Every 15 minutes, the code fetches the time from the Adafruit IO Server. If a new hour is elapsed, the DATA_SOURCE is queried and the resulting JSON data blob is stored into the als_data variable. Instead of fetching and parsing the URL it each time we want to display data, the code uses the als_data variable as a simple way of caching the data from the learning system API. We also update the prv_hour variable to reflect the numerical value of the new hour.

while True:
    if (not refresh_time) or (time.monotonic() - refresh_time) > 900:
        try:
            print("obtaining time from adafruit.io server...")
            matrixportal.get_local_time()
            refresh_time = time.monotonic()
        except RuntimeError as e:
            print("Unable to obtain time from Adafruit IO, retrying - ", e)
            continue

    if time.localtime()[3] != prv_hour:
        print("New Hour, fetching new data...")
        # Fetch and store guide info response
        als_data = matrixportal.network.fetch(DATA_SOURCE)
        prv_hour = time.localtime()[3]

The next chunk of code cycles through the data returned by the Adafruit Learning System API. A call to get_guide_info is made using the current guide number.

# Cycle through guides retrieved
    if guide_idx < DISPLAY_NUM_GUIDES:
        get_guide_info(guide_idx)

The get_guide_info method parses the JSON data returned by the DATA_SOURCE to obtain the number of guides and current guide title. Then, it sets up the text labels and displays them on the Matrix Portal.

def get_guide_info(index):
    """Parses JSON data returned by the DATA_SOURCE
    to obtain the ALS guide title and number of guides and
    sets the text labels.
    :param int index: Guide index to display

    """
    if index > DISPLAY_NUM_GUIDES:
        raise RuntimeError("Provided index may not be larger than DISPLAY_NUM_GUIDES.")
    print("Obtaining guide info for guide %d..."%index)

    # Traverse JSON data for title
    guide_count = matrixportal.network.json_traverse(als_data.json(), ["guide_count"])
    
    # Set guide count
    matrixportal.set_text(guide_count, 0)

    # Reset prv_num_guides to the current guide count
    prv_num_guides = guide_count

    guides = matrixportal.network.json_traverse(als_data.json(), TITLE_DATA_LOCATION)
    guide_title = guides[index]["guide"]["title"]
    print("Guide Title", guide_title)
    
    # Select color for title text
    color_index = randrange(0, len(colors))

    # Set the title text color
    matrixportal.set_text_color(colors[color_index], 1)

    # Set the title text
    matrixportal.set_text(guide_title, 1)

Back in the main loop, the code scrolls the scrollable text label and increments the guide index.

# Scroll the scrollable text blocks
        matrixportal.scroll_text(SCROLL_DELAY)
        guide_idx += 1
    else:
        guide_idx = 0
    time.sleep(0.05)

This guide was first published on Oct 28, 2020. It was last updated on Oct 28, 2020.

This page (Code Walkthrough) was last updated on Oct 26, 2020.

Text editor powered by tinymce.