Introduction: OLED I2c Display With Arduino

Picture of OLED I2c Display With Arduino

In this instructable I will show you how to connect and test a 0.96" i2c OLED display module to an arduino.

Parts:

  • Breadboard and hookup wires
  • Arduino (using a nano v3 5v 16mhz clone in this case)
  • External power supply (regulated 5v)
  • The OLED i2c display

I bought my display around 6 months ago, and I can’t seem to find the exact display on ebay now, but searching for “0.96 ssd1306 i2c OLED” shows a whole lot of similar displays. Other sites, like adafruit, got the same displays if you prefer to shop there.

Step 1: Connecting Your Display

Picture of Connecting Your Display

The display is connected by utilizing the i2c pins on your arduino.

Which pins to use for this differs on some arduino models, but on the UNO and NANO you use pin A4 (SDA) and A5 (SCL). If you’re using another arduino, google the pinout and look for SDA and SCL pins. (For example, google “arduino mega pinout”, and check the images).

I first attempted to power my display from my arduinos 5v. This worked, but only halfway – the display fired up, and started cycling the demos in the sketch we will see later on, and then froze after a few seconds.

I then powered my display from my external 5v supply (with common ground to the arduino), which did the trick – the display is now working properly.

The connections from the display:

  • VCC to external 5v
  • GND to external GND
  • SCL to arduino pin A5 (or the SCL pin for your arduino)
  • SDA to arduino pin A4 (or the SDA pin for your arduino)
  • arduino GND pin to external psu GND

Arduino is connected to the computer via an USB cable. The USB powers the arduino.

Step 2: I2c Scanner

Picture of I2c Scanner

To start out, we need to find out the i2c address of the display. To
accomplish this, I use a quick i2c scanner uploaded to the arduino. The scanner code can be found on http://playground.arduino.cc/Main/I2cScanner.
Copy and paste the code into your arduino IDE, build and upload, and fire up your serial monitor. If your display are connected, powered and working, you will get an address back from the scanner (in serial monitor). My display shows up at address 0x3C.

Step 3: Libraries

In this instructable I am using the arduino IDE (http://arduino.cc) and libraries from adafruit downloaded via github.
Link to the libraries:

I will assume you know how to download and install libraries in your arduino IDE. If not, there are tons of nice tutorials/instructions out there on how to get started with the arduino IDE and libraries.

Both libraries below needs to be installed before you are able to continue with this instructable.

https://github.com/adafruit/Adafruit_SSD1306 (SSD1306 library)

https://github.com/adafruit/Adafruit-GFX-Library (GFX library)

Step 4: Test Sketch

Picture of Test Sketch

Now that we know our displays i2c address, we can open the example sketch in our adafruit ssd1306 library.
In your arduino IDE, check your examples menu and locate the 128×64 i2c sketch found under Adafruit SSD1306 (as shown in the picture).
Change the address of the display to whatever the scanner told you, in my case 3x0C.

Compile and upload to your arduino, give it a second, and the display should fire up and show some different display modes.

The demo sketch ends with stars that continues to fall forever. You can copy-paste from the demo sketch to use the display modes that fits your needs.

Comments

FaisalMal (author)2017-09-14

Hello,

My OLED is a just white color I want to change to different color.

Is it possible?

Thank you and wish you a nice day.

AnderR3 (author)2017-09-09

Sorry if I am wrong and my bad english.. but I have a big question.

Anybody can explain how if the driver SSD1306 has 281 pins aprx, 90 pins are for the commons and the segments (128x64) to the display directly, then a flex of 30 tracks (for data bus, with differential signals in D 0:7, power and staffs like that..)

How the hell can program a librarie to comand all that logic with 2 pins, SCL and SDA?? (which testing with a tester I saw they are connected to two pins of the flex cable.)

I think understand the communication between a MPU and a controller of a display inside when you use all the connections clearly, for example the tipical lcd1602 with arduino at least it uses the D4:7 buses and other pins like W/R etc.. at that way in my unexperience is easier to understand.

Thank you.

ChipStewart made it! (author)2017-06-03

I got the code to load and the display to light, but everything seems to be in a narrow band at the top (photo left). After the 128x64 fix, the band got even narrower (photo right). Any idea why?

tercel89 (author)ChipStewart2017-09-05

You may have SH1106, rather than SSD1306. Watch https://www.youtube.com/watch?v=5DByDu5hDHU

dipa57 made it! (author)ChipStewart2017-06-04

Same problem:

PhilWheat (author)dipa572017-08-04

I'm running into the same issue as well - two different boards, so it doesn't appear to be a hardware or wiring problem.

jerry.ericsson2 (author)2017-09-02

Tried the code with the distance sensor, works good as well, I just happend to have some of those laying around in a parts bin. I am not sure what I was going to do with them when I ordered them several years ago, I think some sort of ghost sensor for my niece who is a paranormal nut case and goes hunting ghosts all the time.

jerry.ericsson2 (author)2017-09-02

For those with the yellow top and blue bottom, these are OLED'S there are no real leds on them, the yellow is actually a piece of yellow tape placed on the screen to show the yellow content. They were designed for some cheap MP3 player or something that had a menu up there, of course nobody really want's MP3 players any more so the screens are easier to peddle then the players.

jonahk38 (author)2017-08-24

i had the same problem with the alternating lines showing up. however after seeing @j3k.2009 's point about commenting them all out I started thinking. each of the # define lines had instructions on width and height. so i changed from the middle line uncommented toe the top line uncommented in that section. That is because the top line is 128 64. That matches the resolution of these screens.

j3k.2009 (author)2017-01-23

If you're seeing every second line as blank, like I was, you need to edit the library file to uncomment:


`#define SSD1306_128_64`

and comment out

`// #defineSSD1306_128_32`


https://github.com/adafruit/Adafruit_SSD1306/blob/...

ArifSae (author)j3k.20092017-02-11

sadness not working for me, used correct settings, but still seconds lines blank like interlacing efect

#define SSD1306_128_64
// #define SSD1306_128_32
// #define SSD1306_96_16

Luis A.G1 (author)ArifSae2017-08-09

The same happened to me.

Solution: Check the location where the libraries were installed, you probably have 2 duplicate folders with the libraries. For example:

C: \ Users \ CASA \ Documents \ Arduino \ libraries

C: \ Program Files \ arduino-1.6.9 \ libraries

Delete one of them, just use a destination folder for the libraries and then modify:

#define SSD1306_128_64

// #define SSD1306_128_32

// #define SSD1306_96_16

Bye

ArifSae (author)Luis A.G12017-08-10

thanks, checked already, no duplicates, if duplicate library is used it also tells that during compilation in end. Using it as it is for a project and be done with it :)

demetrioudemetrios (author)2017-07-25

DOWN LOAD THE SCANNER TO VERIFY THE ADDRESS, THEN RUN SSD1306 128X32 _I2C. IT WORKS PERFECTLY BRAVO TO THE ONE

illumation_ (author)2017-02-06

Why you don't need any pull-up resistors?

Samuel Huff (author)illumation_2017-06-03

The Arduino implements internal pullup resistors

JavierP124 (author)2017-05-24

Great tutorial. Thank you very much. Mine works perfectly now!

DominicB30 made it! (author)2016-07-03

Thanks for the lesson, I butchered the provided code and mashed it up with code for reading a AM2302 temp sensor .... now I have something practical...a digital readout of temp and humidity. Make sure you get the right I2c address. way cool.


#include <SPI.h>
#include <Wire.h>
#include "DHT.h"
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
#define DHTPIN 2
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSD1306 display(OLED_RESET);


void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
dht.begin();
}

void loop() {

int h = dht.readHumidity();

// Read temperature as Fahrenheit (isFahrenheit = true)
int f = dht.readTemperature(true);

display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("TEMP "); display.print(f); display.println("F");
display.setTextSize(2);
display.setTextColor(WHITE);
display.print("Humid: "); display.print(h); display.println("%");
display.display();
delay(10000);

}

WesP13 (author)DominicB302017-02-18

I want to use your code to read the temp sensor but i am getting an error when i try to compile. any ideas? i did grab the DHT.h code from here - http://playground.arduino.cc/Main/DHT11Lib

DominicB30 (author)WesP132017-02-19

a common compile error (for me anyway) is caused by not selecting the right board in the tools>board>boardmanager menu.

are you getting a specific error?

AxelH11 (author)2016-10-10

Thanks for the guide!

I got the code working (had the height problem in the library). And the nano seems to happily take the code. But there is no sign of life from the display. Should it give some sign of life when powered on or does it need to be correctly wired and programed to even light up?

Im worried that my display is a doa, or should I give it some time and search for errors?

BTW: my display are labeled SCK instead of SCL, other than that compleatly identical to the example. (It is labeled SCL on ebay where I bought it).

ArifSae (author)AxelH112017-02-11

i read somewhere this is issue of buffering, check adafruit forums.

ankit.pitroda (author)2016-04-27

Hello there

It's an awesome tutorial.

I want to know in the basic code of testing the 128x32 i2c display they are using reset pin. But there is no reset pin on my OLED display.

Second, I got the flickering display even after giving the external 5V.

What should I do??

Thanks

Adwsail (author)ankit.pitroda2017-01-27

Tie both GNDs together on the nano.

prampec (author)ankit.pitroda2016-11-10

The lack of the reset pin seams to be normal.

But this instruction is wrong. You shouldn't let the example code using pin4 as a non-connected reset pin. Instead you should modify the example not using any parameters while constructing the display. (This will lead to a default value -1 to be set as reset pin, and it is handled by the Adafruite driver.)

Also worth to mention that there are SPI-ready versions of this display board, that are also supported by the Adafruite driver. (Buy Adafruite products to support them developing drivers!)

Adwsail (author)2017-01-27

it took me 2 days to get it working but it now works great. FYI, the 2 god connections on the nano are not the same. The one between RST and D2 works great. The one on the other side does not, impedance is too high on my Chinese clone. Tie the 2 together and all is well. That little lesson cost me a lot of time.

dmainmon made it! (author)2017-01-25

Works. Great primer.

AlvinN14 made it! (author)2017-01-22

This is the very first thing I've made with the arduino, the steps were easy, even though I've never tinkered with this before. Thank you.

adrlau (author)2017-01-17

thanks fore help withe the display.

this work great.

i needed this to my stopwatch projekt

sahils100 made it! (author)2016-12-25

Making a marauders map for myself, thanks to you, easily got started with the display.

bigfilsing. (author)2016-12-22

There's a typo in Step 4 >>3x0C should be 0x3C (as per the scan in step 2)

abilly made it! (author)2016-11-28

I took this one step further and added the HC-SR04. I have it outputting the average distance readings to the screen, as well as serial monitor. Thanks for the help!

[code]

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

// Pins

const int TRIG_PIN = 11;

const int ECHO_PIN = 12;

// Anything over 400 cm (23200 us pulse) is "out of range"

const unsigned int MAX_DIST = 23200, MIN_DIST = 150;

float avgDist = 0, dist, cm,inches;

int pingCount,avgCount;

unsigned long pulse_width;

void setup() {

//lcd.Begin(16,2)

// The Trigger pin will tell the sensor to range find

pinMode(TRIG_PIN, OUTPUT);

digitalWrite(TRIG_PIN, LOW);

// We'll use the serial monitor to view the sensor output

Serial.begin(9600);

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)

// init done

// Show image buffer on the display hardware.

// Since the buffer is intialized with an Adafruit splashscreen

// internally, this will display the splashscreen.

display.display();

delay(2000);

// Clear the buffer.

display.clearDisplay();

// draw a single pixel

display.drawPixel(10, 10, WHITE);

// Show the display buffer on the hardware.

// NOTE: You _must_ call display after making any drawing commands

// to make them visible on the display hardware!

display.display();

delay(2000);

display.clearDisplay();

}

void loop() {

unsigned long t1;

unsigned long t2;

// Hold the trigger pin high for at least 10 us

digitalWrite(TRIG_PIN, HIGH);

delayMicroseconds(10);

digitalWrite(TRIG_PIN, LOW);

// Wait for pulse on echo pin

// while ( digitalRead(ECHO_PIN) == 0 );

pulse_width = pulseIn(ECHO_PIN,HIGH);

// Calculate distance in centimeters and inches. The constants

// are found in the datasheet.

cm = (pulse_width*0.034)/2;// / 58.0;

inches = (pulse_width*0.0133)/2; // 148.0;

pingCount++;

//set average distance and reset it every x pings

if(pingCount>10){

dist=inches;

pingCount= 1;

}

else {

dist= dist+inches++;

avgDist = dist/pingCount;

}

if(pingCount==10){

printReadings();

}

if (avgDist < 10){

// playTone(); //previously had it play tones over a piezo based on distance from the sensor

}

else {

// noTone(piezo);

}

// Wait at least 60ms before next measurement

delay(60);

}

void printReadings()

{

// Print out results

if ( pulse_width > MAX_DIST ) {

Serial.println("Out of range");

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(0,0);

display.println("Out of range");

display.display();

}

else if (pulse_width <MIN_DIST) {

display.print(pulse_width);

Serial.println("Object to close!!") ;

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(0,0);

display.println("Object to close!!");

display.display();

}

else {

Serial.print(pingCount);

Serial.print(" pc \t");

Serial.print(avgDist);

Serial.print(" avgInch \t");

Serial.print(cm);

Serial.print(" cm \t");

Serial.print(inches);

Serial.println(" in");

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(0,0);

display.print(pingCount);

display.print(" pc \t");

display.print(avgDist);

display.print(" avgInch \t");

display.print(cm);

display.print(" cm \t");

display.print(inches);

display.println(" in");

display.display();

}

delay(1000);

display.clearDisplay();

}

[/code]

[code]

johnnyfrx made it! (author)2016-11-20

Very Cool. Thank you for sharing!

julianwiggins (author)2016-10-24

Good work! Nice to get an ebay impulse purchase going so easily. Many thanks!

SriharshaB1 (author)2016-10-21

Very clear instructions and could make it in less than 5 minutes. Thanks a lot

sddennis (author)2016-10-20

Just did it. Thanks for the information. You are spot on about the address 0x3C.

One more thing: there is a glitch in the 128x64 i2c example, before the Setup section, there is a static char bitmap. You must add const on the line just before static in order for it to compile. The error message is pretty clear but it bears mentioning.

Keep up the good work!

I really want to see more ways to use this display. There seems to me no real manual..

WilIiam made it! (author)2016-10-07

It works!

JaneE3 (author)WilIiam2016-10-18

Great, you can find different color and sizes in this amazon store

https://www.amazon.com/s/ref=nb_sb_noss?url=me%3DA28JUS3SJ1A0RV&field-keywords=0.96

GJ Kruijff (author)2016-10-14

Great instructions! Everything working fine ;) (header issue was easy to fix indeed).

Does anyone know of instructions to get the special features like battery strength etc going?

Shopworker (author)2016-10-08

Hi, build this, great.

i found a tool to transfer an picture to binary code here: https://www.instructables.com/id/How-to-use-OLED-di...

but this did´t work in this sketch.

How can i transfer an picture to binary code for this sketch?

Thanxs, Duffy

b

diy_bloke (author)2016-09-30

0x3C is pretty much the standard for these displays o in most cases the I2C scanner wouldn't be necessary. Wont hurt to make sure though

RlNEHART (author)2016-09-28

I had some other problems not addressed in the guide, but I couldn't have done it without your help! I had to change the names of the adafruit libraries because they contained non alphabetic characters, ie - and _. The .h file in the SSD library also had the wrong height around line 70 or so. I opened the file in notepad++ and was able to uncomment the correct 128x64 declaration and remove the 128x32 one. Also I got a compilation error saying all sorts of objects in the "Robot Control" library were not declared. I have no idea why that happened, but I just took RobotControl out of the libraries folder and that problem was solver. The last error I had was that the program could not find the fillCircle class, even though the GFX library was included. To fix this I clicked sketch, then add library and re-added the GFX library, which add this line to the code:

#include <gfxfont.h>

Steen EilerJ made it! (author)2016-09-25

It works! I had to alter the .h file too, but that was it :-)

rich1812 (author)2016-06-14

I got it to work. But I have a questions.

1My display the top 1/3 displays yellow and the bottom 2/3 displays blue. How do I fix it? Is it defective?

DIYmasters (author)rich18122016-09-12

Nothing's wrong, thats just the way the display was made. Assuming that you bought this off eBay. The top yellow bar is for a status bar, battery level, clock, etc... The same stuff as in an MP3 player. Good luck!

mdezem (author)rich18122016-06-22

It's not defective. Some displays are designed to have a different color in the top part. It's not possible to change the colors, they are designed that way to be used in specific applications (an old cel phone top bar, for example).

vernkle (author)rich18122016-06-14

Your display is not defective. Many displays have different color LED's in the upper portion of the screen, I do not know of a way to change this.

Jean0x7BE (author)rich18122016-06-14

Hi, cool that you got it working, but I must admit I haven't seen that behavior before, so I don't know how to help you out. Good luck tho! :)

StevenV24 (author)2016-08-14

You said: "I first attempted to power my display from my arduinos 5v. This
worked, but only halfway – the display fired up, and started cycling the
demos in the sketch we will see later on, and then froze after a few
seconds.

I then powered my display from my external 5v supply
(with common ground to the arduino), which did the trick – the display
is now working properly".

This is somewhat strange ... some of the replyers have no problem with powering from the arduinos 5V?

CraftKing7777 (author)StevenV242016-08-18

Maybe they are plugging into usb 3.0 while he is using USB 2.0 which only supplies half the current of 3.0

About This Instructable

255,884views

136favorites

Bio: Computer geek who stumbled upon arduino and electronics in general a while ago.
More by Jean0x7BE:AC light 433 mhz radio controlled timer with arduinoOLED i2c display with arduino
Add instructable to: