Close Menu
    Facebook X (Twitter) Instagram Pinterest YouTube
    Trending
    • Disable SSH Password Login on Raspberry Pi
    • Elecrow Meteor IPS Touchscreen with RGB LEDs
    • Pi Pico Pinout Display on the Command Line
    • How to Add a Raspberry Pi Pico Reset Button
    • Pi Pico Onboard LED
    • Pi Pico W Pinout and Power Pins
    • CrowPi L Raspberry Pi Laptop and Learning Platform
    • Pi Pico W Launched
    Mastodon YouTube Facebook Instagram Pinterest RSS
    Raspberry Pi SpyRaspberry Pi Spy
    • Home
    • Categories
      • General
      • Hardware
      • Programming
      • Python
      • Software
      • Tutorials & Help
    • BerryClip
      • BerryClip Instructions
      • BerryClip Plus Instructions
      • Videos & Reviews
    • Buy
      • Buy Pi
      • Buy Pi Accessories
      • Buy Books
    • Tools
      • Ultimate Raspberry Pi Alexa Skill
      • Pi Power Estimator App
      • Pi-Lite 14×9 LED Matrix Sprite Editor
      • RPiREF Pin-out Reference App
      • Simple Ohm’s Law Calculator
      • Web Sites & Links
    • Tutorials & Help
        Featured
        November 9, 20200

        Raspberry Pi Temperature Monitoring

        Recent
        February 16, 2024

        Disable SSH Password Login on Raspberry Pi

        December 23, 2022

        How to Add a Raspberry Pi Pico Reset Button

        November 20, 2022

        Pi Pico Onboard LED

      1. Contact Us
      2. Site Map
      Raspberry Pi SpyRaspberry Pi Spy
      You are at:Home»Hardware»Interfaces»I2C»Using an I2C OLED Display Module with the Raspberry Pi
      I2C OLED 128x64 Screen

      Using an I2C OLED Display Module with the Raspberry Pi

      42
      By Matt on April 8, 2018 I2C, Tutorials & Help

      Miniature OLED display modules are a great way to add a small screen to your Raspberry Pi projects. They are available in various sizes but common sizes include 128×32 and 128×64 pixels. The cheaper ones have single colour pixels that are either white, yellow or blue. My device has white pixels and uses an I2C interface which only requires four wires to be connected to the Pi.

      In this tutorial I’ll explain how I setup my 0.96″ OLED display module using the Pi’s I2C interface. Once setup it is easy to use Python to place text, draw shapes or even display simple images and animations.

      UPDATE: This article has been updated to remove references to Python 2 and switch to luma.oled library.

      The OLED Module

      My OLED display module is a 0.96″ I2C IIC SPI Serial 128X64 OLED LCD LED Display Module.

      I2C OLED 128x64 Screen (Front)
      I2C OLED 128x64 Screen (Back)

      It has four pins. Two are power (Vcc and Gnd) and two are for the I2C interface (SDA and SCL). The header may need to be soldered on before you can use it.

      Update Operating System

      As with all my projects I started off by creating an SD card with the latest Raspbian image. Then I made sure this was up-to-date by running the following commands :

      sudo apt update
      sudo apt upgrade

      This step may take a  few minutes if there are lots of packages to update but it usually saves some frustration in the future.

      Display Module Setup

      My screen had four pins, two for power and two for the I2C interface.

      I2C OLED Display and Raspberry Pi GPIO wiring

      I connected them directly to the Raspberry Pi’s GPIO header using the following scheme :

      OLED PinPi GPIO PinNotes
      Vcc1 *3.3V
      Gnd14 **Ground
      SCL5I2C SCL
      SDA3I2C SCA

      * You can connect the Vcc pin to either Pin 1 or 17 as they both provide 3.3V.
      ** You can connect the Gnd pin to either Pin 6, 9, 14 , 20, 25, 30, 34 or 39 as they all provide Ground.

      Enable I2C Interface

      The I2C interface is disabled by default so you need to enable it. You can do this within the raspi-config tool on the command line by running :

      sudo raspi-config

      For additional details on this step please see my how to Enable the I2C Interface on the Raspberry Pi post.

      The following libraries may already be installed but run these commands anyway to make sure :

      sudo apt install -y python3-dev
      sudo apt install -y python3-smbus i2c-tools
      sudo apt install -y python3-pil
      sudo apt install -y python3-pip
      sudo apt install -y python3-setuptools
      sudo apt install -y python3-rpi.gpio
      sudo apt install -y python3-venv

      I would recommend using Python 3 unless you have a really good reason for using Python 2.

      Finding the OLED Display Module’s Address

      With the I2C libraries installed I used the i2cdetect command to find the module on the I2C bus.

      i2cdetect -y 1

      and I got the following result :

      I2C OLED Display Module

      This was good news as it showed the device had been detected with an address of “0x3c”. This is the default hex address for this type of device. I’ve got no idea why the device PCB suggests the address is “0x78” when it is clearly “0x3c”.

      If you’ve got an original Model B Rev 1 Pi then type the following command instead :

      i2cdetect -y 0

      Create Project Folder

      Now the hardware is working create a folder to contain items related to the screen.

      cd ~
      mkdir oled-screen
      cd oled-screen

      Create Python Virtual Environment

      In order to install the luma.oled library we will first create a Python Virtual Environment. This will allows all the libraries and dependencies to be contained in a single directory, protecting your core Python installation from conflicts. If anything goes wrong you can delete the virtual environment without needing to re-image your entire SD card.

      To create a Python 3 virtual environment in a sub-folder named “venv” use:

      python3 -m venv venv

      This creates a self-contained Python 3 system. Activate it using:

      source venv/bin/activate

      You should notice the name of the virtual environment appear in front of your command prompt.

      While activated any Python libraries that are installed will be installed in this virtual environment and not interfere in your default Python installation.

      Note: We created a Python 3 environment so going forward any use of “Python” will automatically refer to Python 3.

      Install Luma OLED Python Library

      To install the library run the following command:

      python -m pip install --upgrade luma.oled

      Install Luma Examples

      It’s worth installing the Luma examples as they will allow you to test your screen.

      Check we are in the project folder:

      cd ~/oled-screen

      Then ensure git is installed:

      sudo apt install -y git

      Then clone the examples repository:

      git clone https://github.com/rm-hull/luma.examples.git

      The following dependencies may need to be installed for the examples to work correctly:

      sudo apt install -y python3-pil libjpeg-dev zlib1g-dev python3-av
      sudo apt install -y libfreetype6-dev liblcms2-dev libopenjp2-7 libtiff5 -y

      Now we should be able to run some examples:

      cd luma.examples
      cd examples

      List the examples with:

      ls

      Finally run an example of your choice. Good examples are:

      python 3d_box.py

      or

      python crawl.py

      By modifying these examples you can create your own scripts for your projects.

      To get the “sys_info.py” example to run I needed to run:

      pip install psutil

      Deleting the Python Virtual Environment

      The useful feature of Python Virtual Environments is that you can delete the folder and remove all the changes that were made by installing libraries using “apt” and “pip”. Earlier in this article we created the folder “luma-env” within our “oled-screen” project folder. To remove the virtual environment

      rm -rf ~/oled-screen/venv

      This will leave the oled-screen folder and any other files in it.

      Increasing I2C Bus Speed

      If you are using your OLED screen for animations or videos it is worth increasing the bus speed of the interface as it can improve performance. Please see the Change Raspberry Pi I2C Bus Speed post .

      Troubleshooting

      If your screen isn’t working you should start at the beginning of this tutorial and work through it. Here are some thing to consider :

      • Did you enable I2C and install “python3-smbus” and “i2c-tools”?
      • Are the four module connections correct? Did you get SDA and SCL mixed up?
      • Did “i2cdetect -y 1” give you the address of the display on the I2C bus?
      • If your screen is using an address other than 0x3c did you adjust the Python script?

      Buy a Miniature OLED Screen

      These screens are available from a number of retailers so take a look and pick one that is convenient for your location :

      • eBay (US)
      • eBay (UK)
      • Amazon

      Read the descriptions carefully as some OLED display modules use the SPI interface rather than I2C. Those are fine but you’ll need to follow a different tutorial to use that style.

      Some of the product links on this page are affiliate links. I receive a small commission based on purchases made via these links. The price you pay is the same.

      Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
      Previous ArticleRaspberry Pi RetroPie Shutdown Button
      Next Article Cheap SD Cards from eBay are Fake

      Related Posts

      Disable SSH Password Login on Raspberry Pi

      How to Add a Raspberry Pi Pico Reset Button

      Pi Pico Onboard LED

      42 Comments

      1. Jes Woodland on April 20, 2018 7:53 am

        Thanks Matt. This has been a really helpful tutorial. There is very little info regarding these little screens beyond setting them up. This is far and away the most concise and well explained tutorial I have read about displaying your own images.

        Reply
      2. Pietro on May 15, 2018 5:07 pm

        Hello,
        Thank you for the helpful tutorial.
        I have a problem while installing the python library. When i execute the command

        sudo python setup.py install

        i get the following output:

        Extracting in /tmp/tmpoaIjab
        Traceback (most recent call last):
        File “setup.py”, line 4, in
        use_setuptools()
        File “/home/pi/Adafruit_Python_SSD1306/ez_setup.py”, line 128, in use_setuptools
        return _do_download(version, download_base, to_dir, download_delay)
        File “/home/pi/Adafruit_Python_SSD1306/ez_setup.py”, line 108, in _do_download
        _build_egg(egg, archive, to_dir)
        File “/home/pi/Adafruit_Python_SSD1306/ez_setup.py”, line 57, in _build_egg
        with archive_context(archive_filename):
        File “/usr/lib/python2.7/contextlib.py”, line 17, in __enter__
        return self.gen.next()
        File “/home/pi/Adafruit_Python_SSD1306/ez_setup.py”, line 88, in archive_context
        with get_zip_class()(filename) as archive:
        File “/usr/lib/python2.7/zipfile.py”, line 770, in __init__
        self._RealGetContents()
        File “/usr/lib/python2.7/zipfile.py”, line 813, in _RealGetContents
        raise BadZipfile, “File is not a zip file”
        zipfile.BadZipfile: File is not a zip file

        and library does not install. How can I solve this? Thank you!

        Reply
        • Matt on May 15, 2018 5:38 pm

          There seems to be an issue with a missing file. Someone has raised this on the Adafruit github page and they have assigned the issue for someone to investigate. https://github.com/adafruit/Adafruit_Python_SSD1306/issues/22. Hopefully they will resolve it soon.

          Reply
      3. Ivan Kuzev on July 17, 2018 4:00 pm

        Is it possible to connect two screens?

        Reply
        • Matt on August 3, 2018 10:43 am

          It should be possible, but you would need a screen that allowed you to change the default I2C address. Some allow this by soldering two contacts together.

          Reply
        • Kevin Ackland on September 13, 2018 9:08 pm

          Hi Ivan, you can get an I2C multiplexer to add 8 screens. I think you can get 2 x 8 channel multiplexers to 16 screens working

          Reply
      4. Robin Hood on August 7, 2018 8:16 pm

        Matt- The reason why the PCB said 0x78 and you’re reading 0x3C from i2c-tools is:

        I2c-tools shifts the entire address to the left by 1 (adding the last bit for R/W). Shift 0x3C to left by 1 gives you 0x78 (and obviously vise versa).

        All the best!

        Reply
        • Matt on August 7, 2018 8:30 pm

          Thanks for explaining that. I’ve just Googled it and understand now. 0x3c is these 7 bits 111100 but once the R/W bit is included it becomes these 8 bits 1111000 which is 0x78.

          Reply
      5. frank on September 6, 2018 5:43 pm

        I had to install python3-dev before the setup script ran ok. *sudo apt-get install python3-dev*

        Reply
        • Matt on September 10, 2018 8:48 pm

          python3-dev should already be installed in the latest Raspbian image.

          Reply
          • Jez McKean on June 8, 2019 9:44 pm

            Not in the `-lite` image.

            Also needed `setuptools`, Image/PIL/pillow (?!), and RPi.GPIO, but I couldn’t get them all installed at this time, so I gave up for now.

            Reply
            • Matt on June 17, 2019 10:16 pm

              I’ve just used this guide on a project and have made some updates. I think you have to install more libraries if using Raspbian Lite.

              Reply
      6. don kingdon on October 21, 2018 6:47 pm

        Thanks for the tutorial – had my screen up and running in about 30 seconds with your excellent direction

        Reply
      7. Bob Random on October 31, 2018 3:55 pm

        THANK YOU SOOOO MUCH!
        I tried to get it work for hours with the official tutorial of the screen, but it was far to complicated and did’nt work.
        Luckily i found this Tutorial, it saved me from a lot of wasted time <3

        Reply
      8. Mucho on February 11, 2019 1:04 pm

        Hello! This is really great and I got it to work perfectly. I was wondering where I would be able to change the GPIO pins as I want to set my relais there (respectively the setup forsees so).
        I couldn’t find the Pins 1,3,5,14 anywhere assigned in the code.
        Thanks for your help.

        Reply
        • Matt on February 13, 2019 1:16 pm

          1 and 14 are 3.3V and Ground. You can use any of the other power pins on the header :
          Raspberry Pi GPIO pinout
          There is only 1 other 3.3V pin and that is pin 17. There are plenty of Ground pins.

          The I2C pins are the defaults. You can configure a new software I2C interface by editing the /boot/config.txt file and adding :
          dtoverlay=i2c-gpio,i2c_gpio_sda=5,i2c_gpio_scl=6
          This would set up a new interface at /dev/i2c-3. However I’ve never tried this myself.

          To detect the device on the new interface you can use :
          i2cdetect -y 3

          Reply
          • Mucho on February 25, 2019 4:15 pm

            thank you MATT, I edited to config.txt and got an output from the i2cdetect -y 3 command, but the result was empty… meaning no detection.

            I am assuming that with i2c_gpio_sda=5 and i2c_gpio_scl=6 pins 5 and 6 are meant, I would change these to let’s say 19 and 21?

            Then again, I read something about a BUS and that I could control different interfaces with sam pins… ughhh. difficult & clueless I am

            Reply
            • Matt on February 27, 2019 1:31 pm

              With the dtoverlay the numbers are GPIO references not physical pin numbers. So i2c_gpio_sda=5 means GPIO5, physical pin 29.

              Reply
          • Christopher D Lawrence on December 2, 2021 8:27 pm

            This is extremely helpful.

            I have one OLED running stats.py fine, and would like to add a second OLED with another script running, like shapes.py or animate.py.

            Assuming I set up the second software I2C using the steps above, how do I then ‘point’ the second script to run on the second OLED? Do the scripts default to run on y 1 / 0x3c, and it’s just a case of manually editing the script to look for the new device?

            Reply
      9. G. Adam on March 2, 2019 1:41 pm

        minor typo:

        it should spell “sudo apt-get upgrade” and not “ugrade”

        Reply
        • Matt on March 2, 2019 6:35 pm

          Well spotted. I have updated the text 🙂

          Reply
      10. Iván on April 18, 2019 10:47 pm

        Is the screen compatible with the Raspberry Pi Zero?

        Reply
        • Matt on May 2, 2019 12:47 pm

          It works via I2C so should work just fine on the Pi Zero.

          Reply
      11. Jaimys on May 11, 2019 3:57 am

        Hi, fantastic tutorial – very clear!

        I was wondering if you would know why when using this i2c screen it seems to effect my ability to also use a DS18B20 temperature sensor? (DS18b20 connects to BCM 4 using the One-Wire (w1) protocol).

        Before detecting the OLED, when I run the following in cmd:

        cd /sys/bus/w1/devices
        ls

        It returns a serial number (28-xxxx).
        After I connect the i2c screen it seems to replace the temp sensor – replaced with a set of DS18b20 unrelated serial numbers… Any thoughts on what’s going on would be greatly appreciated!

        Reply
      12. TC on June 18, 2019 8:33 pm

        I’ve got an OLED display that displays in blue/yellow – it’s also based on the 1306. How would I make an image that makes use of both of those colours? I’m guessing use two colours in the image file, but which ones?

        Silly question, but I’m new to all this!

        Reply
        • Matt on June 26, 2019 6:16 pm

          I haven’t got one of those blue/yellow boards but I suspect the colour is fixed in particular zones of the screen. I’ve only ever seen the different colours at the top and bottom of the screens.

          Reply
      13. ben on July 17, 2019 9:36 pm

        how do you chang the screen size as you stated from 128×32 to 128×64 i cant figure how to do it please help

        Reply
        • Matt on September 1, 2019 11:16 pm

          Edit the example python script using a text editor and make the change as described in the “Screen Size Adjustment” section. You can edit the example scripts on the command line using :
          sudo nano shapes.py
          Make the change and then save/quit using CTRL-X, Y then ENTER.

          Reply
      14. M Gardiner on May 18, 2020 7:06 pm

        Hello, Followed this and almost got it working only issue I am presented with is right at the end. See below. If anyone could help would be much appreciated.Traceback (most recent call last):
        File “monitor.py”, line 26, in
        from PIL import Image
        ImportError: No module named PIL

        Reply
        • Matt on May 19, 2020 12:48 pm

          Did you start with the latest version of Raspbian? I ran through this post myself when I was rebuilding my Pi-Hole system. I seem to remember making some changes to the list of package installs due to a change in the PIL package.

          Reply
      15. Sidney Tupper on June 2, 2020 11:57 pm

        Regarding my last post, about a problem connecting with i2c to the display … I found that one of my breadboard wires was not conducting. It works fine. Thanks for the tutorial. Sorry if I wasted your time thinking about my post.

        Reply
      16. andy on September 8, 2020 6:19 pm

        THank you for your tutorial . I managed to get my OLED screen to work on my Pi3 but cant get it to work on the Pi zero w.
        After doing every step by step initially on the zero it wouldnt show up on the oled detect command. I then put the SD card into my Pi3 and it did detected the screen plus the examples straight away.
        Is there something i missed with the set up for the zero which is stopping this?

        Reply
        • Matt on September 15, 2020 8:39 am

          Did you try i2cdetect -y 0?

          Reply
      17. Barry on November 4, 2020 3:41 pm

        Matt

        I’ve just resolved it by running ‘pip3 install Adafruit-BBIO’ just a guess. the screen worked immediately

        Thanks

        Reply
      18. Alvin G on December 18, 2020 3:05 pm

        is it possible to set up 2 oled display on a Pi Zero?

        Reply
        • Matt on January 20, 2021 7:15 pm

          I2C allows multiple devices on the same bus as long as you can give each device a unique ID. If your screen allows you to change to an alternative address you should be able to run two on the same pins.

          Reply
      19. Kenton White on May 27, 2021 11:33 am

        Hi Matt, I’ve got a 128×32 screen from PiHut, and I’ve been able to install and run as you suggest above. But when I run the stats.py, I get the variables preceded by a b’ and followed by \n’. I can’t see where these added characters are coming from.

        Reply
        • zicoon on October 22, 2021 2:27 pm

          i’ve the exact same problem but with an 128×64 and i can’t see the solution…

          Reply
        • zicoon on October 22, 2021 2:39 pm

          Just found the solution after commenting -.-

          https://stackoverflow.com/questions/37016946/remove-b-character-do-in-front-of-a-string-literal-in-python-3

          you need to decode the string you want to display as utf-8

          Reply
      20. dieter meijer buschbaum on November 2, 2022 8:11 pm

        HI THERE WELL I GOT THE OLED TO WORK. BUT MY ISSUE IS IR DOES NOT WORK WHEN I REBOOT MY PI? WHAT HAVE I DON WRONG?LOL

        Reply
        • Matt on November 13, 2022 10:00 pm

          If you want a script to run when your Pi reboots you need to launch the script autonatically.
          You can do this using cron:

          crontab -e

          and adding the following line to the end :

          @reboot python3 /home/pi/stats.py &

          You cron file will look like this :

          # For more information see the manual pages of crontab(5) and cron(8)
          #
          # m h dom mon dow command
          @reboot python3 /home/pi/stats.py &

          Save and exit using CTRL-X, Y then ENTER.

          Obviously replace “stats.py” with the name of the script you want to run.

          Reply
      21. Darren on January 12, 2025 8:39 pm

        Working perfectly in 2025. Perfect instruction. Many thanks.

        Reply
      Leave A Reply Cancel Reply

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

      Recent Posts
      February 16, 2024

      Disable SSH Password Login on Raspberry Pi

      March 13, 2023

      Elecrow Meteor IPS Touchscreen with RGB LEDs

      December 26, 2022

      Pi Pico Pinout Display on the Command Line

      December 23, 2022

      How to Add a Raspberry Pi Pico Reset Button

      November 20, 2022

      Pi Pico Onboard LED

      Categories
      • 1-wire
      • 3D Printing
      • Add-ons
      • BBC Micro:bit
      • BerryClip
      • Books
      • Camera Module
      • Cases
      • Events
      • General
      • Hardware
      • I2C
      • Infographics
      • Interfaces
      • Minecraft
      • Model A+
      • Model B+
      • News
      • Pi Models
      • Pi Pico
      • Pi Zero
      • Power
      • Programming
      • Python
      • Raspberry Pi OS
      • Raspbian
      • RetroGaming
      • Robotics
      • Sensors
      • Software
      • SPI
      • Tutorials & Help
      Tags
      Arduino audio battery berryclip Birthday bluetooth cambridge camera CamJam DigiMakers display games GPIO I2C interface Kickstarter Kodi LCD LED Linux media Minecraft Model A motionEyeOS PCB photography photos Pi-Lite Pi Pico power python Raspberry Jam Raspberry Pi Bootcamp raspbian Retrogaming retroPie screen SD card security sensor SPI SSH temperature ultrasonic video
      Raspberry PI Related
      • Adafruit Blog
      • Average Maker
      • Official RaspBerry Pi Site
      • Raspberry Pi Pod
      • RasPi.tv
      • RaspTut
      • Stuff About Code
      Tech Resources
      • MattsBits – Pi Resources
      • Microbit Spy
      • Technology Spy
      Archives

      Entries RSS | Comments RSS

      This site is not associated with the official Raspberrypi.org site or the Raspberry Pi Foundation. Raspberry Pi is a trademark of the Raspberry Pi Foundation.

      Copyright © 2025 - All Rights Reserved - Matt Hawkins

      About

      Unofficial site devoted to the Raspberry Pi credit card sized computer offering tutorials, guides, resources,scripts and downloads. We hope to help everyone get the most out of their Pi by providing clear, simple articles on configuring, programming and operating it.

      Popular Posts
      September 19, 2014

      Top 5 Reasons The Raspberry Pi Sucks

      July 27, 2012

      16×2 LCD Module Control Using Python

      October 20, 2013

      Analogue Sensors On The Raspberry Pi Using An MCP3008

      Latest Posts
      February 16, 2024

      Disable SSH Password Login on Raspberry Pi

      March 13, 2023

      Elecrow Meteor IPS Touchscreen with RGB LEDs

      December 26, 2022

      Pi Pico Pinout Display on the Command Line

      Mastodon YouTube Instagram Facebook Pinterest RSS

      Entries RSS | Comments RSS

      This site is not associated with the official Raspberrypi.org site or the Raspberry Pi Foundation. Raspberry Pi is a trademark of the Raspberry Pi Foundation.

      Copyright © 2025 - All Rights Reserved - Matt Hawkins

      mastodon.social@RPiSpy

      Type above and press Enter to search. Press Esc to cancel.