mcauser / micropython-ssd1327

MicroPython driver for SSD1327 128x128 4-bit greyscale OLED displays
MIT License
25 stars 10 forks source link

Obtaining present state of a pixel #4

Closed elhoncho1 closed 4 months ago

elhoncho1 commented 3 years ago

First of all, thanks for this awesome library. I am using it with an Adafruit 128x128 grayscale oled connected to a Pi Pico. It works great. Quick question: is there a way to interrogate the display, returning the present state of a specific pixel?(something akin to lcd.get(x,y)). Apologies if this is obvious, I am a noob to micropython. Thanks again!

elhoncho1 commented 3 years ago

(or alternatively reading the state of the whole array of pixels, for further use. I can update these via display.pixel(x,y,col) followed by display.show(), but I cannot find any obvious way in the examples or the library to read rather than write. Apologies if this is noob blindness. For reasons of code optimization I would prefer to have this option to interrogate the display when needed, rather than keeping programmatic track of what was previously written to the display)

nicolasff commented 2 years ago

Hopefully you've found a workaround in the 5 months since this was posted, but if you're still interested, here's how you could do it.

One (hacky) way you can do this is to query the pixel value via the framebuf field that the SSD1327 library wraps around.

So if you set a pixel at (x,y) with value c this way: lcd.pixel(x,y,c), then you can get c back by calling lcd.framebuf.pixel(x,y).

Example with a Zio.cc 128x128x16 grayscale display:

>>> display.pixel(0,0,15)   # brightest grayscale value
>>> display.pixel(16,16,8)  # half brightness
>>> display.pixel(32,32,1)  # lowest brightness
>>> display.show()          # 3 pixels are displayed
>>> display.framebuf.pixel(0,0)
15
>>> display.framebuf.pixel(16,16)
8
>>> display.framebuf.pixel(32,32)
1

Using the internal framebuf object so obviously not ideal, so you could also add a method to the SSD1327 class, like this:

def get_pixel(self, x, y):
    return self.framebuf.pixel(x, y)

Hope it helps!

elhoncho1 commented 2 years ago

I did find a workaround, but with some sacrifices (had to reduce the size of my matrix, making pixels aggregates of four, to reach the processing speed intended). Your comment is now inspiring me to go back to the original purpose, using the whole 128x128 matrix. Definitely a project for Xmas break. Thanks for the excellent input!

mcauser commented 4 months ago

Normally, displays like this are write-only. You can't get the pixel state back from the display. If you maintain a copy of the display data (ie use a framebuf), then you can get the data from there instead, as demo'd above. But if you write data directly to the display, then sadly no, it's fire and forget.