Display Raspberry Pi Statistics on a 128x32 Mini OLED

View the Project on GitHub

Display Raspberry Pi Statistics on a 128x32 Mini OLED

This page discibes version 2 of displaypistats. Version 1 is depreciated but the old page can be found here

Table of Contents


displaypistats is an installation package for raspios to automate the set up to display Raspberry Pi Statistics on a 128x32 Mini OLED.

OLED Image sample

The idea was to take the manual process outlined by lady ada, Brent Rubell and, Danny Nosonowitz here https://bit.ly/3rjHarP and wrap all the individual configuration steps into one easy to install .deb package.


There are two ways to install this package one, the automated easy way and two, the manual way:

Automated install:

curl -sS https://displaypistats.loonix.ca/displaypistats.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/displaypistats.gpg
sudo curl -s --compressed -o /etc/apt/sources.list.d/displaypistats.list "https://displaypistats.loonix.ca/displaypistats.list"
sudo apt update
sudo apt -y install displaypistats
sudo reboot

Manual install

  1. Download the file from the Files section here - for example wget https://github.com/l00nix/displaypistats/blob/main/displaypistats_2.0-0_all.deb
  2. Install the package with sudo dpkg -i ./displaypistats_2.0-0_all.deb Note: Ignore the error message that the package failed to install.
  3. Finish the installation by retrieving the required dependencies sudo apt-get -f install - The dependencies of this package are “python3, python3-pip, and python3-pil”
  4. Reboot

The display should now display the following stats on the OLED:

Explained - What does the package actually do?

  1. The package installs a python script that is responsible for displaying the stats on the OLED in /usr/local/etc/displaypistats (there are also a man page and copyright file that are being installed)
  2. The postinst script of the package checks if the I2C setting is enabled on the Pi and if not enables it.
  3. Next the postinst script checks if the adafruit-circuitpython-ssd1306 library is installed and installs it if not.
  4. Next the postinst script adds the python script in #1 to the rc.local startup file so the OLED starts displaying on system restart.
  5. Finally the postinst scripts sets the reboot flag in the system

The postinst script in detail


echo "Check if i2c is enabled and enable if not:"

I2C=`/usr/bin/raspi-config nonint get_i2c`
if [ $I2C == 0 ]; then
   echo "I2C is already enabled!"
   /usr/bin/raspi-config nonint do_i2c 0
   echo "I2C has been enabled!"

echo "Check if adafruit-circuitpython-ssd1306 library is installed and install if not:"

/usr/bin/pip3 list | grep adafruit-circuitpython-ssd1306 &> /dev/null
if [ $? -eq 0 ]; then
   echo "adafruit-circuitpython-ssd1306 library is already installed!"
    echo "Installing adafruit-circuitpython-ssd1306 library!"
    /usr/bin/pip3 install adafruit-circuitpython-ssd1306

echo "Adding displaypistats to startup"
NL=$(wc -l /etc/rc.local)
sed -i ${NL%% *}'i\sudo /usr/bin/python3 /usr/local/etc/displaypistats &' /etc/rc.local

echo "Telling system that reboot is required"
touch /var/run/reboot-required
echo "*** System restart required ***" > /var/run/reboot-required

The python script that actually displays the stats on the OLED


# SPDX-FileCopyrightText: 2017 Tony DiCola for Adafruit Industries
# SPDX-FileCopyrightText: 2017 James DeVito for Adafruit Industries
# SPDX-License-Identifier: MIT

# This example is for use on (Linux) computers that are using CPython with
# Adafruit Blinka to support CircuitPython libraries. CircuitPython does
# not support PIL/pillow (python imaging library)!

import time
import subprocess

import sys

from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

# Create the I2C interface.
i2c = busio.I2C(SCL, SDA)

# Create the SSD1306 OLED class.
# The first two parameters are the pixel width and pixel height.  Change these
# to the right size for your display!
disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)

# Clear display.

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new("1", (width, height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0, 0, width, height), outline=0, fill=0)

# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height - padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0

# Load default font.
font = ImageFont.load_default()

# 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('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 9)

while True:

    # Draw a black filled box to clear the image.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)

    # Shell scripts for system monitoring from here:
    # https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load
    cmd = "hostname -I | cut -d' ' -f1"
    IP = subprocess.check_output(cmd, shell=True).decode("utf-8")
    cmd = 'cut -f 1 -d " " /proc/loadavg'
    CPU = subprocess.check_output(cmd, shell=True).decode("utf-8")
# working    cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%s\" ,$3,$2}' && free | awk 'NR==2{printf \" %.1f%%\" ,$3*100/$2}'"
    cmd = "free -m | awk 'NR==2{printf \"Mem: %.2f%% of \" ,$3*100/$2}' && free -hm | awk 'NR==2{printf \"%s\", $2}'"
    MemUsage = subprocess.check_output(cmd, shell=True).decode("utf-8")
    cmd = 'df -h | awk \'$NF=="/"{printf "Disk: %d/%d GB  %s", $3,$2,$5}\''
    Disk = subprocess.check_output(cmd, shell=True).decode("utf-8")

    # Write four lines of text.

    draw.text((x, top + 0), "IP: " + IP, font=font, fill=255)
    draw.text((x, top + 8), "CPU load: " + CPU, font=font, fill=255)
    draw.text((x, top + 16), MemUsage, font=font, fill=255)
    draw.text((x, top + 25), Disk, font=font, fill=255)

    # Display image.

Change which network adapter’s IP address being displayed

Most Raspberry Pis have two network adapters - wifi and physical NIC (except for the Compute Module 4 which has either wifi only or no wifi) . By default the displayrpistats script displays the IP address that is assigned to the first network adapter. In most cases this is the IP assigned to the wifi/wlan adapter. If you want to change which IP address is being displayed on the OLED display you need to change the following line in the python script /usr/local/etc/displaypistats

hostname -I | cut -d' ' -f1


hostname -I | cut -d' ' -f2

Rotate the direction of the Display

Depending on how you are connecting the OLED display to your Raspberry Pi you may have to change the rotation of the text displayed on the OLED. If you want to change the rotation you need to add the following line in the python script /usr/local/etc/displaypistats

disp.rotation = 2

just after the line

disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)

The rotation should be a value of 0, 1, 2 or 3 only, where 0 is no rotation, 1 is rotate 90° clockwise, 2 is 180° rotation and 3 represents 270° rotation. See ssd1306 Documentation page 4.


   Alexander Rau aka. loonix (alexander@rau.ca)
   Contributors: lady ada, Brent Rubell, Danny Nosonowitz