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

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

Uggima (author)Samuel Huff2018-01-06

Not quite right, some of these displays have pullups included on the display's pbc, had a couple from different places that did that but maybe not all of them? This might be the cause of some people's garbled displays (either that or some i2c clock issue?)

Could also suggest looking at the u8g2 library which supports the ssd1306 driver used commonly in these things.

https://github.com/olikraus/u8g2

ONOKE1997 (author)2018-01-06

Thank you for this helpful tutorial. Although I'm new at arduino, I could manage to use my oled by means of your tutorial. Thank you. Hope everybody have a nice year...!

MrCm made it! (author)2017-12-31

Thanks for the tutorial, it was quite helpful. I also needed the link that tercel89 posted: https://www.youtube.com/watch?v=5DByDu5hDHU My cheap OLED is running a SH1106 chip. This means I had to use the u8glib library from: https://github.com/olikraus/U8glib_Arduino My OLED also has the wrong addresses printed on it. It says 0x77 but it's actually 0x3C. I used this I2C address scanner code to find the correct address: https://playground.arduino.cc/Main/I2cScanner I also added on a BME280 on the I2C bus and made a simple weather station. For that part I used the Adafruit BME280 library.

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

MrCm (author)tercel892017-12-31

Thank you for this link. It was just what I needed to get my display working.

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.

abhishekcshah15 (author)2017-12-29

ssd1306_128x64_i2c:54: error: #error ("Height incorrect, please fix Adafruit_SSD1306.h!");

#error ("Height incorrect, please fix Adafruit_SSD1306.h!");

^

exit status 1

#error ("Height incorrect, please fix Adafruit_SSD1306.h!");

I got this error and can't solve this. Plzz help

kschmidt2 (author)2017-10-23

My board for some reason won't compile the 128x64, telling me the height is incorrect, but will compile the 128x32 code, even though, on the box is says it's 128x64. I think I've been ripped off.

tfried (author)kschmidt22017-12-15

You have not been ripped off (in all likelihood):

You will have to adjust the *library* in order to tell it you have a 64 lines display. More specifically, locate your arduino "libraries" folder, and edit "Adafruit_SSD1306/Adafruit_SSD1306.h". Search for "#define SSD1306_128_32", disable that line, and enable "#define SSD1306_128_64", instead.

(Yes, that's stunningly bad design, but again, it's a problem in the library, not the display.)

kschmidt2 (author)tfried2017-12-25

Wouldn't it display incorrectly though? I'll give it a go but.

danieldiasm (author)kschmidt22017-11-08

Happened to me also...but on Aliexpress those displays are so cheap that I don't even minded. I thought mine wasn't working on the beginning, the address told my the manufacturer is wrong.

kschmidt2 (author)danieldiasm2017-11-09

All well and good but mines from a local retailer and was something like $15 or so. Not really thrilled but it works I guess. I might check the .h file though.

HSS1978 made it! (author)2017-12-12

Just testing my

0.91 Inch 128x32 IIC I2C Blue OLED LCD Display DIY Oled Module SSD1306 Driver IC DC 3.3V 5V For Arduino PIC
using the example from library

AndrasS15 (author)2017-12-09

My Arduino Nano (cheap Chinese clone) was able to power the display via its 5V regulated output though it was plugged into a powered USB hub and not into the computer directly.

Possibly, only, the USB port of your computer was not strong enough to supply enough power.

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/...

Jean0x7BE (author)j3k.20092017-11-30

Thank you for the nice tip and adding value to the tutorial!

danieldiasm (author)j3k.20092017-11-09

Now I got it! Thanks!

It was a nice trick

danieldiasm (author)j3k.20092017-11-08

It compiled, but the display got frozen. I believe my display is too simple for that. Anyway, thanks! I've learned something more.

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 :)

Jean0x7BE (author)2017-11-30

I just have to thank you all for the great comments, and for adding value by helping others out with their problems! I belive many questions are solved by just reading these comments.

Again, thanks!!

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);

}

Jean0x7BE (author)DominicB302017-11-30

Awesome! Thanks so much for adding value to the tutorial! :)

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?

danieldiasm made it! (author)2017-11-08

I got this display a long time ago, back then I could not make it work (using the address told by the manufacturer), I also wasn't good at programming, electronics and my understanding wasn't so refined.

The only difference is my display worked with128x32 (the xcompiler cursed me for trying with the 64 library) and the image looks like interlaced video...

Anyway, thanks! I've almost thrown in the trash another day...

Your tutorial was great! Good advices, clear and concise, well explained.

Thank you!

Jean0x7BE (author)danieldiasm2017-11-30

I'm so happy I could help, and thanks so much for the nice comments! :)

TheRadMan made it! (author)2017-11-04

Jean0x7BE: I verified your ible. Good writing and nice touch on I2C scan steps. John

General Information

GM009605 China OLED [White] display counterfeits have 4 pins across top, GND and VDD and SCK and SDA. Definitely I2C bus. Shipped configured for 3C address. Your images show board with VCC then GND and this board is Adafruit legit. But mine was $4 CDN and still works (not sure for how long).

At 3.28 Vdc, peak current was 17.6mA (58mW) with all pixels ON.

At 5.05 Vdc, bench test P.S. reads peak 12.3mA (62mW) all pixels ON.

Tip: I found text mono-inversion command [OLED.setTextColor(BLACK,WHITE);].

Caution ; many China supplied pin jumpers are/become/ *open* because pin plugs are bad/cheap/inferior and the wire male-male jumper is *open circuit*.

Advice: Check all male jumpers after use; pull up and out of breadboard carefully. (I make my own DuPont females and Pin male jumpers for rapid develo). Many of these comments could be attributed to open jumpers; check by swapping your jumpers. If cables are *disturbed/open* during operations, then user must hit RESET button once; the OLED does NOT recover; it just goes dark until the board+program is reset. I think Clock and Data are synchronized but disturbed if disconnected while Ardy/Wemos/STM32 are still spitting out the I2C 'stream'.

WEMOS D1 MINI (ESP8266) with IoT : same deal as this Instructible, pins are SCK (clocking) D1 pin, SDA (data) D2 pin, powered by 3.3V. Bright display of 20chars x 4lines with under 20mA of draw for battery operation. \cool/

More advice: ADAFRUIT_SSD_1306.H has to be edit-modded for size 128x64; see comments within files and everywhere on Inet.

Ardy IDE 1.8.4 works OK with both SSD_1306 library .H (header) and .CPP (C-preprocessor) files, as well as GFX library.

Let me know if you find a *command* description for OLED. library commands in a handy PDF reference on the Inet. Please and thanks.

Jean0x7BE (author)TheRadMan2017-11-30

Thanks for the nice advices, it adds great value! And thanks for the nice comment :)

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.

ledom (author)AnderR32017-10-17

This is because the SSD1306 incorporates a an I2C receiver which converts the serial communications into instructions that are then used to drive the display. Think of it as an intelligent serial to parallel converter.

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.

Alex_1998 (author)FaisalMal2017-10-07

I suppose, it is impossible. The colour is unchangeable, it defined by the used OLED type.

FaisalMal (author)Alex_19982017-10-08

Is there different ROLES with the same controller but different color? because as you can see up there it's blue .

Alex_1998 (author)FaisalMal2017-10-08

Yes, you are rigth. The same SSD1306 controller can supplied with blue or white monohrome display panels.

thomas30 (author)FaisalMal2017-10-05

Most of these small OLED displays can only use black and white

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.

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

JavierP124 (author)2017-05-24

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

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.

About This Instructable

314,280views

151favorites

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: