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!

SSD1306 on PIC

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…

Recent dev board