In this guide, I’ll show you how to program a 128×64 I2C OLED stats display as a quick dashboard for your Raspberry Pi. I use this script on my Raspberry Pi Desktop Case and a lot of people have asked me for some more in-depth setup and programming instructions to get it running.
This guide is written specifically for a Raspberry Pi 4B running Raspberry Pi OS Buster, although you should be able to work through it for other Raspberry Pi models.
Update: For those running Raspberry Pi OS Bullseye, please use my revised guide.
Here’s a video guide to connect and program the OLED stats display, read on for the full written guide and script modifications.
What You Need For This Project
Amazon Affiliate Links
- Raspberry Pi 4 – Buy Here
- Ice Tower – Buy Here
- Micro SD Card – Buy Here
- Raspberry Pi Power Supply – Buy Here
- I2C OLED Display – Buy Here
- Female to Female Jumper Cable – Buy Here
Banggood Affiliate Links
Connecting Your I2C OLED Stats Display To Your Raspberry Pi
We’ll start by hooking the display up to the Raspberry Pi. To do this, you’ll need a 4 wire female to female jumper cable. The colours on the cable don’t matter, they’re just there to help you keep track of which wire goes to which terminal.
The OLED display’s pins are labeled on the front, which seems to confuse a lot of people, especially when they’ve installed the display into a case or housing and the front area above the screen is no longer visible.
These are most commonly GND, VCC, SCL, and SDA. Don’t just copy this arrangement though, make sure you check your own display as there are versions of this display that have the VCC and GND pins the other way around.
These displays don’t have reverse polarity protection, so if you connect them incorrectly (even just once) then it’s quite likely that they’ll be damaged and will no longer work, even if you correct the wiring afterward.
Plug your ribbon cable into these pins and then make a note of which colour you’ve got connected to which of the four pins. If you’re installing the display into your case before connecting it then it’s a good idea to write down which colour is connected to which pin so that you don’t forget.
Next, you need to plug the other ends of the jumpers into your Raspberry Pi’s GPIO pins. The Pi’s GPIO pinout diagram can be found quite easily online and is available on the official Raspberry Pi website.
Make sure that your Pi is off and the power is disconnected before plugging or unplugging jumpers from the GPIO pins. You don’t want to short a connection or plug a lead into the incorrect pin by mistake and not have a chance to check your connection before powering it up.
You’ve got a few options for the GND and VCC jumpers. I usually plug the GND jumper (mine is green) into Pin 14, but you can use any pin labelled Ground. I plug the VCC jumper (mine is blue) into Pin 1, which is a 3.3V power pin. Again, you can use any of the 3.3V or 5V power pins as this display can run on both 3.3V and 5V.
Next, we need to connect the communication jumpers SCL and SDA, which just get plugged into the corresponding GPIO pins. Plug SCL (mine is purple) into Pin 5 and SDA (mine is white) into Pin 3. Don’t get confused between the GPIO numbers and the Pin numbers, ignore the GPIO numbers on the diagram and just go by the SDA and SCL labels and the corresponding pin numbers.
Check all of your connections again and you’re then ready to power your Pi up and get started with programming the display.
Programming The OLED Stats Display
Once you’ve booted up your Pi, you should be on the Raspberry Pi OS desktop. It’s possible to do this installation on a headless Pi as well, it’s just easier to make the required layout changes to the script in the full version first.
Enabling & Testing I2C Communication
To get the display to show our Raspberry Pi’s performance stats, we’re going to be running a Python script. Before we do this we need to enable I2C communication on the Pi as this is how it communicates with the display. You can either do this through the preferences menu or by typing this command into a new terminal window:
Select interfacing options, then I2C and then select Yes and then reboot the Pi by typing in the following command:
Once your Pi has rebooted, you need to check that the following 3 libraries have been installed. You may already have them installed, but it’s worth checking. Run each one of these commands individually in your terminal:
sudo apt-get install python-smbus sudo apt-get install i2c-tools sudo pip3 install Adafruit_BBIO
Once you’ve done that then you can check that your Pi is able to see that your display is connected. You can do this by typing in the following command:
sudo i2cdetect -y 1
You should then see a table, similar to the below, that shows a single pair of characters in it. This code indicates the I2C address of your display.
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
If your table is returned blank then you’ve either got a wiring issue or I2C communication isn’t turned on. If you get a table full of characters then you’ve probably made a wiring mistake as this happens if SDA is shorted to ground. Go back and re-check your connections to your Pi and display and re-check that you’ve got I2C communication enabled after a reboot.
Don’t proceed with trying to get the script to work if you don’t get the correct response in this step, if your Pi isn’t able to see the display thats connected to it then it won’t be able to communicate with it to get anything displayed.
Downloading And Running The Adafruit Stats Script
Next let’s have a look at the python script and how to install it.
The script is one of the example scripts provided in the Adafruit Python SSD1306 library, with some tweaks. There is a note on the Github page to say that this is a depreciated library, but that doesn’t mean that you can’t use it or that it will no longer work. It just means that they have developed a better or more recent set of libraries. We’re not so much interested in the library as we are in the stats example script, so we’re going to use it anyway.
Download the script by typing in the following commands:
sudo python -m pip install --upgrade pip setuptools wheel git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
Next, navigate to your library’s directory:
Then run the setup script to install the library. Make sure that the python version you choose here matches the version you are going to run the actual script in.
sudo python3 setup.py install
Next navigate to the examples directory in the Adafruit directory:
Then execute the stats script:
You should then see your Pi’s stats shown on the display.
You can see the text isn’t that clear, there are a few weird characters on the display and the CPU temperature isn’t displayed. So we’re going to try and fix those in the following section.
Adjusting The Display Content & Layout
The following steps are done on the Raspberry Pi OS desktop and edits to the script are made in Thonny Python IDE (which comes pre-installed).
Open up the examples folder in the Adafruit library which you were working on in the previous step and use the Thonny Python IDE to open up the stats script so that you can edit it.
Copy these two portions of the script below and paste them into your script on your Pi.
Add the following two lines to the script at the end of the “# Shell scripts for system monitoring from here” section
cmd = "vcgencmd measure_temp |cut -f 2 -d '='" temp = subprocess.check_output(cmd, shell = True )
Replace the following lines in the “# Write two lines of text” section.
draw.text((x, top), "IP: " + str(IP,'utf-8'), font=font, fill=255) draw.text((x, top+8), str(CPU,'utf-8') + " " + str(temp,'utf-8') , font=font, fill=255) draw.text((x, top+16), str(MemUsage,'utf-8'), font=font, fill=255) draw.text((x, top+25), str(Disk,'utf-8'), font=font, fill=255)
Have a look at the video at the begining if you’re unsure about which lines to replace or change.
Running the script you can now see that the characters are gone and the temperature is being displayed alongside the CPU load:
This is where I left the display in my original video, but it looks a lot better if you use a better font, which allows the text to fit into the width limit and uses the full height of the display, so let’s look at that next.
First, let’s change the display size so that we’re using all of the display’s pixels so that the text is a bit clearer. This display is actually a 128 x 64 display, not the 128 x 32 display which is set by default.
Comment out the line near the top which sets the display size to 128 x 32:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
And then uncomment the line which sets the display size to 128 x 64:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
If you run the script you’ll now see that the text is much clearer, but it all bunched up in the top half.
We can play around with the spacing, but this font is just not great for this stats layout. So let’s now look at changing the font.
Download the font PixelOperator.ttf from https://www.dafont.com/pixel-operator.font and then unzip the contents of the download.
Look for the standard pixel operator font and copy the font into the same directory as your stats script.
You’ll then need to copy the filename of your font, along with the extension, to put into the script.
Comment out the line which loads the default font:
# Load default font. # font = ImageFont.load_default()
Uncomment the line which loads the replacement font and paste your filename into it, keeping the inverted commas on either side. You can also play around with the font size by editing the number after the font name, I’ve used 16 here.
# Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as the python script! # Some other nice fonts to try: http://www.dafont.com/bitmap.php # font = ImageFont.truetype('PixelOperator.ttf', 16)
If you now run the script you’ll see that the text is a bit taller and is in your new font, but it’s still bunched up at the top of the display. So the last thing we need to do is adjust the layout.
Adjusting the layout is a bit of a guessing game until you get it looking the way you’d like it to, or just copy the numbers I’ve used:
draw.text((x, top+2), "IP: " + str(IP,'utf-8'), font=font, fill=255) draw.text((x, top+18), str(CPU,'utf-8') + " " + str(temp,'utf-8') , font=font, fill=255) draw.text((x, top+34), str(MemUsage,'utf-8'), font=font, fill=255) draw.text((x, top+50), str(Disk,'utf-8'), font=font, fill=255)
When you’re done, you should now have a clear OLED stats display running on your Pi.
This script will continue to run and update the display as long as you’ve got your IDE open. But we want it to run all the time and run on startup, so there’s one last thing to do.
Setting The Script To Run Automatically On Startup
Copy the OLED stats display script and the font into your home directory.
Open crontab by typing the following command into your terminal:
If this is the first time you’re opening crontab then select 1 as your editor and hit enter.
Add the following line to the end of the file to run the script:
@reboot python3 /home/pi/stats.py &
You might need to change the directory to suit the directory that you’ve got your script saved into.
Also don’t forget the & at the end to tell the Pi to continue starting up and run the script in the background.
Save the file when you exit and then try rebooting your Pi to see if it is working correctly.
If it is all working correctly then you should have a working stats display which starts up automatically each time your Pi boots up.
If you’re using an Ice Tower with your stats display, plug the fan’s power cables in to the 5V and GND GPIO pins next to the display’s connections as shown below.
Let me know what you think of this OLED stats display in the comments section below and let me know what you’re using it for. Have you built it into your own case?