adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.09k stars 1.21k forks source link

MatrixPortal and displayio, changing brightness causes font rendering issues #3664

Closed MadMaxMcKinney closed 3 years ago

MadMaxMcKinney commented 3 years ago

I'm currently working on my first circuitpython project, a 'busy light' that I'm hanging in front of my office. I'm using the resources from the latest Adafruit box which is a MatrixPortal and supporting hardware (like a 64x32 led matrix).

I wanted to give the system control via adafruit.io to turn the display on and off remotely. The closet solution I could find was to turn the brightness to 0. However my issues is that the font renders incorrectly once I turn the brightness back to 1. I have no idea how to fix this, I don't even know what is going wrong to google the right questions. I would really love some insight into this problem and how I could fix it.

Example images:

Before: IMG_6254

After: IMG_6253

My code:


import time
import random
import board
import terminalio
import displayio
from digitalio import DigitalInOut, Direction, Pull
from adafruit_matrixportal.matrixportal import MatrixPortal
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text.label import Label
from adafruit_display_shapes.rect import Rect
from adafruit_matrixportal.network import Network

# --- Vars
UPDATE_DELAY = 5
IS_BUSY = True
IS_DIMMED = False
# ---

# --- Display setup ---
matrixportal = MatrixPortal(status_neopixel=board.NEOPIXEL, debug=True)
display = matrixportal.display

# Create group to hold content
group = displayio.Group()

# --- Content ---
# Background object
background = Rect(0,0,64,32, fill=0x000000)
group.append(background)

# Create status label (with a default y spacing for the 'connecting' text
font = bitmap_font.load_font("/IBMPlexMono-Medium-24_jep.bdf")
status_label = Label(font,y=14, max_glyphs=20)
# Default text show as connecting, once the internet connection has happened it will resume the code flow and update the text
status_label.text = "..."

group.append(status_label)

# ---

# Add group to display
display.show(group)

def update_bg():
    # Pop the background off the bottom of the stack
    background = group.pop(0)

    # Change the background color of the background
    if IS_BUSY:
        background.fill = 0xFF0000
    else:
        background.fill = 0x00FF00
    # Insert the modified background back at the bottom of the stack
    group.insert(0, background)

def update_text():
    # Set status text
    status_label.text = "BUSY" if IS_BUSY else "FREE"

    # Set status text position
    # Get the bouding box info from the label component so we can center it. I subtract 1 from the final value to offset it due to the custom font sizing.
    bbx, bby, bbwidth, bbh = status_label.bounding_box
    status_label.x = round((display.width / 2 - bbwidth / 2) - 1)
    status_label.y = display.height // 2

def fetch_updates():
    print("Fetching status...")

    # Returns a JSON object as a python dict object from the selected AdafruitIO feed
    meetingFeed = matrixportal.get_io_feed("redacted")
    meetingValue = meetingFeed['last_value']

    isDimmedFeed = matrixportal.get_io_feed("redacted")
    isDimmedValue = isDimmedFeed['last_value']

    # Update the value with the converted string
    global IS_BUSY
    IS_BUSY = str_to_bool(meetingValue)

    global IS_DIMMED
    IS_DIMMED = str_to_bool(isDimmedValue)

def update_screen():
    fetch_updates()
    update_bg()
    update_text()

def str_to_bool(s):
    if s == 'True':
         return True
    elif s == 'False':
         return False
    else:
         raise ValueError # evil ValueError that doesn't tell you what the wrong value was

# Initial update
update_screen()
last_update = time.monotonic()

while True:

    # Brightness checking
    if IS_DIMMED:
        display.brightness = 0
    else:
        display.brightness = 1

    # Status checking interval
    if time.monotonic() > last_update + UPDATE_DELAY:

        update_screen()

        last_update = time.monotonic()
jepler commented 3 years ago

Hi and thank you for your report. The only extra piece of info that would have been nice was the specific CircuitPython version you were using.

This was a bug in the underlying library that enables RGBMatrix to work. They've fixed the bug, but unfortunately we haven't upgraded to the fixed version and it looks like we will miss doing this before the release of 6.0.0 stable.

For now, you can create an empty Group object and show() it when you want to blank the screen, then show() your normal group when you want to display your text.

MadMaxMcKinney commented 3 years ago

@jepler Thanks for the feedback, I'll try that solution. I was using CircuitPython 6.0.0-rc.1 for reference. Sounds like I should see that bug fixed in a release after 6.0 stable?

tannewt commented 3 years ago

@MaxMcKinney Yup! It should be fixed in 6.0.0-rc2 or 6.0.0 when we release it.