3 ms·
There are two things you need to consider: how fast you can push pixels (determined by bus speed), and how fast/often you're actually pushing pixels (library ef
by joshvm 8y ago
There are two things you need to consider: how fast you can push pixels (determined by bus speed), and how fast/often you're actually pushing pixels (library efficiency). A faster clock will usually speed things up.
One oddity about many displays (including the SSD1306) is that you can't write to a single pixel. Single pixels are not addressable (it would be a waste of RAM on a 1-bit display), so you usually have to send a write sequence that includes a memory offset and then a data byte (8 pixels). That also implies you can only write to 8-pixel wide blocks on the display in one go.
If you have RAM on your micro, the way to minimise write overhead and code complexity is to buffer the entire display and then update it in one go; I assume this is what adafruit does. Most displays have a mode where you keep sending bytes and it'll auto increment the display pointer. However now you have the cost of updating the entire display if you just want to update say four numbers for a sensor readout.
An approach I've used in the past is to defined a variable width font 8 pixels high (i.e. each character is 8xN). This is stored column-wise in memory (so character[10][0] has the bits in the first col). Then a write operation simply involved writing to a memory location, and iterating through each character's columns in the string. It's very fast even over I2C.
I would define an imaginary grid on the display and then call something like put_text(row, x, "my_string"). The approach means your write regions must be multiples of eight high, but the width doesn't matter. And you can also use this for things like simple sparkline plots where you don't need to store an entire displays' worth of data. I believe on the SSD1306 you get to choose whether the RAM is treated in column-wise order or row-wise order (or something like that to make this approach work).
Obviously refresh rate is determined by how much you change on the display per second, but for a few numeric fields it's really fast.
EDIT: https://www.electrodragon.com/w/images/9/95/SSD1306.pdf https://www.electrodragon.com/w/images/9/95/SSD1306.pdf
Yes - it has either vertical or horizontal page addressing which you can exploit.
I strongly recommend trying to write a display driver. The SSD1306 is great, and they're so cheap on eBay. You get instant feedback when stuff isn't right and it's a lot of fun trying to write efficient routines on 8-bit microcontrollers.
- muth02446 8y agoOften the rendering of GUI elements happens in an off-device image buffer which is then copied periodically to the device. This can be very slow in python if bit-fiddling is involved. Sometimes utilizing numpy for the copy can help a lot. If you want to roll your own, this might be a good starting point: https://github.com/robertmuth/Pytorinox/blob/master/spi_display.py https://github.com/robertmuth/Pytorinox/blob/master/spi_disp... It was written for raspi but should be easy to port.
- embeddedt 8y agoI'm one of the developers on the LittlevGL project. As a note, the display architecture does buffer chunks of the display and then write them.
- joshvm 8y agoGood to know! I checked though, Adafruit's doesn't :) https://github.com/adafruit/Adafruit_CircuitPython_SSD1306/blob/master/adafruit_ssd1306.py https://github.com/adafruit/Adafruit_CircuitPython_SSD1306/b...