Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitmap Label does not update using displayio #45

Open
EAGrahamJr opened this issue Jul 11, 2024 · 2 comments
Open

Bitmap Label does not update using displayio #45

EAGrahamJr opened this issue Jul 11, 2024 · 2 comments

Comments

@EAGrahamJr
Copy link
Contributor

EAGrahamJr commented Jul 11, 2024

The following code (supplied by todbot on Discord and modified) shows that the bitmap_label does not update (or very slowly/sporadically) while the "regular" version flies.

import time, board,  displayio, i2cdisplaybus, terminalio
import adafruit_displayio_ssd1306

# Select one to run
# from adafruit_display_text import bitmap_label as label
from adafruit_display_text import label as label

displayio.release_displays()
dw,dh = 128, 32

i2c = board.I2C()
display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=dw, height=dh)
display.wake()

maingroup = displayio.Group()
display.root_group = maingroup
text1 = label.Label(terminalio.FONT, text="helloworld...", x=0, y=4)
text2 = label.Label(terminalio.FONT, text="@edgjr       ", x=0, y=19)

for t in (text1, text2):
    maingroup.append(t)

while True:
    try:
        text2.text = "%.1f" % time.monotonic()
        time.sleep(0.1)
    except KeyboardInterrupt:
        break

display.sleep()

Tested on Raspberry Pi Zero W, bookworm 32-bit

requirements.txt

The expectation is that the behavior should be similar. I do not know if this behavior is present on other displays like this since this is the only one I have at the moment 😃

@EAGrahamJr
Copy link
Contributor Author

NOTE This is not reproducible using "plain ol'" CP -- I put the same SSD1306 display on an RP2040 via the STEMMA port with the following packages:

Found device at /media/edgjr/CIRCUITPY, running CircuitPython 9.1.0.
adafruit_displayio_ssd1306==2.0.2
adafruit_framebuf==1.6.5
adafruit_ticks==1.0.13
adafruit_bus_device==5.2.9
adafruit_bitmap_font==2.1.2
adafruit_display_text==3.1.2

This suggests to me that the issue lies in the Blinka implementation of the bitmap_label.

@FoamyGuy
Copy link
Contributor

Thanks for reporting @EAGrahamJr. This is an odd one. I confirmed the noted behavior and made a reproducer that draws both types on the screen and attempts to update both but only works for label, bitmap_label stays static.

This suggests to me that the issue lies in the Blinka implementation of the bitmap_label.

Blinka and core displayio both use the same implementation of bitmap_label. The displayio system itself is where the implementations differ. In the core displayio is implemented in C code. For Blinka it's python code from here: https://github.com/adafruit/Adafruit_Blinka_Displayio/

I'm surprised that this difference exists and applies specifically to updating labels and not setting their text the first time. My gut instinct is somehow the BitmapLabel is not getting counted as a "dirty" region that needs re-drawn. I can't really imagine why it wouldn't be though, bot BitmapLabel and Label ultimately use one or more Bitmaps and TileGrid objects internally so I would have expected them all to work the same.

I'll dig into this a bit more later and perhaps move this issue over the Blinka_Displayio repo.

reproducer script:

import board
import displayio

# Compatibility with both CircuitPython 8.x.x and 9.x.x.
# Remove after 8.x.x is no longer a supported release.
try:
    from i2cdisplaybus import I2CDisplayBus

    # from fourwire import FourWire
except ImportError:
    from displayio import I2CDisplay as I2CDisplayBus

    # from displayio import FourWire

import time
import terminalio
from adafruit_display_text import bitmap_label, label
import adafruit_displayio_ssd1306

displayio.release_displays()

# Use for I2C
i2c = board.I2C()  # uses board.SCL and board.SDA
display_bus = I2CDisplayBus(i2c, device_address=0x3C, reset=None)


WIDTH = 128
HEIGHT = 32  # Change to 64 if needed
BORDER = 5

display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT)

# Make the display context
splash = displayio.Group()
display.root_group = splash

color_bitmap = displayio.Bitmap(WIDTH, HEIGHT, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF  # White

bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(WIDTH - BORDER * 2, HEIGHT - BORDER * 2, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000  # Black
inner_sprite = displayio.TileGrid(
    inner_bitmap, pixel_shader=inner_palette, x=BORDER, y=BORDER
)
splash.append(inner_sprite)

# Draw a label
text = "label"
text_area = label.Label(
    terminalio.FONT, text=text, color=0xFFFFFF, x=12, y=HEIGHT // 2 - 1
)
splash.append(text_area)

bmp_text_area = bitmap_label.Label(
    terminalio.FONT, text="bmp", color=0xFFFFFF, x=64, y=HEIGHT // 2 - 1
)
splash.append(bmp_text_area)

i = 1
while True:

    time.sleep(2)
    text_area.text = f"label{i}"
    bmp_text_area.text = f"bmp{i}"
    i += 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants