This tutorial illustrates the basics of programming .96″ OLED display from Arduino by I2C interface. This program will give you an idea about the control and data bytes that should be sent to the OLED display.
#include <Wire.h>
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_MEMORYMODE 0x20 ///< See datasheet
#define SSD1306_COLUMNADDR 0x21 ///< See datasheet
#define SSD1306_PAGEADDR 0x22 ///< See datasheet
#define SSD1306_SETCONTRAST 0x81 ///< See datasheet
#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet
#define SSD1306_SEGREMAP 0xA0 ///< See datasheet
#define SSD1306_SEGREMAP2 0xA1 ///< See datasheet
#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet
#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used
#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet
#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet
#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet
#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet
#define SSD1306_DISPLAYON 0xAF ///< See datasheet
#define SSD1306_COMSCANINC 0xC0 ///< Not currently used
#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet
#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet
#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet
#define SSD1306_SETCOMPINS 0xDA ///< See datasheet
#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet
#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used
#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used
#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet
#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V
#define WIDTH 128
#define HEIGHT 64
// put your setup code here, to run once:
const uint8_t vccstate = SSD1306_SWITCHCAPVCC;
const uint8_t i2caddr = 0x3C;
const uint8_t i2cAddress = 0x3C;
void wireWrite(const uint8_t* array, uint8_t arraySize)
{
Wire.beginTransmission(0x3C);
Wire.write((uint8_t)0x00);
for(int i=0;i<arraySize;i++)
{
Wire.write(*array);
array++;
}
Wire.endTransmission();
}
void clearDisplay(void)
{
int count = 1024;
uint8_t bytesOut = 0;
Wire.beginTransmission(i2cAddress);
Wire.write((uint8_t)0x40);
while(count--)
{
if(bytesOut >= 31)
{
Wire.endTransmission();
Wire.beginTransmission(i2cAddress);
Wire.write((uint8_t)0x40);
bytesOut = 0;
}
Wire.write(0x00);
bytesOut++;
}
Wire.endTransmission();
}
void allDisplayOn(void)
{
const uint8_t array16[] = { SSD1306_DISPLAYALLON_RESUME };
wireWrite(array16, sizeof(array16));
const uint8_t array17[] = { SSD1306_DISPLAYON };
wireWrite(array17, sizeof(array17));
}
void allDisplayOff(void)
{
const uint8_t array1[] = { SSD1306_DISPLAYOFF };
wireWrite(array1, sizeof(array1));
}
void displayLines(void)
{
uint8_t *buffer;
int size = 1024;
buffer = (uint8_t*)malloc(size);
for(int i=0;i< size;i++)
{
buffer[i] = 0x01;
}
int count = WIDTH * HEIGHT;
uint8_t bytesOut = 0;
Wire.beginTransmission(i2cAddress);
Wire.write((uint8_t)0x40);
while(size--)
{
if(bytesOut >= 31)
{
Wire.endTransmission();
Wire.beginTransmission(i2cAddress);
Wire.write((uint8_t)0x40);
bytesOut = 0;
}
Wire.write(0x01);
bytesOut++;
}
Wire.endTransmission();
}
void configureDisplay(void)
{
const uint8_t array1[] = { SSD1306_DISPLAYOFF };
wireWrite(array1, sizeof(array1));
const uint8_t array2[] = { SSD1306_DEACTIVATE_SCROLL };
wireWrite(array2, sizeof(array2));
const uint8_t array3[] = { SSD1306_MEMORYMODE, 0x00 };
wireWrite(array3, sizeof(array3));
const uint8_t array4[] = { SSD1306_SETSTARTLINE };
wireWrite(array4, sizeof(array4));
const uint8_t array5[] = { SSD1306_SEGREMAP2 };
wireWrite(array5, sizeof(array5));
const uint8_t array6[] = { SSD1306_SETMULTIPLEX, HEIGHT - 1 };
wireWrite(array6, sizeof(array6));
const uint8_t array7[] = { SSD1306_COMSCANINC };
wireWrite(array7, sizeof(array7));
const uint8_t array8[] = { SSD1306_SETDISPLAYOFFSET, 0x0 };
wireWrite(array8, sizeof(array8));
const uint8_t array9[] = { SSD1306_SETCOMPINS, 0x12 };
wireWrite(array9, sizeof(array9));
const uint8_t array10[] = { SSD1306_SETDISPLAYCLOCKDIV, 0x80 };
wireWrite(array10, sizeof(array10));
const uint8_t array11[] = { SSD1306_SETPRECHARGE, (SSD1306_SWITCHCAPVCC == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1 };
wireWrite(array11, sizeof(array11));
const uint8_t array12[] = { SSD1306_SETVCOMDETECT, 0x40 };
wireWrite(array12, sizeof(array12));
const uint8_t array13[] = { SSD1306_CHARGEPUMP, (SSD1306_SWITCHCAPVCC == SSD1306_EXTERNALVCC) ? 0x10 : 0x14 };
wireWrite(array13, sizeof(array13));
const uint8_t array14[] = { SSD1306_SETCONTRAST, (SSD1306_SWITCHCAPVCC == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF };
wireWrite(array14, sizeof(array14));
const uint8_t array15[] = { SSD1306_NORMALDISPLAY };
wireWrite(array15, sizeof(array15));
const uint8_t array18[] = { SSD1306_COLUMNADDR, 0, 127 };
wireWrite(array18, sizeof(array18));
const uint8_t array19[] = { SSD1306_PAGEADDR, 0, 7 };
wireWrite(array19, sizeof(array19));
const uint8_t array16[] = { SSD1306_DISPLAYALLON_RESUME };
wireWrite(array16, sizeof(array16));
const uint8_t array17[] = { SSD1306_DISPLAYON };
wireWrite(array17, sizeof(array17));
}
void setup() {
Wire.begin();
Serial.begin(9600);
configureDisplay();
allDisplayOff();
clearDisplay();
delay(1000);
allDisplayOn();
displayLines();
}
void loop() {
// put your main code here, to run repeatedly:
}
Output of the above program will be as shown in the following image.