Adafruit_CircuitPython_DisplayIO_SSD1306 icon indicating copy to clipboard operation
Adafruit_CircuitPython_DisplayIO_SSD1306 copied to clipboard

Fix sleep/wake, again

Open regicidalplutophage opened this issue 1 year ago • 12 comments

Not sure about wake(), but sleep() were throwing TypeError: object with buffer protocol required at me.

regicidalplutophage avatar Jun 30 '24 04:06 regicidalplutophage

It seems like the actual issue is incompatibility between i2cdisplaybus.I2CDisplayBus and I2CDisplay.I2CDisplayBus and my misguided fix would break it for the folks who needed the recent fix that broke it for me.

Converting it to draft for now.

regicidalplutophage avatar Jul 01 '24 10:07 regicidalplutophage

@EAGrahamJr can you test if this works for you? I think your issue was caused by Blinka, but your fix broke it for me on CircuitPython 9.0.5

regicidalplutophage avatar Jul 01 '24 14:07 regicidalplutophage

This seems like the wrong place to fix incompatibilities as this code should not be "blinka" aware. If there's an incompatibility, it should be fixed at the bus level.

EAGrahamJr avatar Jul 01 '24 16:07 EAGrahamJr

This code is kind of aware though, as typing module would only be available in Python, not CircuitPython. If I understand the issue correctly, what I think should happen is that Blinka implementation of i2cdisplaybus should be brought in line with CircuitPython and sleep/wake fixes for SSD1306 and SH1106 should be reverted. I have zero investment in Blinka so I'm trying to figure out if my theory is even correct before I proceed. Though it's better if someone else fixes Adafruit_Blinka_Displayio's i2cdisplaybus.

regicidalplutophage avatar Jul 01 '24 16:07 regicidalplutophage

This code is kind of aware though, as typing module would only be available in Python, not CircuitPython.

That's not quite correct: the imports are "aware" but the rest of the code should not be: whatever bus is being used should have a consistent interface so that the display code doesn't have to make a choice when calling the method.

EAGrahamJr avatar Jul 04 '24 19:07 EAGrahamJr

Sorry for barging in. I have the same problem of sleep() throwing TypeError: object with buffer protocol required. I'm new to CircuitPython and I'm pretty sure I don't understand the hierarchy with Adafruit_Blinka_Displayio and so yet.

Do I understand correctly if this issue should be handled in Adafruit_Blinka_Displayio? If so, have an issue been raised there?

I tried looking for one but I'm not sure what I would be looking for :-)

mboehn avatar Jul 11 '24 23:07 mboehn

Basically, the way I understand it, the latest commit should be reverted and the stuff that commit was fixing should be fixed elsewhere. You can use the 2.0.1 release, @mboehn

regicidalplutophage avatar Jul 12 '24 00:07 regicidalplutophage

Part of the problem here is that this driver isn't quite the same as the other SSD drivers: they all seem to only take a displayio constructor, which should have a consistent interface at this point and should fix (or break :smiling_imp: ) all the issues here.

I only have I2C, so that's all I can test/verify.

(see https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SH1106/pull/19#issuecomment-2248198557 for similar comments)

EAGrahamJr avatar Jul 24 '24 14:07 EAGrahamJr

It seems like the actual issue is incompatibility between i2cdisplaybus.I2CDisplayBus and I2CDisplay.I2CDisplayBus and my misguided fix would break it for the folks who needed the recent fix that broke it for me.

Converting it to draft for now.

Since this was mentioned in the forums recently, I thought I would re-comment on this: as noted this is a conflict between the two I2CDisplayBus interfaces and and it is my opinion that should be resolved first. Since that is more of a core issue and a conflict between the two libraries, I'm not sure who the appropriate person is to get involved and I'm hesitant to blindly "at" someone.

EAGrahamJr avatar Aug 01 '24 16:08 EAGrahamJr

Yes, I can confirm that there is an issue between the two implementations. The fix I submitted apparently only works on Blinka.

  • Adafruit CircuitPython 9.1.1 on 2024-07-22; Adafruit QT Py RP2040 with rp2040
  • Raspberry Pi Zero; Bookworm

Library Comparisons

Raspberry Pi (Blinka) QTPY RP2040 (error)
adafruit-circuitpython-displayio-ssd1306 2.0.2 adafruit_displayio_ssd1306 2.0.2
adafruit-blinka-displayio 2.1.0
adafruit-circuitpython-busdevice 5.2.9 adafruit_bus_device 5.2.9

EAGrahamJr avatar Aug 01 '24 17:08 EAGrahamJr

@tannewt This was mentioned in forum post https://forums.adafruit.com/viewtopic.php?t=212512 -- since this involves a conflict between two core drivers, I still think that the resolution should be attempted there and not at this driver level.

EAGrahamJr avatar Aug 02 '24 04:08 EAGrahamJr

I still think that the resolution should be attempted there and not at this driver level.

I agree. This is a Blinka bug. A list isn't a readable buffer because it isn't linear memory. bytes, bytearray and array are. Blinka should be updated to match CP.

tannewt avatar Aug 05 '24 20:08 tannewt

I believe this was resolved by https://github.com/adafruit/Adafruit_Blinka_Displayio/pull/142

I tested the sleep / wake functionality successfully on a RPi with this code

import board
import displayio
import time

# 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
except ImportError:
    from displayio import I2CDisplay as I2CDisplayBus

import terminalio
from adafruit_display_text import label
import adafruit_displayio_ssd1306

displayio.release_displays()

i2c = board.I2C()  # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
display_bus = I2CDisplayBus(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32)

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

color_bitmap = displayio.Bitmap(128, 32, 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(118, 24, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000  # Black
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=5, y=4)
splash.append(inner_sprite)

# Draw a label
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=28, y=15)
splash.append(text_area)
i = 0
while True:
    i += 1
    text_area.text = f"hello {i}"
    display.sleep()
    time.sleep(1)
    display.wake()
    time.sleep(1)

FoamyGuy avatar Jan 15 '25 17:01 FoamyGuy