OLED SPI Interface with Arduino Tutorial
When you get our OLED, they are followings so may have to do before you start to use it.
It’s a quite cheap and easy to use OLED, offering a few communication protocol 68XX, 8080, 4 wires, 3 wires and I2C, we are now going to try the 4 wires. It’s also fast and good at animation, looks cool. You can find the product here.
See the demo video at break.
Soldering
Soldering so break way headers
The resistor on the back (BS0, BS1, BS2) are the configuration of different interface. See the page 9 and sub-title ‘MCU Bus Interface Pin Selection ‘, since we are going to use 4-wires configuration, so you need to move the BS1 resistor from “1” to “0” posistion, just heat it up a little bit with iron tip, and then grab and move with tweeter, it’s easy.
Library
Install the <SSD1306> library, get it from the product page, upload the following codes into your arduino, and then you can see how it works.
Demo Codes
Now you can start using the following demo codes, see the wiring of the first couple of lines.
[c]
#define OLED_DC 11
#define OLED_CS 12
#define OLED_CLK 10
#define OLED_MOSI 9
#define OLED_RESET 13
#include <SSD1306.h>
SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static unsigned char __attribute__ ((progmem)) logo16_glcd_bmp[]={
0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0xf8, 0xbe, 0x9f, 0xff, 0xf8, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
0x20, 0x3c, 0x3f, 0x3f, 0x1f, 0x19, 0x1f, 0x7b, 0xfb, 0xfe, 0xfe, 0x07, 0x07, 0x07, 0x03, 0x00, };
void setup() {
Serial.begin(9600);
// If you want to provide external 7-9V VCC, uncomment next line and comment the one after
//oled.ssd1306_init(SSD1306_EXTERNALVCC);
// by default, we’ll generate the high voltage from the 3.3v line internally! (neat!)
oled.ssd1306_init(SSD1306_SWITCHCAPVCC);
// init done
oled.display(); // show splashscreen
delay(2000);
oled.clear(); // clears the screen and buffer
// Fill screen
oled.fillrect(0, 0, SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, WHITE);
oled.display();
delay(2000);
// draw a single pixel
oled.setpixel(10, 10, WHITE);
oled.display();
delay(2000);
oled.clear();
// draw many lines
testdrawline();
oled.display();
delay(2000);
oled.clear();
// draw rectangles
testdrawrect();
oled.display();
delay(2000);
oled.clear();
// draw multiple rectangles
testfillrect();
oled.display();
delay(2000);
oled.clear();
// draw mulitple circles
testdrawcircle();
oled.display();
delay(2000);
oled.clear();
// draw a white circle, 10 pixel radius, at location (32,32)
oled.fillcircle(32, 32, 10, WHITE);
oled.display();
delay(2000);
oled.clear();
// draw the first ~12 characters in the font
testdrawchar();
oled.display();
delay(2000);
oled.clear();
// draw a string at location (0,0)
oled.drawstring(0, 0, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation");
oled.display();
delay(2000);
oled.clear();
// miniature bitmap display
oled.drawbitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
oled.display();
// invert the display
oled.ssd1306_command(SSD1306_INVERTDISPLAY);
delay(1000);
oled.ssd1306_command(SSD1306_NORMALDISPLAY);
delay(1000);
// draw a bitmap icon and ‘animate’ movement
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}
void loop()
{
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i++) {
for (uint8_t j=0; j<SSD1306_LCDHEIGHT; j++) {
oled.setpixel(i, j, WHITE);
oled.display();
}
}
}
void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
uint8_t icons[NUMFLAKES][3];
srandom(666); // whatever seed
// initialize
for (uint8_t f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random() % SSD1306_LCDWIDTH;
icons[f][YPOS] = 0;
icons[f][DELTAY] = random() % 5 + 1;
Serial.print("x: ");
Serial.print(icons[f][XPOS], DEC);
Serial.print(" y: ");
Serial.print(icons[f][YPOS], DEC);
Serial.print(" dy: ");
Serial.println(icons[f][DELTAY], DEC);
}
while (1) {
// draw each icon
for (uint8_t f=0; f< NUMFLAKES; f++) {
oled.drawbitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE);
}
oled.display();
delay(200);
// then erase it + move it
for (uint8_t f=0; f< NUMFLAKES; f++) { oled.drawbitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK); // move it icons[f][YPOS] += icons[f][DELTAY]; // if its gone, reinit if (icons[f][YPOS] > SSD1306_LCDHEIGHT) {
icons[f][XPOS] = random() % SSD1306_LCDWIDTH;
icons[f][YPOS] = 0;
icons[f][DELTAY] = random() % 5 + 1;
}
}
}
}
void testdrawchar(void) {
for (uint8_t i=0; i < 168; i++) {
oled.drawchar((i % 21) * 6, i/21, i);
}
}
void testdrawcircle(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
oled.drawcircle(63, 31, i, WHITE);
}
}
void testdrawrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
oled.drawrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, WHITE);
}
}
void testfillrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i++) {
// alternate colors for moire effect
oled.fillrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, i%2);
}
}
void testdrawline() {
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
oled.drawline(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
oled.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
oled.drawline(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
oled.display();
}
delay(1000);
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
oled.drawline(i, SSD1306_LCDHEIGHT-1, 0, 0, BLACK);
oled.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
oled.drawline(SSD1306_LCDWIDTH – 1, i, 0, 0, BLACK);
oled.display();
}
}
[/c]
Comments (15)
Hello,
This tutorial bring me some questions :
– According to the documentation, default mode for LCD interface is 8080 parallel mode. So to switch to 4 wires SPI mode we need to change BS1 and BS2 ?
– The tutorial do not mention level shifter, does this mean we can drive the LCD with the +5V of the arduino board and apply high level 5V to the inputs ?
Thank you for your help
Hi charly,
yes you need to switch BS1 and BS2 to 1 position.
and this module does work with 5V voltage, it’s no problem, just connect it directly with arduino.
Hi,
The documentation says
“When I2C
mode is selected, D2 & D1 should be tired together an
serve as SDAout & SDAin in application and D0 is the
serial clock input SCL.”
By “tired” does it mean D2 and D1 should be joined together?
Hello Tim,
I guess it’s a typing mistake, it’s simply just “wired” not “tired”, sorry for the confusing! And it should means not wired together, but connect respectively for it’s function.
Also the test code from above is incomplete, the void loop is missing code.
I tried 4 wires as used in the tutorial,
OLED pin 1 – Vcc > Arduino +5v
OLED pin 2 – Ground > Arduino GRND
OLED pin 3 – CS > Arduino Digital Pin 12
OLED pin 4 – RES > Arduino Digital Pin 13
OLED pin 5 – D/C > Arduino Digital Pin 11
OLED pin 8 – CLK > Arduino Digital Pin 10
OLED pin 9 – MOSI > Arduino Digital Pin 9
Resoldered BS1 from factory stock 1 to 0 so BS0,1,2 all have resistors on 0.
Any idea what I’m doing wrong? OLED dosent power up or disply anything at all.
Actually got the OLED working now on 4 wires serial, although a i2c tutorial would be awesome if you guys ever get time!
Hi, I’m totally new to this and would also ask if anybody has a i2c solution (code) for this display. explaining the wiring would also be very helpful (oled –> arduino).
Thank you very much!!
Hello Tim,
I just updated the code, it’s complied successfully, some errors we made during editing this post. if you have any further questions with it please let me know.
Hi,
I don’t seem to be able to find the I2C library for this OLED display. Even the Demo Code uses SPI not I2C. Can you kindly point me to the right library?
Thanks!
Hello Manuel,
I think there is only SPI demo code available, IIC is not yet available, thanks.
Is it possible to buy these already set up properly for SPI, to match the demo code?
Moving surface mount resistors around might be easy if you’re young and have good eyesight and steady hands. None of those things apply to me any more, unfortunately.
Any way to make this work on a Chipkit Uno 32 without drastic library rewritting? I’m not that versed to rewrite libraries.
I downloaded the library from the product page and attempted to compile the code provided using the arduino IDE and this code is not compiling.
“lt was not declared in this scope”
This is awesome pushing the limits of arduino!
What are the pins for n Arduino Mega? the ones above only work for the Uno