SARPi Project - Slackware Linux on a Raspberry Pi


Mini Tower Case for the Raspberry Pi with 0.96" SSD1306 I2C OLED display module (128×64)

When it comes to Raspberry Pi Mini Tower enclosures, or cases as they're generally referred to, there are quite a few currently available on the market to choose from. At the cheaper end of the price range there's the ElectroCookie Raspberry Pi Mini Tower cases, for the Raspberry Pi 3, 4, and 5. Rising up the tiered pricing charts is the Pironman 5-MAX Dual NVMe M.2 SSD PCIe PC Case for the Raspberry Pi 5 from Sunfounder with enough cooling capacity to impress Antarctica and create a baroclinic extratropical cyclone in the right/wrong environment. 🌪

As usual, and expected, there are multiple manufacturers of Raspberry Pi Mini Tower case designs, all offering a slightly different approach and concepts to accommodate and suit almost all end-user requirements. In addition to the aforementioned ElectroCookie and Pironman, there's CUBE Pi (a.k.a. Yahboom), Elecrow, Seeed Studio, GeeekPi (a.k.a. 52Pi) and various offerings on Amazon, Alibaba, and Etsy, to name just a few.

It boils down to personal preference which Mini Tower case is best or most suitable for your needs. At the SARPi Project we honed in on the GeeekPi [52Pi] range of ABS enclosures.

52Pi Mini Tower Kits for Raspberry Pi

We found the 52Pi Mini Tower Kits for Raspberry Pi to be very interesting and very good value for money. These come in various iterations; ZP-0187, ZP-0172, ZP-0130, ZP-0129, and ZP-0128, each offering a slightly different configuration with a similar form factor and an identical footprint. Some of these have been phased out and discontinued by the manufacturers. However, some third-party independent suppliers may still have available stock of these older products that are on longer in production.

After investigating and considering multiple factors on which GeeekPi Mini Tower case would best suit our requirements, we agreed and made a decision to get hold of a 52Pi ABS Case Kit for Raspberry Pi 5 [SKU: ZP-0187] [better known as the GeeekPi N07 Minitower NVMe NAS Kit for Raspberry Pi 5] for testing. We chose this particular Mini Tower design over the alternatives because it featured an Ice Tower cooler and an N07 M.2 NVMe SSD M-key expansion board. These two items alone, bought separately, are almost the same price as the entire Mini Tower package. Another deciding feature was the included 0.96" SSD1306 I2C OLED display module (128×64), which seemed a very cool and useful addition.

GeeekPi N07 Minitower NVMe NAS Kit for Raspberry Pi 5GeeekPi N07 Minitower NVMe NAS Kit for Raspberry Pi 5
GeeekPi N07 Minitower NVMe NAS Kit for Raspberry Pi 5

GeeekPi N07 Minitower NVMe NAS Kit for Raspberry Pi 5

52Pi ABS Case Kit: 52Pi ABS Case Kit for Raspberry Pi 5, with N07 PCIe M.2 M-Key NVMe SSD PCIe Peripheral Bottom Board and Ice Tower Cooler OLED for Raspberry Pi 5.

In this SARPi mini-project we have installed a Raspberry Pi 5 in the GeeekPi N07 Minitower NVMe NAS Kit, fitted a NVMe SSD to the N07 M.2 NVMe SSD M-key expansion board for storage, and installed Slackware AArch64 -current Linux on it. We also installed a Keyestudio DS3234 high precision Real Time Clock (RTC) module into out new Mini Tower case. We installed the RTC for three main reasons; 1) the I2C interface was being used by the 0.96" SSD1306 I2C OLED display module (128×64), so a conventional I2C RTC (such as the DS3231 that we'd normally install) was out of the question, and 2) because there was more than enough space for it, and 3) we do not have any faith or trust in the accuracy of the Raspberry Pi 5 onboard RTC, which has an external 32khz crystal, so limited by the accuracy of that (50ppm typical). Compare that to the DS3234 SPI-bus RTC module with an integrated temperature-compensated crystal oscillator (TCXO), providing ±2ppm accuracy from 0°C to +40°C and ±3.5ppm from -40°C to +85°C - which translates to a maximum drift of roughly one minute per year, making it far more precise than any standard crystal-based RTCs, like the DS1307 and PCF8523.

Ks0166 keyestudio DS3234 high precision real time clock (RTC) module
Ks0166 keyestudio DS3234 high precision real time clock (RTC) module

The spaciousness of the interior inside this enclosure is very welcome, there's a surprisingly large amount of it - enough to accommodate the largest 52Pi Ice Tower Cooler and then some! If you were ever looking for a viable compact, flexible, versatile, freestanding Raspberry Pi enclosure that doesn't break the bank, this may very well be it, or somewhat close.

SARPi Project muse views ... The 52Pi (GeeekPi) Mini Tower kits are also supported via GeeekPi absminitowerkit GitHub repository which offers an 'ABS mini tower kit driver and installation script' for the latest Raspberry Pi OS.

Although this isn't something we'll be covering in this mini-project, we'll certainly be looking into it at a later date!

Our Slackware Linux system's HOSTNAME is 'maia'. We will be setting up and configuring the 0.96" SSD1306 I2C OLED display module (128×64) to work in Slackware using Python 3 to display our own custom output.

Nonetheless, you're not here to read our musings on Raspberry Pi Mini Tower cases. So we're going to stop pontificating and "procrastinating now", and get on with this SARPi mini-project. 🤐 😁

SARPi Project muse views ... Below are some 'quick links' for you to quickly navigate this mini-project page.

Please also take note of the requirements for this mini-project in the "What's needed" section.

Quick Links

The 0.96" SSD1306 I2C OLED display module (128×64) mini-project
Things you will need for this mini-project
Connecting the 0.96" SSD1306 I2C OLED display module (128×64) to the Raspberry Pi GPIO header
Getting Started With The Basics
Confirming Hardware/Software Availability
Installing Required Python 3 Libraries Using pip
Python 3 Script for the 0.96" SSD1306 I2C OLED display module (128×64) [by the SARPi Project]
The SARPi 'oled_sysinfo.py' Python 3 Script Explained In Brief
How to run Python 3 scripts for the 0.96" SSD1306 I2C OLED display module (128×64)?
Downloading and running Python 3 luma.examples for the SSD1306 I2C OLED display module (128×64) [GitHub luma.examples repo]

What you will need for this Mini Tower mini-project

• A 0.96" SSD1306 I2C OLED display module (128×64), [optionally] installed in a 52Pi ABS Mini Tower case, that's connected to the Raspberry Pi's GPIO I2C interface.
• A Raspberry Pi with Slackware 15.0 ARM / AArch64 -current Linux operating system installed.
Python 3.8 [minimum] or later installed on your Slackware ARM / AArch64 Linux system!
• An Internet connection and/or means of installing/updating Python 3 software and libraries using pip.
• An Internet connection to download luma.examples from GitHub. [optional]

No additional pip installs are required beyond:

• luma.core (provides a pillow-compatible drawing canvas)
• luma.oled (interfaces OLED matrix with SSD1306 controller)
• smbus2 (dependency of luma.core - sends data and sequences of data to I2C bus)
• psutil (C-accelerated Python library for retrieving data on running processes and system utilization; CPU, memory, storage, network, sensors, etc.)
• pillow (dependency of luma.core - Python imaging library)

The 0.96" SSD1306 I2C OLED display module (128×64) mini-project

This mini-project involves; installing the popular 0.96" SSD1306 I2C OLED display module (128×64) on Slackware ARM / AArch64 Linux running on a Raspberry Pi device.

Whether the SSD1306 I2C OLED display module is fitted inside a Raspberry Pi enclosure/case or not isn't important. As long as the SSD1306 I2C OLED display module has been connected to the I2C interface correctly that's basically all that's required to get it up and running successfully.

The 0.96" SSD1306 I2C OLED display module (128×64) is useful for so many purposes and applications. Sure, it's less than an inch wide and very small compared to a conventional desktop PC or laptop screen, but you won't be using it to watch the latest cliché Marvel™ superhero movie, or browse the Internet on it. That's absolutely guaranteed and inevitable. 😄

SARPi Project muse views ... The SSD1306 driver with controller chip itself is manufactured by Solomon Systech, a Taiwanese semiconductor company. The SSD1306 is a single-chip CMOS OLED/PLED driver with controller for organic / polymer light emitting diode dot-matrix graphic display system. It consists of 128 segments and 64 commons. This IC is designed for Common Cathode type OLED display panels.

The 0.96" SSD1306 I2C OLED display module features a framebuffer-driven monochrome display with 128x64 true addressing, no internal column offset, and a colour depth of 1 bit per pixel (i.e. ON/OFF). There is no character grid at the hardware level and when you render text with 'draw.text(...)' you're rendering glyphs via 'pillow' (bitmap font or TrueType rasterised) ➡ converting that into pixels ➡ writing those pixels into the SSD1306 framebuffer ➡ sending the buffer via 'smbus2' over the I2C interface bus. So your rows in a script are just 'line_height * n' (and that’s basically pixel maths, not terminal rows). Therefore, with a 10px font (for example) each line consumes roughly 10–12 vertical pixels (depending on ascent/descent) for a total height of 64px - where 5 lines will fit comfortably and 6 lines is a bit of a squeeze.

The 0.96" SSD1306 I2C OLED display module is hugely popular and is readily available almost anywhere in the world. It has thousands (if not tens of thousands) of suppliers and retailers, from Amazon to eBay to Alibaba to ThePiHut to Adafruit and everywhere in between - online and offline. 💸

Connecting the 0.96" SSD1306 I2C OLED display module (128×64) to the Raspberry Pi GPIO header

The 0.96" SSD1306 I2C OLED display module needs just four wires in order to be powered and communicate with the Raspberry Pi using the I2C interface. If your SSD1306 I2C OLED display module is already installed in your Raspberry Pi case then all you'll need to do is connect the jumper housing or Dupont connectors/cables correctly. Otherwise, here's some instructions to wire the SSD1306 I2C OLED display module up to the Raspberry Pi.

SARPi Project muse views ... 🛑 STOP AND THINK! You should ONLY connect any wires to the Raspberry Pi or 0.96" SSD1306 I2C OLED display module with the power turned OFF! 🔌 ⚡

Examine the Raspberry Pi 40-pin GPIO header. Pin 1 (3V3) 3.3V power is closest to the SD card slot - see the diagrams below for reference.

Connect the 0.96" SSD1306 I2C OLED display module like this:

0.96" SSD1306 I2C OLED display module (128×64) wiring connections
0.96" SSD1306 I2C OLED display module (128×64) wiring connections

Raspberry Pi 40-pin GPIO (general-purpose input/output) header on all current boards
Raspberry Pi 40-pin GPIO (general-purpose input/output) header on all current boards

• The VCC connection from the 0.96" SSD1306 I2C OLED display module ➡ Raspberry Pi GPIO header pin 1 (3V3) 3.3V power. NEVER use the 5V pin or you'll risk damaging the OLED display module!
• The GND connection from the 0.96" SSD1306 I2C OLED display module ➡ any ground pin on the Raspberry Pi GPIO header (pin 6 or 9 are closest — whichever is more convenient).
• The SDA connection from the 0.96" SSD1306 I2C OLED display module ➡ Raspberry Pi GPIO header pin 3
• The SCL connection from the 0.96" SSD1306 I2C OLED display module ➡ Raspberry Pi GPIO header pin 5

SARPi Project muse views ... 💡 You'll already know what the VCC power and GND ground connections are for, power and earth.

The SDA connection is the single bidirectional path that both the Raspberry Pi and the 0.96" SSD1306 I2C OLED display module take turns communicating on this one wire (just like a walkie-talkie two-way radio). Data goes both ways over it so there's no separate send/receive connections needed.

The SCL connection does not carry any useful data - it's purely a timing/sync path that sends a steady tick-tock signal to keep everything coordinated, so the Raspberry Pi and the SSD1306 I2C OLED display module know exactly when to send or listen for data. Without the SCL connection there would be data-flow chaos. 😵

That's it - four straight connections. Pins 1, 3, 5 are conveniently next to each other on The Raspberry Pi GPIO header, and ground pins 6 and 9 are close by.

Before proceding, double-triple-check your 0.96" SSD1306 I2C OLED display module's wiring connections (some modules swap GND/VCC order). Use (3V3) 3.3V power ONLY for power and NEVER 5V.

Once you're done verifying the wiring and connections are correct and are satisfied it's all in order, plug in the power cable, power on the Raspberry Pi, boot into Slackware Linux, and consider that a job well done! 🖖

Getting Started With The Basics

So, following 52Pi's "How to assemble it?" instructions, we've fitted our Raspberry Pi 5 into the case and that's now been installed with, and running, Slackware AArch64 -current. Which is booting from a SSD that's installed on the N07 PCIe M.2 M-key NVMe SSD PCIe Peripheral Bottom Board mounted underneath the RPi inside the enclosure. We've connected the OLED screen display connector plug to the GPIO header of the Raspberry Pi 5. If you're looking for details on how to put this all together there's the aformentioned instructions on 52Pi's wiki page and also quite a few assembly video guides on YouTube. To install Slackware AArch64 -current you can follow the SARPi Project's Slackware Linux on a Raspberry Pi Installation tutorial on this website or the official software instructions available via the official Slackware Linux Project website.

If you've got the same or a similar setup as we have then it'll be straight-forward and very easy to follow this mini-project. Or, if you've just connected your SSD1306 I2C OLED display module to the Raspberry Pi GPIO header and looking for details on how to get it working in Slackware then it's just as easy to achieve success by following this mini-project's simple instructions.

SARPi Project muse views ... NOTE: As far as hardware is concerned, it doesn't matter if you're running a Raspberry Pi (1) with Slackware 15.0 ARM installed or a Raspberry Pi 5 with Slackware AArch64 -current installed. As long as you have; A) correctly connected the SSD1603 chipset OLED 128 x 64 display to the Raspberry Pi GPIO header, and B) Python 3.8 or later installed on your system, then you'll be able to achieve results and succeed in this SARPi mini-project.

Confirming Hardware/Software Availability

First off, you need to make sure that your Slackware system is fully up to date before doing anything else. Run 'slackpkg' or carry out whichever method you use to update your Slackware system.

Once that's been validated, you're going to need two very significant confirmations. These will be explained more as we get into this mini-project. For now, you'll be checking and verifing the status of:

1. Your kernel I2C status
2. The Python version that's installed on your Slackware Linux system

So now log in as 'root' to your Slackware system and open a terminal to the CLI. Then type the following and press :

root@maia:~# lsmod | grep i2c

This should be the output you see.

lsmod | grep i2c

SARPi Project muse views ... If you're not seeing any output from the 'lsmod | grep i2c' command it possibly means the I2C interface has not been enabled in your /boot/config.txt file. Check and look for a line in that file that reads 'dtparam=i2c_arm=on'. If the line is commented out (i.e. #dtparam=i2c_arm=on) then remove the '#' from the start of the line and save/exit. Then reboot your system for the new setting to take effect.

Once that's been done, run the 'ls mod | grep i2c' command again. Hopefully you will now see the I2C interface is displayed in the output, which means it's enabled. 🤞

If you don't get any output then the kernel you're using might not have the I2C interface enabled. Run the following command to find out:

root@maia:~# zcat /proc/config.gz | grep -i 'CONFIG_I2C='

Your looking for a return output of 'CONFIG_I2C=y' and if you don't get that then try the same command but referencing '/boot/config.gz' instead (i.e. : zcat /boot/config.gz | grep -i 'CONFIG_I2C='). If that fails too then you should consider installing another kernel that does have the I2C interface enabled.

With the I2C interface verified as enabled you can now scan the I2C bus with a command that will show any connected and active devices. You may not be aware of which I2C interface devices are connected and this is a great way to find out. This will show you any I2C devices by responding with their address. If you've installed an I2C Real Time Clock (RTC) before, or any other I2C device, then you'll know exactly what to expect here.

Type this command at the prompt and press :

root@maia:~# i2cdetect -y 1

This should result in the following output:

i2cdetect -y 1

SARPi Project muse views ... If you get an error from using the 'i2cdetect' command it probably means you do not have the 'i2c-tools' package installed. This package can be downloaded from Slackware.UK and installed. Alternatively, use 'slackpkg' to download and install it.

If you can see the same, or similar, output then you know that the SSD1306 I2C OLED display module is installed and detected on the I2c bus.

Because you've used 'i2cdetect -y 1' it means you are scanning I2C bus (or port) number "1". The "3c" is the device address on I2C bus 1 where it is located. This means the full adddress of the device is '0x3c'. I2C buses have a range of 0x00 to 0x7F and devices can be anywhere within that range. But, most I2C interface devices are preset with specific address so that a known standard across installation and comfiguration on different devices and platforms is maintained. This makes them easier to work with, basically.

So far, this output verifies that the I2C interface is enabled. I2C bus 1 is working. Your OLED screen display is physically connected correctly, powered, and responding.

Now you need to check your Python 3 version. This is very easy. Just type the following at the command prompt and press :

root@maia:~# python3 --version

You should see a result similar to the following:

python3 --version

Our Python 3 version is '3.12.12' but yours may be different. As long as it is at least version '3.8' minimum (greater is better) then you're good to proceed. If your Python 3 version is earlier than 3.8 then you should upgrade to the latest available version.

Installing Required Python 3 Libraries Using pip

Now you will install only the required libraries that are needed for running your SSD1306 I2C OLED display module, and you'll be using 'pip' to do this. Generally, 'pip' comes with Python 3 but not always. You can easilly check if you have pip installed with the following command:

root@maia:~# python3 -m pip --version

If 'pip' is not already present then you can bootstrap it and upgrade Python 3 with the following commands:

root@maia:~# python3 -m ensurepip
root@maia:~# python3 -m pip install --upgrade pip
root@maia:/tmp# which pip3
/usr/bin/pip3

Now, install the required Python 3 libraries: luma.core, luma.oled, smbus2, psutil, pillow - these are the only libraries you will need. They can be installed at the same time, efficiently, within the same command. Type the following at the command prompt and press :

root@maia:~# pip3 install luma.core luma.oled smbus2 psutil pillow

Once the Python 3 libraries are installed, you need to check and verify that your system can import the luma.core and luma.oled modules. So type (or copy and paste) the following command and run it in your terminal:

root@maia:~# python3 - << 'EOF'
from luma.core.interface.serial import i2c
from luma.oled.device import ssd1306
print("IMPORT OK")
EOF

The output from running this command should be:

python3 - << 'EOF'

In other words you should see an output of: "IMPORT OK"

This indicates that the Python 3 libraries installed successfully and everything is working perfectly.

Python 3 Script for the 0.96" SSD1306 I2C OLED display module (128×64)

You're going to need a Python 3 script to drive the SSD1306 I2C OLED display module. This can be done in many ways, but two of them very easily. It involves downloading scripts that have already been written and optimised specifically for this OLED screen. We'll cover what we did at the SARPi Project first.

SARPi Project muse views ... If you're not interested in downloading and running the SARPi Project's Python 3 'oled_sysinfo.py' script, you can skip this section and go to: Downloading and running Python 3 luma.examples

We wrote our own Python 3 script named 'oled_sysinfo.py' specifically for the GeeekPi Mini Tower Kit's SSD1306 I2C OLED display module. Primarily because we couldn't find a suitable existing script online. They either displayed superfluous fancy shapes or patterns, had too little information output, or too much output that extended beyond the contraints of the 128 x 64 pixel screen display. Often the font used was too large, or too small. All we needed was some basic parameter outputs to be displayed with a current timestamp (date '+%F %T'). So, we decided to roll up our sleeves and get involved in some good old fashioned D.I.Y. Python scripting.

After revising and fine tuning our Python 3 script 'oled_sysinfo.py' code, the result was perfect for us. It displayed exactly what we wanted it to show, in an appropriately sized expanding font that won't overflow off the edge of the screen, updated once per second on an infinte loop, and could be run in multiple ways. We also made it easy to edit with configurable settings should we need to change the most fundamental parameters. We designed this script so that the the infinite loop poll period can be as brief as 0.1 seconds or as long a time period as is required.

The 'oled_sysinfo.py' script can be downloaded here: https://sarpi.penthux.net/files/extra/sarpi_oled_sysinfo.tar.xz

root@maia:~# wget https://sarpi.penthux.net/files/extra/sarpi_oled_sysinfo.tar.xz

Download and unpack this tarball. Save the 'oled_sysinfo.py' script in a location you're happy with. You'll know what's best for your own system. We saved ours in /root/.oled/oled_sysinfo.py location.

root@maia:~# mkdir -p /root/.oled
root@maia:~# tar -xvJf sarpi_oled_sysinfo.tar.xz -C /root/.oled/
root@maia:~# chown -x /root/.oled/oled_sysinfo.py

Now the 'oled_sysinfo.py' script is ready to be used and will light up our screen with specific display output.

As a test, it can just be run with a standard execution command, once. This will put the terminal 'on hold' while the script is running, until we + to exit, This is as just a test for you to verify that the script (and your OLED display) works as intended. So type this at the prompt and press :

root@maia:~# python3 /root/.oled/oled_sysinfo.py

What we witnessed, and what you should see too, is the SSD1306 I2C OLED display module activating and displaying this type of output:

0.96" SSD1306 I2C OLED display module (128×64)
0.96" SSD1306 I2C OLED display module (128×64) on Slackware AArch64 Linux

That's exactly what we wanted to be displayed on our OLED screen. BTW, you might have noticed the Slackware Linux bubble badge affixed to the front of the case. That little icon of beauty was fitted into place as the first priority task, before the Raspberry Pi 5 was installed! 😜

What you observe from the generated output of the SSD1306 I2C OLED display module when it's active appears as if the screen is streaming. What's really happening is; it's just a self-emisive, command-driven, static OLED display output that's refreshed every second. The illusory result offers the impression that it's perpetually streaming. The OLED controller is multiplexing rows constantly. You never see it flicker or dim because the refresh rate is so fast. Although the SSD1306 OLED display appears to behave like a continuously streaming screen, it actually contains its own framebuffer and refresh logic. The Raspberry Pi writes pixel data into internal memory, and the controller independently scans and refreshes the panel using that data. Unlike a desktop computer [PC] or laptop screen, the Raspberry Pi is not continuously transmitting a live video signal to the SSD1306 OLED controller.

When we are done drooling over it (which may be a while in our case) we'll press + keys together, at the same time, to exit the running Python 3 script process. This kills the display output and exits the script gracefully, as per our code.

The SARPi 'oled_sysinfo.py' Python 3 Script Explained In Brief

Fundamentally, what this script does is: generate some data (bytes), turn it into human-readable values, load it into memory so that the OLED screen controller can access and use it, and then an "infinite loop sleep period" keeps cycling this process so it never ends.

If you look at the script's code (e.g. in a text editor) you'll see that every section and block of code is "# commented" clearly so the reader knows what it is and does. You are more than free and welcome to play around and tinker with it. By all means, knock yourselves out with setting a different font size or even a new font! You'll find the comments '# Set the font file' and '# Set font pixel size' a little further down in the script's code which governs and sets these parameters. Just make sure you make a backup of it first so that you always have the original to fallback on in case of disaster.

SARPi Project muse views ... ❗❗❗IMPORTANT TO NOTE:❗❗❗

Any font you use to display output on the 0.96" SSD1306 I2C OLED display module (128×64) MUST be a TrueType or OpenType (.ttf / .otf) font.

Trouble-Shooting Tip: More often than not, when there's no display output, or there is output but it looks similar to the opening credits of The Matrix movie, and it seems like a real head-sratcher of a problem because all the Python 3 code checks out with no errors, this is the culprit. 99.999% of the time you will be using the wrong, incompatible, font(s).

Extra Note: It's also worth bearing in mind that some (.ttf / .otf) fonts render poorly at small pixel sizes on small OLEDs. Testing, sometimes by trial and error, is often required when choosing font styles. There are approx. a dozen fonts to use and try out in the 'luma.examples/examples/fonts' directory on the GitHub repository (covered and discussed later in this mini-project).

Incidentally, we chose the 'DejaVuSansMono.ttf' font because it looks great at 9px font size.😉

The section titled "# OLED screen settings" is where your screen's chipset ID, I2C bus (port), and I2C address are specified. The section titled "# Screen refresh time [seconds]" is where you can set the update loop period - i.e. how often it refreshes. We have set it to 1 second refresh by default but you can change this value to whatever suits you. Values from 0.1 seconds to <think of a number> are valid. For example, if you're running this script on a Raspberry Pi 2 you might want to set the refresh period to 3 or 5 seconds, or longer. On a Raspberry Pi 5 we set it to 1 second refresh loop because it has a very minimal impact on the system and doesn't even show on the top 20-25 entries of 'top'. That's not just minimal, that's practically insignificant in terms of resources.

Summary of the SARPi Project's 'oled_sysinfo.py' Python 3 script for the 0.96" SSD1306 I2C OLED display module (128×64):

• Initializes cleanly
• Properly configured
• Validates signal handling correctly
• Memory footprint stable (no leaks after +72 hours)
• Survives heavy load / network blips without degradation
• No runaway CPU usage
• Crisp font rendering
• psutil polling stable and reliable
• No I2C bus lockups
• OLED driver rock-solid
• Runs in deterministic infinite loop
• Handles SIGTERM gracefully
• No zombie processes
• Crash-free
• Exits cleanly and gracefully

That’s daemon-grade behaviour for something this small. 😜 🤣

How to run Python 3 scripts for the SSD1306 I2C OLED display module?

You might ask, "How do I run this script continually and still be able use my Slackware Linux terminal while it's active?" The answer is very simple, and easy:

• You can start a 'screen' session and run the script, then detatch from the screen session and leave it running as a background process. You can do exactly the same thing using 'tmux' too.
• You can start the script and press + to put it in the background (NB: use 'bg' command to start the process it if it's stopped after you put it in the background). Use 'fg' command to bring it back into the foreground and then you can press + to kill the process. You can also use 'kill PID' to end the process while it's in the background.
• You can use 'nohup' (NB: DON'T forget the ampersand on the end) like this:

root@maia:~# nohup python3 /root/.oled/oled_sysinfo.py &

• You can enter a line into crontab and run it as a cron job at boot time, like this:

# Run OLED display script at boot time
@reboot /usr/bin/python3 /root/.oled/oled_sysinfo.py

SARPi Project muse views ... To end the process when running the script with 'nohup' you need to find the process PID and 'kill' it:

root@maia:/tmp# ps aux | grep oled_sysinfo
root 12345 0.9 0.1 332960 24848 ? Sl Feb28 11:34 python3 /root/.oled/oled_sysinfo.py

So when you know the process PID (in our example it's: '12345') use this:

root@maia:/tmp# kill 12345

NB: if 'kill PID' doesn't work to stop the process then use: kill -9 PID

It's as simple and easy as that.

When it comes to ways and means of running Python (or any other) scripts on Slackware Linux you are, quite literally, spolied for choice. 😂

Downloading and running Python 3 luma.examples for 0.96" SSD1306 I2C OLED display module (128×64)

The luma.examples repository on GitHub, created and maintained by Richard Hull, is the companion repo for running examples against the luma.emulator, luma.oled, luma.lcd and luma.led_matrix display drivers. There are various display emulators available for running code against, for debugging, and for screen capture functionality. By default, all the luma.examples assume I2C port 1, address 0x3C and the SSD1306 driver. Which matches the 0.96" SSD1306 I2C OLED display module's required settings and configuration perfectly.

For this task we'll be working in the '/tmp/' directory.

To download the luma.examples GitHub repository, type the following at the command prompt and press :

root@maia:/tmp# git clone https://github.com/rm-hull/luma.examples.git

Then 'cd luma.examples' to enter the newly cloned directory.

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

Next, list the examples directory using 'ls examples' to view its contents:

ls examples

Within the examples directory are all the Python 3 scripts that can be run and tested on the Raspberry Pi with the 0.96" SSD1306 OLED display module connected to the I2C interface on bus 1 at address 0x3c. That's you, that is! 😏

SARPi Project muse views ... To run any of these scripts, it's no different in command execution structure from running the SARPi 'oled_sysinfo.py' Python 3 script. In general you will deal with all of these luma.examples scripts in the same way to execute them, and once they are running. Some scripts have an infinite loop and some have a pre-set list of commands to perform before exiting once they have completed their task(s).

These Python 3 luma.axamples already have built-in to them the assumption that the 0.96" SSD1306 I2C OLED display module (128×64) is connected to the Raspberry Pi on the I2c interface on bus 1 with a 0x3c address. So there's no need to edit or configure them whatsoever. This is why we can run them "as is" because (just like our own SARPi Project 'oled_sysinfo.py' script) they are already optimised to run with the correct configuration and settings.

❓ What _IF_ you wanted to run a Python 3 script that didn't contain the correct (or any) I2C interface, bus, and address settings? Well... you'd need to run them with the following [for example] command options:

root@maia:/tmp# python3 path/to/my_script.py --display ssd1306 --interface i2c --i2c-port 1 --i2c-address 0x3C

These additional command options inject the I2C configurations into the script to give it the correct settings required in order for it to work on theSSD1306 I2C OLED display module. If you find any Python 3 scripts for the SSD1306 I2C OLED display module that do not work as expected, or even crash when you run them, try running such scripts with the above command options and see if that makes all the difference.

Typically, if there are any Python libraries required that are not already installed the script(s) will throw out an error and list which libraries are missing.😉

The instructions on the lumas.examples GitHub repository (i.e. the README.md file) show examples of running the examples/demo.py script. So that's what we'll do here first. As previously mentioned the command structure is exactly the same, only the path and filenames have changed. So we can just type the following at the command prompt and press :

root@maia:/tmp# python3 examples/demo_sys_info.py

This is what was displayed on our SSD1306 I2C OLED display module's screen:

luma.examples/examples/demo.py
luma.examples/examples/demo.py

The 'examples/demo.py' script will run its brief code and then exit gracefully. Test complete.

Next we ran the 'examples/matrix.py' script to test and verify the results:

luma.examples/examples/matrix.py
luma.examples/examples/matrix.py

Digital rain - 0.96" SSD1306 I2C OLED display module (128×64) style. Not quite the 'digital rain' we were hoping for (NB: a few members of the SARPi Team are HUGE Matrix fans! 🎥) but on a 128 x 64 pixel OLED screen this wasn't bad, all things considered. We're actually thinking of creating a more dynamic and authentic Digital rain effect for the luma.examples repository. Stay tuned!

SARPi Project muse views ... A few days after this mini-project was completed, the SARPi Project team modified the examples/matrix.py to display 'variable intensity' Digital rain (via a value setting within the script) with a little more realism, like in The Matrix movies (or as much as a 128×64 pixel monochrome OLED screen would allow). A pull request was made on the luma.examples repository on GitHub, maintained by Richard Hull and examples/matrix_intensity.py was accepted and merged into the main branch. 😎

We then tried and tested nearly all of the Python 3 scripts in the 'luma.examples/examples' directory. After running the 'examples/clock.py' script we discovered a slight problem:

luma.examples/examples/clock.py
luma.examples/examples/clock.py

The bottom of the date and top of the time were overlapping and colliding. So, naturally (and instinctively) we corrected the spacing and this was the result:

updated luma.examples/examples/clock.py
luma.examples/examples/clock.py - after revising the spacing

In keeping with the principles of free and open-source software development, we committed the fix and submitted it to Richard Hull’s GitHub luma.examples repository for inclusion. The pull request was subsequently approved and merged into the main branch. ✅

We've honestly been having some good old fashioned, unabated, fun at the SARPi Project with the luma.examples scripts. We hope you find them as interesting, entertaining, and useful as we do. They are absolutely perfect for testing and immense fun to play around with on the SSD1306 I2C OLED display module. Full credit and kudos for making this possible goes to Richard Hull and contributors to the luma.examples repository on GitHub. That... err... we just became part of. 🤔 🤓 🤣

That just about wraps it up for another SARPi mini-project. The only thing left for you to do now is go and enjoy your 0.96" SSD1306 I2C OLED display module (128×64). 💻

Acknowledgements & Thanks!

Thank you ALL for reading and taking part in this SARPi mini-project. We trust you enjoyed it and found it interesting, educational, and great fun!

Thanks and perpetual gratitude to Patrick Volkerding, and the entire Slackware Team of developers, for producing a truly wonderful OS. Without you, and the work you do, the SARPi Project would not exist.

Many thanks also to GeeekPi (a.k.a. 52Pi) for the incredibly useful and inspired ABS Mini Tower Kits for Raspberry Pi.

BIG thank you to Solomon Systech for the SSD1306 driver with controller chip.

HUGE thank you to Richard Hull who maintains the luma.examples scripts on GitHub which run on the 0.96" SSD1306 I2C OLED display module (128×64).

The SARPi Project is grateful to all of the above for their time and efforts in making things possible on Slackware Linux. 🙇

Back to Top


Updated: 2026-03-26 13:13:28 UTC

Disclaimer: The SARPi Project website is for non-commercial and general information purposes only. The content is provided by Penthux.NET and while we endeavour to keep information up to date and correct, we make no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the website or any information, software, products, services, or related graphics which is available on the website for any purpose. Any reliance you place on such information is therefore strictly at your own risk. In no event will Penthux.NET be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this website or any of its contents. Through this website you are able to visit other websites which are not under our control. Penthux.NET has no influence over the nature, content or availability of any external URLs. The inclusion of any URLs does not necessarily imply a recommendation or endorsement of any content therein. Every effort is made to ensure the SARPi Project website remains accessible. However, Penthux.NET takes no responsibility for, and will not be liable for, the SARPi Project website being temporarily unavailable due to technical issues beyond our control. SARPi Project is in no way affiliated with Slackware Linux, Inc, or the Linux Foundation, or Raspberry Pi Ltd., or any of their respective members, trustees, partners, or associates.


Decline! Accept!

SARPi Project uses cookies for website traffic data analytics purposes only. Cookies from this website do not collect or store any of your personal data.

Please read the SARPi Project website [ Cookie Policy ] for more details.