Libraries
We'll need to make sure we have these libraries installed. (Check out this link on installing libraries if needed.)
- adafruit_bitmap_font
- adafruit_bus_device
- adafruit_display_text
- adafruit_esp32spi
- adafruit_io
- adafruit_matrixportal
- adafruit_requests.mpy
- neopixel.mpy
Connect to the Internet
Once you have CircuitPython setup and libraries installed we can get your board connected to the Internet. The process for connecting can be found here.
Text Editor
Adafruit recommends using the Mu editor for editing your CircuitPython code. You can get more info in this guide.
Alternatively, you can use any text editor that saves simple text files.
Code
Click the Download: Zip File link below in the code window to get a zip file with all the files needed for the project. Copy code.py from the zip file and place it on the CIRCUITPY drive.
# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries # # SPDX-License-Identifier: MIT # Quote board matrix display # uses AdafruitIO to serve up a quote text feed and color feed # random quotes are displayed, updates periodically to look for new quotes # avoids repeating the same quote twice in a row import time import random import board import terminalio from adafruit_matrixportal.matrixportal import MatrixPortal # --- Display setup --- matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL, debug=True) # Create a new label with the color and text selected matrixportal.add_text( text_font=terminalio.FONT, text_position=(0, (matrixportal.graphics.display.height // 2) - 1), scrolling=True, ) # Static 'Connecting' Text matrixportal.add_text( text_font=terminalio.FONT, text_position=(2, (matrixportal.graphics.display.height // 2) - 1), ) QUOTES_FEED = "sign-quotes.signtext" COLORS_FEED = "sign-quotes.signcolor" SCROLL_DELAY = 0.02 UPDATE_DELAY = 600 quotes = [] colors = [] last_color = None last_quote = None def update_data(): print("Updating data from Adafruit IO") matrixportal.set_text("Connecting", 1) try: quotes_data = matrixportal.get_io_data(QUOTES_FEED) quotes.clear() for json_data in quotes_data: quotes.append(matrixportal.network.json_traverse(json_data, ["value"])) print(quotes) # pylint: disable=broad-except except Exception as error: print(error) try: color_data = matrixportal.get_io_data(COLORS_FEED) colors.clear() for json_data in color_data: colors.append(matrixportal.network.json_traverse(json_data, ["value"])) print(colors) # pylint: disable=broad-except except Exception as error: print(error) if not quotes or not colors: raise RuntimeError("Please add at least one quote and color to your feeds") matrixportal.set_text(" ", 1) update_data() last_update = time.monotonic() matrixportal.set_text(" ", 1) quote_index = None color_index = None while True: # Choose a random quote from quotes if len(quotes) > 1 and last_quote is not None: while quote_index == last_quote: quote_index = random.randrange(0, len(quotes)) else: quote_index = random.randrange(0, len(quotes)) last_quote = quote_index # Choose a random color from colors if len(colors) > 1 and last_color is not None: while color_index == last_color: color_index = random.randrange(0, len(colors)) else: color_index = random.randrange(0, len(colors)) last_color = color_index # Set the quote text matrixportal.set_text(quotes[quote_index]) # Set the text color matrixportal.set_text_color(colors[color_index]) # Scroll it matrixportal.scroll_text(SCROLL_DELAY) if time.monotonic() > last_update + UPDATE_DELAY: update_data() last_update = time.monotonic()
Adafruit IO Setup
Our project will use Adafruit IO to serve up a feed of quotes and colors. Adafruit IO is absolutely free to use, but you'll need to log in with your Adafruit account to use it. If you don't already have an Adafruit login, create one here.
If you haven't used Adafruit IO before, check out this guide for more info.
Once you have logged into your account, there are two pieces of information you'll need to place in your secrets.py file: Adafruit IO username, and Adafruit IO key. Head to io.adafruit.com and simply click the View AIO Key link on the left hand side of the Adafruit IO page to get this information.
Then, add them to the secrets.py file like this:
secrets = { 'ssid' : 'your_wifi_ssid', 'password' : 'your_wifi_password', 'aio_username' : '_your_aio_username_', 'aio_key' : '_your_big_huge_super_long_aio_key_' }
Problems Getting Quotes
If you have any problems getting the data to display correctly, check that the secrets.py file has the information noted above.
Adafruit IO Group, Feeds, Dashboard
Next, we'll create the necessary Adafruit IO Group, Feeds, and Dashboard to host our quotes and colors.
First, if you're new to Adafruit IO, take a look at this excellent guide on getting started.
Next, we'll create a Group that will contain our two Feeds.
Group Creation
In the Feeds screen click on the Actions menu and then pick Create a New Group from the dropdown menu.
Feed Creation
In the Feeds screen click on the Actions menu and then pick Create a New Feed from the dropdown menu.
Name this feed signcolor, and select Sign Quotes from the Add to groups field, then click Create.
Repeat this process a second time to make a new Feed called signtext.
Dashboard Creation
Now that we have the two feeds we need, let's create a Dashboard with a couple of UI block elements that will make it easy to add data points to our two feeds.
From the Dashboards page, click the Actions dropdown menu and select Create a New Dashboard.
Name the Dashboard as Quotes and then click Create.
Click on the create a new block + sign in the Dashboard page, this will present you with a number of UI element block options.
Pick the Text block.
From the Chose feed pop-up window that appears, chose the signtext feed, then click Next step.
In the Block settings popup window, give the block the title Text quote, then click Update block.
Repeat this process to create a Color picker block, assigning it to the signcolor feed.
Create Quotes
Now, you can pick a few different colors with the color picker to add to your arsenal of sign text colors.
Type in text in the text block to add quotes to your feed.
If you ever decide you don't want one of the colors or quotes, simply head to the relevant feed and click the red 'x' to remove a data point!
import time import random import board import terminalio from adafruit_matrixportal.matrixportal import MatrixPortal
Next, the Display is set up using the matrixportal
object. We also create text label objects:
# --- Display setup --- matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL, debug=True) # Create a new label with the color and text selected matrixportal.add_text( text_font=terminalio.FONT, text_position=(0, (matrixportal.graphics.display.height // 2) - 1), scrolling=True, ) # Static 'Connecting' Text matrixportal.add_text( text_font=terminalio.FONT, text_position=(2, (matrixportal.graphics.display.height // 2) - 1), )
Feed Variables
In order to use the feed data, we need a couple of variables to help traverse the AIO json data.
We also create variables for the scroll speed and update time.
QUOTES_FEED = "sign-quotes.signtext" COLORS_FEED = "sign-quotes.signcolor" SCROLL_DELAY = 0.02 UPDATE_DELAY = 600 quotes = [] colors = [] last_color = None last_quote = None
Update Data
The update_data()
function is created to handle the quote feed and color feed data queries. This will be the key function that is run each time the code checks for new quotes and colors.
def update_data(): print("Updating data from Adafruit IO") matrixportal.set_text("Connecting", 1) try: quotes_data = matrixportal.get_io_data(QUOTES_FEED) quotes.clear() for json_data in quotes_data: quotes.append(matrixportal.network.json_traverse(json_data, ["value"])) print(quotes) # pylint: disable=broad-except except Exception as error: print(error) try: color_data = matrixportal.get_io_data(COLORS_FEED) colors.clear() for json_data in color_data: colors.append(matrixportal.network.json_traverse(json_data, ["value"])) print(colors) # pylint: disable=broad-except except Exception as error: print(error) if not quotes or not colors: raise "Please add at least one quote and color to your feeds" matrixportal.set_text(" ", 1)
This is run as soon as the function has been defined, so that we now have a list of quotes and colors to work with.
Main Loop
In the main loop of the code, a random quote is selected from the list that has been returned by the update_data()
function. This includes a while
loop that ensures we don't get the same quote or color twice in a row!
# Choose a random quote from quotes if len(quotes) > 1 and last_quote is not None: while quote_index == last_quote: quote_index = random.randrange(0, len(quotes)) else: quote_index = random.randrange(0, len(quotes)) last_quote = quote_index # Choose a random color from colors if len(colors) > 1 and last_color is not None: while color_index == last_color: color_index = random.randrange(0, len(colors)) else: color_index = random.randrange(0, len(colors)) last_color = color_index
Display the Quote
Now, the randomly selected quote is displayed using the matrixportal.set_text()
and matrixportal.set_text_color()
commands, and the text is scrolled using matrixportal.scroll_text()
.
# Set the quote text matrixportal.set_text(quotes[quote_index]) # Set the text color matrixportal.set_text_color(colors[color_index]) # Scroll it matrixportal.scroll_text(SCROLL_DELAY)
Update Time
After ten minutes, the code will go and fetch the quotes and colors from the AIO feeds anew, in case anything has changed.
if time.monotonic() > last_update + UPDATE_DELAY: update_data() last_update = time.monotonic()
Text editor powered by tinymce.