Jul 28, 2013

Using the SSD1306 Text/Graphics OLED Display module

A guide to using the commands for the display. I am using the 128x64 SPI version. (applicable to SPI or I2C interface versions, and 128x32 and 128x64 sizes). You will need two libraries: Adafruit-GFX and Adafruit_SSD1306.

library alternative: u8g2

This library of vast scope has multiple fonts and seems faster. Especially useful are fonts without a 't' in their name. This means "not-transparent." If using on of these, you can keep updating a value on the display without needing to clear or write the inverse of previous character to erase. Fast and no flash-off betwee refresh!

Update on addressing

for I2C, it can be hard to find this info online. The i2c_scan() function is useful.
  the 128x32 size is 0x3c
  the 128x64 size is 0x3d; if SA0 pin connected to gnd, it becomes 0x3c
For other manufacturers of either size, I've so far only run into 0x3c.
(Having the same address is convenient for sharing code. Different addresses useful for using two displays)

The example code that is included with library runs through all of functions that can be implemented using the library, but it took me quite a while to sort out the minimum functions necessary to display a pixel and display a character. Here's a simplified list of commands with an explanation on their use. This may save you a few hours of head-scratching.

A minimum subset of the library functions for drawing :

display.clearDisplay();      // all pixels off
display.display();           // plotted items don't appear until this refreshes scrn
// for pixels (graphics)
display.drawPixel(x,y,clr);  // plot a pixel; upper left x,y = 0,0; lower right = 127,63
// for text
display.setTextColor(WHITE); // or BLACK);
display.setTextSize(n);      // printable sizes from 1 to 8; typical use is 1, 2 or 4
display.setCursor(x,y);      // begin text at this location 
display.print("Hello");      // print characters at loc x,y

Example: plot a single white pixel on a black screen at top-left and top-right corners
// plot a pixel, top-lf
display.clearDisplay();     
display.drawPixel(0, 0, WHITE);  // draw a single pixel
display.display();
   
// plot another pixel, top-rt
display.drawPixel(127,0, WHITE);
display.display();  


The next thing to know is how the character sizes are defined. The character set is a standard 5x7 dot matrix. With one pixel margin at the right and the bottom, a character's area is 6x8 for size=1. The size value simply multiplies each height and width by the size. for size=2, the character will be 2*6 x 2*8 = 12x16. The setCursor still applies and points to the top-left pixel of the character location.
With size=1, there can be eight lines of text, size=2: 4 lines, size=4: two lines
Example: write some text to the screen at two sizes


// write a line, size=2
display.clearDisplay();     
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0,16); 

display.print("Size 2 txt");


// write 2 lines below, size = 1
display.setTextSize(1);
display.setCursor(0,8*4);
display.print("Size 1 text");
display.setCursor(0,8*5);
display.print("Size 1 text again");
display.display();


To erase a pixel or a character, you must put the cursor at the same location and plot/print with color = black. This generally means the program will have to remember the previous values. 

display.setTextColor(BLACK);
display.setCursor(0,8*5);
display.print("Size 1 text again");
display.display();
Here's how this looks:


OLED 128x64


Note also that the display.display() command is slow; where appropriate, change many things before refreshing. 
Here's a complete program listing:

/* 
 This illustrates the sizes and positioning for text, plus
 a simple example of individual pixel positioning
 using monochrome OLEDs and the SSD1306 driver (SPI) from Adafruit
 David Smith
 */

#include <Wire.h>
#include <Adafruit_GFX.h>      // graphics library
#include <Adafruit_SSD1306.h>  // device driver for 128x64 SPI
 
// assign SPI control functions to pins
#define OLED_DC    11
#define OLED_CS    12
#define OLED_CLK   10
#define OLED_MOSI   9
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup()   {                
  display.begin(SSD1306_SWITCHCAPVCC);  // enable internal HV supply for display

  // plot a pixel, top-lf
  display.clearDisplay();     
  display.setTextColor(WHITE);
  display.drawPixel(0, 0, WHITE);  // draw a single pixel
  display.display();
  delay(500);
  // plot another pixel, top-rt
  display.drawPixel(127,0, WHITE);
  display.display();
  delay(500);

  // write a line size=2
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(0,16); 
  display.print("Size 2 txt");

  // write 2 lines below, size = 1
  display.setTextSize(1);
  display.setCursor(0,8*4);
  display.print("Size 1 text");
  display.setCursor(0,8*5);
  display.print("Size 1 text again");
  display.display();

  delay(2000);

  // erase the last write printed
  display.setTextColor(BLACK);
  display.setCursor(0,8*5);
  display.print("Size 1 text again");
  display.display();
}

void loop() {
}

See this post for a function to position text at an x,y location.

Here's the code to draw (just) the sine wave shown below.


Once you do sort out the text and graphics functions, you can combine them to create screens you want.
OLED SPI Module, Adafruit