Adafruit SSD1306 OLED Display Driver for Raspberry Pi

As I had some questions by mail about my SSD1306 SPI and I2C driver port for Raspberry, I decided to get back to this driver and write some documentation.

The first time I wrote it, I tested with SPI oled but did not test with i2c because Adafruit I2C OLED display was not in stock. But for now, I have one and I will to verify that it is working also with I2C.

 What do you need ?

  • A Raspberry Pi (Rev 2 or Rev 1) with Raspbian, I recommand the Wheezy version
  • A I2C or SPI Adafruit OLED display (or whatever but take care at the wiring and powering the OLED)
  • Wiring cable or better if you do not want to use wire, a ArduiPi Board that contains connectors for Adafruit OLED. This is with this board that this tutorial was made
  • SSD1306 Library Source code located on my github
  • Setup correct I2C bus according to Raspberry Pi Revision (1 or 2) 

Assumptions

  • You must have dev tool installed onto your Raspberry Pi for compiling the driver library and a updated Wheezy distribution is preferable.
  • A good idea to read the excellent Adafruit tutorial about OLED display

Cabling the OLED Display

The SPI display use more pins than the I2C version, has I connected it to a ArduiPi board the connections are already done on the board so nothing to do, but if you want to do it with cable you should do it as following /

  • Connections for SPI
Adafruit SPI Display
OLED Pin
Pi P1 Header Pin
Raspberry Pi Pin
GND160V
3V3 (output, leave unconnected)2
VIN325V
DATA419MOSI (SPI)
CLK523SCLK (SPI)
D/C618IO24 (GPIO)
RST (Reset)722IO25 (GPIO)
CS (Chip Select)824CE0 (SPI)
  • Connections for I2C
Adafruit I2C Display
OLED Pin
Pi P1 Header Pin
Raspberry Pi Pin
VIN125V
3V3 (output, leave unconnected)2
GND36GND
RST (Reset)422IO25 (GPIO)
SCL55SCL
SDA63SDA

Ok done, now go to Raspberry Pi

I am connecting to Pi with ssh, once you’ll on the Pi issue the following commands :

To be able to compile you will need the compiler and some others tools, issue a :

To drive the Raspberry PI I/O ports I decided to use the small and pretty cool library bcm2835 from Mike. I added some functionalities so I included directly in build so you do not need to install anything. The features added are :

  • Added millis() function
  • Added option to use custom Chip Select Pin PI GPIO instead of only CE0 CE1
  • Done a hack to use CE1 by software as custom CS pin because Pi hardware SPI for CE1 seems not to work (I will investigate on this later)
  • Added function to determine PI revision board
  • Added function to set SPI speed (instead of divider for easier look in code)
  • Rewrited the I2C functions, I was unable to get the included one working, surely I was doing bad things

Bryan found a problem because i2c and bcm modules were not started and thus he cannot start the sample code. He gave us the solution to start the modules at startup by adding the two following lines into the file /etc/modules

These lines was enabled by default on my Adafruit distribution, that is why I did not had it.

Installation of SSD1306 Driver

The SSD1306 Driver is based on Adafruit Arduino library, I just ported the code to be able to compile and run on Raspberry Pi.

The driver is compiled into a library with all functions, including driving OLED with SPI or I2C and driving 128×32 and 128×64 LCD size. The LCD size and driving mode is now on the new init function of the class, no need to compile with #define

Get all the file from github dedicated repo :

The buid install process is in the Makefile, so issue a:

The new build script will compile the library (libssd1306.so.*) and install it for you (this is why need sudo) library in /usr/local/lib/ and library headers in /usr/local/include/

Fire the sample test code

Go to the examples folder and issue a :

Plug the OLED on your ArduiPi board (or manually wire), and you’re in,

You will see help and OLED supported

For now the Seeed OLED are not yet supported, I will work on this soon

So launch the following command to use a Adafruit SPI 128×32 OLED :

For a I2C 128×64 OLED do a :

 

Now time to post some picture of course

This one with SPI OLED

Adafruit SPI SSD1306 on ArduiPi

Adafruit SPI SSD1306 on ArduiPi

The second with I2C OLED

Adafruit I2C SSD1306 on ArduiPi

Adafruit I2C SSD1306 on ArduiPi

Next job will be to add to this library the Seeed 96×96 OLED that is pretty fine, see below, but for the picture below it is driven by the Arduino side of ArduiPi board when doing test with ArduiPi test board

ArduiPi Test Board with Grove Oled Display

ArduiPi Test Board with Grove Oled Display

49 thoughts on “Adafruit SSD1306 OLED Display Driver for Raspberry Pi

  1. Pingback: Adafruit SSD1306 OLED Display Driver for Raspberry Pi « adafruit industries blog

  2. Pingback: Community Corner: An All Adafruit Component Arduino Powered Remote Control Robot and Other Treats from this Week in Adafruit’s Community « adafruit industries blog

  3. Thank you so much for posting this! One thing that I found out I had to do with I2C was I needed to add two lines to the bottom of /etc/modules

    After I added those and rebooted I was able to get it to work!

  4. Thank you Mr. Hallar for your great tutorial and lib. :)
    I just ran into the CE1 problem.
    First I tried to connected SSD1306 on CE0. It ran fine. Then I added a nrf24l01 on CE1…it was somewhat dead. ;)
    Then swapped SSD1306 and nrf24l01, thanks to your patch SSD1306 was working and nrf24l01 was now working as well, but when I try to use both devices at the same time, the output on the oled gets disturbed.
    Do you know whether there is already a solution or a reason for the behaviour?

    Felix

    • Felix,

      How do you access your both devices ? with one program (exe) or two ?
      Because even if SPI can speak multi devices, it can’t do it “at the same time”.
      So if you use 2 executable (one for LCD and one for NRF for example) you can’t assume that both program will not speak in “the same” time to modules.

      As linux can switch from task to other, imagine LCD executable start SPI com to LCD, but Linux switch to NRF, that also start com, then SPI bus is “lost” because two devices try to speak in the same time.

      Could you add more description to your problem ?

      Charles

  5. Thanks for this nice tutorial! The last step somehow seems not not working for me, since the display stays black:
    pi@raspberrypi ~/ArduiPi_SSD1306/examples $ sudo ./ssd1306_demo –verbose –oled 1
    ssd1306_demo v1.1
    – OLED params –
    Oled is    : Adafruit SPI 128×64
    – Other Stuff –
    verbose is : yes

    x: 9y: 0dy: 3
    x: 30y: 0dy: 2
    x: 111y: 0dy: 2
    x: 81y: 0dy: 4
    x: 41y: 0dy: 2
    x: 85y: 0dy: 5
    x: 7y: 0dy: 5
    x: 76y: 0dy: 2
    x: 72y: 0dy: 3
    x: 76y: 0dy: 4

    I am not so much into C++ to see what causes this console output (via Putty) in ssd1306_demo.cpp. Any help is appreciated!

    Robert

  6. My display stayed blank too (this is with a 128×64 over i2c). The problem was that the i2c address being used was the wrong one. You can run the following command to see what address your display is responding to:

    sudo i2cdetect -r 0

    Mine showed a device at address 3d. If this is the case on your Pi as well, you can fix it by modifying the ArduiPi_SSD1306.h file. On line 34, change the ADAFRUIT_I2C_ADDRESS to 0x3D instead of 0x3C. After doing a make clean and make again, everything worked as advertised.

    Thanks for the library!

  7. I can’t compile examples:

    g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -Wall -lssd1306 ssd1306_demo.cpp -o ssd1306_demo
    /usr/local/lib/libssd1306.so: undefined reference to i2c_smbus_write_i2c_block_data'
    /usr/local/lib/libssd1306.so: undefined reference to
    i2c_smbus_write_byte_data’
    /usr/local/lib/libssd1306.so: undefined reference to `i2c_smbus_write_word_data’
    collect2: ld returned 1 exit status
    make: *** [ssd1306_demo] Error 1

    Kernel  version: 3.9.8+ #2 PREEMPT Tue Jul 2 17:38:12 CEST 2013 armv6l GNU/Linux

  8. The first Make was great:

    root@raspberrypi:/home/pi/ArduiPi_SSD1306# Make

    But the second in example gived me the same problem, fail.
    here is the command line:

    root@raspberrypi:/home/pi/ArduiPi_SSD1306/examples# make
    g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -Wall -lssd1306 ssd1306_demo.cpp -o ssd1306_demo
    /usr/local/lib/libssd1306.so: undefined reference to
    i2c_smbus_write_i2c_block_data'
    /usr/local/lib/libssd1306.so: undefined reference to
    i2c_smbus_write_byte_data'
    /usr/local/lib/libssd1306.so: undefined reference to `i2c_smbus_write_word_data'
    collect2: ld returned 1 exit status
    make: *** [ssd1306_demo] Error 1
    root@raspberrypi:/home/pi/ArduiPi_SSD1306/examples#

    Its seems to be linked to libssd1306.so in the I2c part.
    Is there a way to resolve it?
    is it possible to have an only I2C or only SPI lib?

    however thank for your JOB, so great!!

    Sorry for my poor english, I’m french ;)

  9. Hi guys,

     

    Sorry for my late anwser, I had the same problem the first time, If I remember correctly installing some i2c library dev header did the trick.

     

    Did you installed the libi2c-dev and i2c-tools using a

     

  10. Thanks for your fast reply, I’ve just check and these libs are on my raspi.
    The probleme is not solved, sorry!

    I’m performing a so long apt-get upgrade, I will tell you about the result.

    Thank again!

    • nesnes,

      Ok, I think I found it, it scratched again my head, in fact I went on my 3st Pi that had the same problem, then tried to find out the trick.

      I just needed to intall again lm-sensors package (even if correctly installed) then all wen fine. Something obvious I’d like to understand, but it seems to work.

      look below how I resolved it.

       

      Hope it will help you

      Charles

    • Hi Matmat,

      The ArduiPi Board just make the good connection between Raspberry and Adafruit Oled, so of course you can do it without a ArduiPi board.

      You just need to do the connection betbween your Pi and OLED that are indicated into the post in section Connections for SPI if you have a SPI OLED or Connections for I2C if you have a I2C OLED

      Charles

  11. Your are the best!
    it’s working perfectly!
    After an adresse change in ArduiPi_SSD1306.h
    Adafruit_I2c_adress = 3D ; (for me)

    Thanks a lot!

  12. Hi guys i’m having difficulty with a v2.1 oled 128×64

    everything compiles well but when i come to run the example the display briefly flashes of garbage the nothing. the output i get is

    sudo ./ssd1306_demo –vee –oled 1
    ssd1306_demo v1.1
    – OLED params –
    Oled is : Adafruit SPI 128×64
    – Other Stuff –
    verbose is : yes

    x: 9y: 0dy: 3
    x: 30y: 0dy: 2
    x: 111y: 0dy: 2
    x: 81y: 0dy: 4
    x: 41y: 0dy: 2
    x: 85y: 0dy: 5
    x: 7y: 0dy: 5
    x: 76y: 0dy: 2
    x: 72y: 0dy: 3
    x: 76y: 0dy: 4

    cheers in advance  for your help

    regards Gee

  13. hi
    i try to compile you lib for another hardware by cross compilation
    lib compilation is fine i have just some warnings:
    bcm2835.c:870:3: warning: implicit declaration of function ‘i2c_smbus_write_byte_data’ [-Wimplicit-function-declaration]
    bcm2835.c:873:3: warning: implicit declaration of function ‘i2c_smbus_write_word_data’ [-Wimplicit-function-declaration]
    bcm2835.c:876:3: warning: implicit declaration of function ‘i2c_smbus_write_i2c_block_data’ [-Wimplicit-function-declaration]

    but when i try to compile the example:
    /usr/local/lib/libssd1306.so: undefined reference to i2c_smbus_write_i2c_block_data'
    /usr/local/lib/libssd1306.so: undefined reference to
    i2c_smbus_write_byte_data’
    /usr/local/lib/libssd1306.so: undefined reference to vtable for Adafruit_GFX'
    /usr/local/lib/libssd1306.so: undefined reference to
    i2c_smbus_write_word_data’

    Any idea of the problem ?

  14. Hi, i’m getting the following error message when trying to
    compile your files with sudo make: In file included from
    ssd1306_demo.cpp:27:0: /usr/local/include/ArduiPi_SSD1306.h:1:1:
    error: expected unqualified-id before ‘+’ token make: ***
    [ssd1306_demo] Fehler 1 In file included from
    ssd1306_demo.cpp:27:0: /usr/local/include/ArduiPi_SSD1306.h:1:1:
    error: expected unqualified-id before ‘+’ token make: ***
    [ssd1306_demo] error 1 Any idea how to solve this ? Thanks !
    Regards Andreas

    • AVara,
      If I understand correctly, the error is happening when you try to compile the demo sample is that right ?
      If so, did you succeeded to compile and install the library before trying to compile the sample ?

  15. Hi Charles,

    I managed to compile the files now.
    My display is lighting up when i start the file teleinfo. Unfortunately its only showing a noisy picture. With the file ssd1306_demo i’m not seeing anything. I2cdetect is showing 3D as device.

    Thank you !

    Regards Andreas

  16. Hi i am able to compile you driver with my Pi
    i have a new question on my oled driver there is a SSD1305T7 instead of SSD1306 the difference is the width the 1305 is 132×64
    so i change in Adafruit_SSD1306.cpp the value of ssd1306_lcdwidth = 132;
    it seems to be not enaught
    any idea of what else i need to change ?

    • Hi mos89

      Well, I’m pretty sure that this is the reason it’s not working, there are lot of different SSD chip drivers with different configuration, and each chip need specific driver. SSD1305 could work, or not, I do not know this device.
      But, someone wrote a driver for this chip (should be working, not tested)
      here
      You can try to look at the init code (if we assume there is only this code different, which we do not now) located into glcd_Device.cpp of this link

      But as we do not know where it is not working, my advice could be, try you’re wiring and my driver with OLED with SSD1306, then when it works, wire the SSD1305 and change the init code into SSD1306 init code according the link above. This will avoid big headache because trying as “blind” will bring you for sure Murphy’s law. So start with example driver SSD1306 with SSD1306 driver then hack and mod to try on SSD1305 is a good starting from my point of view.

      You can find SSD1306 128×64 OLED starting $9 at tindie wich work fine with my driver.

      Charles

    • Mos,
      Which driver did you tried to compile the Adafruit or the ArduiPi Oled (both on my github) ?
      The ArduiPi Oled has both 32 and 64 pixels built in with several OLED, just need to tell what driver to use on command Line when you start the oled_demo located in examples folder. This driver is able to drive
      Adafruit SPI 128×32
      Adafruit SPI 128×64
      Adafruit I2C 128×32
      Adafruit I2C 128×64

      Once compiled just type ./oled_demo –help

      Charles

    • Hello Mos,

      Pour info je viens d’en commander 2
      ici 5$ pièce, bien entendu les connexions ne sont pas les mêmes d’un OLED à l’autre c’est galère, j’ai donc réglé le problème par un PCB dedié qui est capable de tous les adapter. J’attends la livraison. Je vais publier les PCB ce WE sur mon github, j’ai fait çà rapidement, c’est pas super présentable pour le moment ;-)

      Charles

  17. Hello,

    I have one of these Adafruit 128×32 OLED displays and I have managed to follow your brilliant instructions to get the demo working.

    I was wondering if you could help with a small script to display text on the screen. Just a simple, standard ‘Hello World!’ will do.

    I have tried to de-construct the code provided above but it’s so big I just get lost.

    My eventual aim is to display the temperature from a DS1820 temperature sensor on the screen.

    Thanks!

    • Hi Darren,

      The library code has been made for interfacing with C or C++ programs. Of course it is possible to build a executable called by a script to display temperature or other string.

      You just need to dig into the demo example code, (located into examples subfolder) not into the library.

      I need to change these library, may be one day when I will get more time to work on this.

      How would you get DS1820 temperature, from Pi or from other device ?

      Charles

  18. Hi
    just receive and plug in my new oled the text are now correctly displayed but i still have somme issue can i post you a picture ?

    • Hi Justin
      Well, I just digged around the 1st screen (1601, which obviously look so fine) and this screen use the 2 chipselect SPI CE0 and CE1 exposed by raspberry PI

      As you can have concurrent SPI devices, each one need to have it own CS pin.

      So fast answer is yes, long answer is yes but with caution

      If you want to use second one (931) with the 1st one, then the second one need to have a custom chip select pin that can’t be one of the already in place on raspberry CE0 and CE1 because they will be used by the first screen. This is not a problem with my driver because you can use another GPIO as chip select pin.

      But what I do not know is how the kernel handle concurrent SPI access, as the screens will share spi bus (except CS pin of course) if you try to send SPI command from 2 differents process I’m not sure it will not break the communication (but may be can work, need to be tested)

      So, if you’re driving both screens in the same program and pay attention on how you handle screen concurrency, it will work (but it’s a bit challenging because you’ll certainly need to write your own program)
      If you’re trying using first screen with Adafruit kernel framebuffer (wich obviously display linux console/X11) and try my Oled driver for the second screen (with custom GPIO CS of course), it could work depending how kernel is handling SPI devices. But I have no certitude. This needs to be tested, and sure it’ll be really interesting to know this result.

      I have several SPI LCD, may be I can put one on CE0 the other on custom GPIO and launch two oled_demo process in background (oled_demo &) and see if they interfere on each other, good test !!!!

      But nothing will work out of the box, sure you’ll have some headaches

  19. Has someone made a command line utility to write text to the Oled ? This so it can be used in scripts etc..
    I have the Oled running on 0x3D and the example seems to work now (had a small issue that I used 0x3d and needed to use 0x3D (capital) that did the trick.

    But now it would be great to display items on the disp. it’s A 128X64

    Chrs…

    • Paul,

      That is a great idea, It should be possible using the basic example demo to just write some text passed in parameter to the program. But the library has just one font (obvioulsy very small).
      A quick an dirty display could be get a new parameter from the demo code ans just print it to the OLED. The syntax could be something like that
      demo “Line 1\nLine 2\nLine 3\Line 4 …” or
      demo x y “text” with x and y cursor position
      I could test that but I have no time for now.
      I’m sure it won’t be too complicated to do.
      Charles

Add Comment Register



Leave a Reply

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


× 7 = forty nine

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">