rust-embedded-community / ssd1306

SSD1306 OLED driver
Apache License 2.0
282 stars 69 forks source link

read or toggle pixel in bufferedMode? #192

Open thomas725 opened 10 months ago

thomas725 commented 10 months ago

I found I can use this method to set a pixel in the buffer: https://github.com/jamwaffles/ssd1306/blob/5c50f1158546e02e8ddc1ad3889eaf8d25112053/src/mode/buffered_graphics.rs#L161

But I would now like to toggle a pixel without having to add another buffer to remember what all the pixels previous state was, so I'd either need a toggle or a read method, but neither seems to exist.

I guess my description already hints onto the only solution: fork & add those functions myself? Or is there any easier way?

jamwaffles commented 10 months ago

Hey, thanks for opening this. There's currently no way of getting a pixel value, but no reason there shouldn't be! I think a pub fn pixel(&self, x: u32, y: u32) -> Option<bool> method would be a good feature to add to BufferedGraphics if you would like to open a PR.

thomas725 commented 10 months ago

like that? https://github.com/jamwaffles/ssd1306/pull/193

No. How do I get a read only reference to one byte of our buffer, when having a read only reference to the BufferedGraphicsMode instance? What is this buffer's type? I don't understand enough Rust for this, sorry...

jamwaffles commented 10 months ago

193 looks good at first glance, but I'm not sure what you're after. Can you write out some (pseudo) code to better describe what's lacking in the current API vs what you'd like to see?

thomas725 commented 10 months ago

I'd like the ability to toggle pixels instead of just turning them either on or off. Either directly (see https://github.com/thomas725/ssd1306/blob/a6cfe678bc95a55aa8a58367ea5338cd147aac9b/src/mode/buffered_graphics.rs#L204 ) or by enabling reading current pixel's value to then be able to set it to the opposite value manually.

The current API only has the get_pixel(..) function, and as far as I can tell is missing any way to read or modify the buffers state depending on it's current state.

If the question you're asking is what I need that for on a higher level: I'd like to draw a curve showing the history of my last 128 sensor values (128x32 pixel display) over some text that's telling the user what curve he is looking at (which variable + current min & max values of that variable). And to not leave the user guessing what the curve might look like where it's overlapping with those characters I'd like to draw it by toggling = flipping the current value of those pixels instead of just turning them on.

It's an open-sourced smart-home hobby project of mine, if you're interested in more details see: https://gitlab.com/thomas351/esp32-rust-playground/ - though the described function does mostly only exist in my head as of yet. Only preparation I've already implemented for this function is the buffer for the last 128 sensor values.

UPDATE: I've now implemented my idea, it doesn't work as well as I hoped but it's still okayish ;) Code: https://gitlab.com/thomas351/esp32-rust-playground/-/blob/53c848fd3bd9b597fcfbe0367c4d3c8ac5de607a/src/display_handler.rs#L274

Result: IMG_20230901_074413_crop

UPDATE2: I've now improved my logic to make the line more visible where it overlaps with the text by detecting such conflicts (includes points where neighboring pixels are part of the text) and toggling those 15 times for 100ms instead of leaving the graph static for 1.5 seconds. For this new logic I use all 3 of get_pixel, set_pixel & toggle_pixel.