Contact us by email if you have any questions! Info@electrodragon.com

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.

#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&lt;SSD1306_LCDWIDTH; i++) {
    for (uint8_t j=0; j&lt;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&lt; 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&lt; 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&lt; 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] &gt; 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 &lt; 168; i++) {
    oled.drawchar((i % 21) * 6, i/21, i);
  }    
}

void testdrawcircle(void) {
  for (uint8_t i=0; i&lt;SSD1306_LCDHEIGHT; i+=2) {
    oled.drawcircle(63, 31, i, WHITE);
  }
}

void testdrawrect(void) {
  for (uint8_t i=0; i&lt;SSD1306_LCDHEIGHT; i+=2) {
    oled.drawrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, WHITE);
  }
}

void testfillrect(void) {
  for (uint8_t i=0; i&lt;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&lt;SSD1306_LCDWIDTH; i+=4) {
    oled.drawline(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
    oled.display();
  }
  for (uint8_t i=0; i&lt;SSD1306_LCDHEIGHT; i+=4) {
    oled.drawline(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
    oled.display();
  }

  delay(1000);

  for (uint8_t i=0; i&lt;SSD1306_LCDWIDTH; i+=4) {
    oled.drawline(i, SSD1306_LCDHEIGHT-1, 0, 0, BLACK);
    oled.display();
  }
  for (uint8_t i=0; i&lt;SSD1306_LCDHEIGHT; i+=4) {
    oled.drawline(SSD1306_LCDWIDTH - 1, i, 0, 0, BLACK);
    oled.display();
  }
}
Tagged

14 Replies to “OLED SPI Interface with Arduino Tutorial”

  1. Charly86 says:

    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

  2. Chao says:

    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.

  3. Tim says:

    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?

  4. Chao says:

    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.

    1. Tim says:

      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.

      1. Tim says:

        Actually got the OLED working now on 4 wires serial, although a i2c tutorial would be awesome if you guys ever get time!

        1. berlin says:

          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!!

  5. Chao says:

    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.

  6. Manuel says:

    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!

  7. Chao says:

    Hello Manuel,

    I think there is only SPI demo code available, IIC is not yet available, thanks.

  8. andy says:

    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.

  9. Pete says:

    Any way to make this work on a Chipkit Uno 32 without drastic library rewritting? I’m not that versed to rewrite libraries.

  10. David says:

    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”

  11. poulbran says:

    This is awesome pushing the limits of arduino!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.