Skip to content

displayio won't refresh (certain circumstances) on 3-Color il0373 EPD FeatherWing #2144

Open
@anecdata

Description

@anecdata

Environment:
Adafruit Feather M4 Express with samd51j19
5.0.0-alpha.2 on 2019-09-04
CP Lib Bundle 20190907

The code below attempts to implement the Sprite Sheet example from:
https://learn.adafruit.com/circuitpython-display-support-using-displayio/sprite-sheet
...by adapting it to the timing requirements of EPD displays (e.g., time.sleep(display.time_to_refresh))

This code works on the 2-color EPD FeatherWing (switch the True/False on the board flags below).

Can't completely characterize the failure and recovery modes here, but if your 3-coolor EPD is like mine... if you load this code onto the 3-color EPD (might need t power-cycle too), it will never refresh. Seems related to the imageload - some kind of init-deinit issue? The code runs, loops, and prints fine, just no refreshes.

You'll see two commented out blocks in the code. One tries to show/refresh to None (terminal). The other uses a solid red bitmap instead of the imageload. The only surefire way I've found to unfreeze the refreshes once it happens is to comment out the imageload, uncomment the red bitmap, and usually power-cycle).

I know this is convoluted. Hopefully it's reproducible by others, and maybe someone has some insights.

Interestingly perhaps, once the refresh is kicked back on, uncommenting the imageload code and commenting out the red bitmap, with a simple save or reload, will then allow the imageload sprites to refresh properly.

You can shorten the iterations from 180 seconds by adding the seconds_per_frame KW arg when you create the display.

This issue was moved from adafruit/Adafruit_CircuitPython_SSD1675#2 (which has been closed).

import os
import time
import board
import terminalio
import displayio
import adafruit_imageload
from adafruit_display_text.label import Label
from adafruit_ssd1675 import SSD1675
from adafruit_il0373 import IL0373


# CicruitPython 5.0.0-alpha.2

# Feather M4 Express + choose your own EPD adventure...
ssd1675 = False  # 2C FeatherWing
il0373 = True    # 3C FeatherWing


def show_none():
    # Wait, then display default CircuitPython terminal
    time.sleep(display.time_to_refresh + 1)
    try:
        print("None    ", display.time_to_refresh)
        display.show(None)
        display.refresh()
    except RuntimeError as e:  # Refresh too soon
        print("None    ", display.time_to_refresh, e)


displayio.release_displays()
cs = board.D9
dc = board.D10

if ssd1675:
    display_bus = displayio.FourWire(board.SPI(), command=dc, chip_select=cs, baudrate=1000000)
    time.sleep(1)
    display = SSD1675(display_bus, width=250, height=122, rotation=90)
    epd_type = 'ssd1675_2C'
elif il0373:
    display_bus = displayio.FourWire(board.SPI(), command=dc, chip_select=cs, baudrate=1000000)
    time.sleep(1)
    display = IL0373(display_bus, width=212, height=104, rotation=90, highlight_color=0xff0000)
    epd_type = 'il0373_3C'


# sometimes this kicks refresh back on (sometimes power-cycle is needed too)...
# comment out the imageload to be sure
# show_none()

# Load the sprite sheet (bitmap) "/cp_sprite_sheet.bmp" (48x32) from:
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/sprite-sheet
sprite_sheet, palette = adafruit_imageload.load("/cp_sprite_sheet.bmp",
                                                bitmap=displayio.Bitmap,
                                                palette=displayio.Palette)

# this usually kicks refresh back on (sometimes power-cycle is needed too)...
# comment out the imageload to be sure
# red bitmap
# prite_sheet = displayio.Bitmap(48, 32, 1)
# palette = displayio.Palette(1)
# palette[0] = 0xff0000


# Create a sprite (tilegrid)
sprite = displayio.TileGrid(sprite_sheet, pixel_shader=palette,
                            width = 1,
                            height = 1,
                            tile_width = 16,
                            tile_height = 16)

# Create a Group to hold the sprite
group = displayio.Group(scale=1)

# Add the sprite to the Group
group.append(sprite)

# Add the Group to the Display
# display.show(group)

# Set sprite location
group.x = 60  # was 120
group.y = 20  # was 80

# Loop through each sprite in the sprite sheet
source_index = 0
while True:
    sprite[0] = source_index % 6

    # Wait, then refresh display Sprite
    time.sleep(display.time_to_refresh + 1)  # +1 b/c occasional "Refresh too soon 0.001"
    try:
        print("Sprite  ", display.time_to_refresh, source_index)
        display.show(group)
        display.refresh()
    except RuntimeError as e:  # Refresh too soon
        print("Sprite  ", display.time_to_refresh, source_index, e)

    source_index += 1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions