Installing 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 PyPortal_Quotes/ 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 look similar to the following image:

CIRCUITPY
# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

import time
import board
from adafruit_pyportal import PyPortal

# Set up where we'll be fetching data from
DATA_SOURCE = "https://www.adafruit.com/api/quotes.php"
QUOTE_LOCATION = [0, 'text']
AUTHOR_LOCATION = [0, 'author']

# the current working directory (where this file is)
cwd = ("/"+__file__).rsplit('/', 1)[0]
pyportal = PyPortal(url=DATA_SOURCE,
                    json_path=(QUOTE_LOCATION, AUTHOR_LOCATION),
                    status_neopixel=board.NEOPIXEL,
                    default_bg=cwd+"/quote_background.bmp",
                    text_font=cwd+"/fonts/Arial-ItalicMT-17.bdf",
                    text_position=((20, 120),  # quote location
                                   (5, 210)), # author location
                    text_color=(0xFFFFFF,  # quote text color
                                0x8080FF), # author text color
                    text_wrap=(35, # characters to wrap for quote
                               0), # no wrap for author
                    text_maxlen=(180, 30), # max text size for quote & author
                   )

# speed up projects with lots of text by preloading the font!
pyportal.preload_font()

while True:
    try:
        value = pyportal.fetch()
        print("Response is", value)
    except (ValueError, RuntimeError, ConnectionError, OSError) as e:
        print("Some error occured, retrying! -", e)
    time.sleep(60)
If you run into any errors, such as "ImportError: no module named `adafruit_display_text.label`" be sure to update your libraries to the latest release bundle!

How It Works

The PyPortal Quote Board is doing a couple of nifty things to deliver your delightful quote-y experience!

Background

First, it displays a bitmap graphic as the screen's background. This is a 320 x 240 pixel RGB 16-bit raster graphic in .bmp format.

Font

Then, it displays a quote and the author's name as text created with bitmapped fonts to overlay on top of the background. The font used here is a bitmap font made from an oblique Arial typeface. You can learn more about converting type in this guide.

JSON

The neat part is that the text is not coming from a file on the device, but rather it is grabbed from a website!

Adafruit.com has a PHP script at the adafruit.com/api/quotes.php page. Each time it is requested, it returns a new quote from a large database of quotes.

In fact, you can run the same query the PyPortal does to see the results. Copy and paste this link: https://www.adafruit.com/api/quotes.php

into your browser and you'll see a result like this:

[
  {
    "text": "Science, my lad, is made up of mistakes, but they are mistakes which it is useful to make, because they lead little by little to the truth",
    "author": "Jules Verne"
  }
]

That result is the quote formatted as a JSON (JavaScript Object Notation) array. It is comprised of a single element with two keys: text and author.

  • The value of the text key is Science, my lad, is made up of mistakes, but they are mistakes which it is useful to make, because they lead little by little to the truth
  • The value of the author key is Jules Verne

Since this JSON object has a consistent way to return the results to us, the code we're running on the PyPortal can easily parse the data and display it!

You can see how it's done in this part of code.py:

# Set up where we'll be fetching data from
DATA_SOURCE = "https://www.adafruit.com/api/quotes.php"
QUOTE_LOCATION = [0, 'text']
AUTHOR_LOCATION = [0, 'author']

Then, in the pyportal query we ask for the text and author name from that URL, and then use the text_ arguments to set the font, position, color, wrap, and maxlen of the text when it is displayed.

pyportal = PyPortal(url=DATA_SOURCE,
                    json_path=(QUOTE_LOCATION, AUTHOR_LOCATION),
                    status_neopixel=board.NEOPIXEL,
                    default_bg=cwd+"quote_background.bmp",
                    text_font=cwd+"fonts/Arial-ItalicMT-17.bdf",
                    text_position=((20, 40),  # quote location
                                   (5, 190)), # author location
                    text_color=(0xFFFFFF,  # quote text color
                                0x8080FF), # author text color
                    text_wrap=(35, # characters to wrap for quote
                               0), # no wrap for author
                    text_maxlen=(180, 30), # max text size for quote & author
                    )

With all of this prepared, during the main loop of while True: the code will query the Adafruit quotes page for the JSON data, and display it, and then wait one minute until repeating the process.

Want your quotes to update more quickly or slowly? Simply change the number of seconds specified in the time.sleep() line.

Now, you can test out the program and once it connects to your WiFi, it'll will pull in a quote!

Next, we'll make and enclosure for the PyPortal Quote Book.

This guide was first published on Feb 27, 2019. It was last updated on 2023-12-06 00:12:15 -0500.

This page (Code PyPortal with CircuitPython) was last updated on Dec 05, 2023.

Text editor powered by tinymce.