The goal here was to take a common (and cheap) SSD1306 LCD module and drive it using a PIC16F677A. Now, there’s a lot of code online - libraries and such - for driving an SSD1306, but the problem is that these all use buffered memory (i.e. a temporary screenbuffer to store pixel data before transmission). And why shouldn’t it? This is by far the best way to manage graphics.
Note: This project was created before this blog existed, and as such the write up is quite short.
The problem
Unfortunately, the PIC16F677A has a grand total of 128 bytes of SRAM. Yes, you read that right, 128 bytes. The SSD1306 module has 128x64 pixels. Even if it was 1 bit per pixel, I’d still need 1024 bytes of memory to store a screenbuffer.
So how am I going to be able to drive this LCD?
My solution
This was a bit of a challenge.
Using the resources from
- https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
- https://simple-circuit.com/ssd1306-oled-ccs-c-library/
- https://simple-circuit.com/pic18f4550-ssd1306-oled-display/
And then
- https://circuitdigest.com/microcontroller-projects/i2c-communication-with-pic-microcontroller-pic16f877a for I2C,
I ported and edited and mangled the original source codes so that it would fit and support a subset of operations of the original SSD1306 driver operations on the I2C library, without any data buffering at all! Hooray! (Wait, is this a good thing?)
If you’re interested, the useful code is on my github under ssd1306_unbuffered.h
and i2c.h
.
And here’s the proof!
How much more can we do?!
As it turns out, you can support a screen, some buttons, an ADC, and a relay! Just make sure you don’t go deeper than 8 functions in your calls…