0.91 inch OLED Display - Product Introduction

Language

The 0.91-inch OLED display is a low-power display module based on I2C communication with a resolution of 128x32. It supports connection with various development boards such as Jetson series main controllers, Raspberry Pi, and Orange Pi, and can display system operation status information in real time.

Core Features

  • 📊 Real-time display of CPU usage
  • ⏰ Display current system time
  • 💾 Display memory usage and total memory
  • 🗄️ Display TF card space usage
  • 🌐 Display device local IP address
  • 🔌 Support hot swap, stable and reliable

Hardware Connection

Wiring Instructions

Using I2C communication interface, the wiring method is as follows:

OLED Pin Development Board Pin
VCC 3.3V
GND GND
SDA I2C SDA
SCL I2C SCL
⚠️ Note: Please make sure the wiring is correct and avoid pin short circuit, otherwise it may cause damage to the main board hardware!

Software Usage Guide

Supported platforms:

  • ✅ Jetson series main controllers
  • ✅ All Raspberry Pi models
  • ✅ All Orange Pi models
  • ✅ Other Linux development boards supporting I2C communication

Jetson Series Installation Steps

1. Install Dependencies

sudo apt install -y python3-pip
sudo pip3 install smbus
sudo pip3 install Adafruit_SSD1306

2. Detect I2C Devices

# List all I2C buses
i2cdetect -l

# Detect I2C devices, OLED default address is 0x3c
i2cdetect -y -r *

3. Run Test Code

#!/usr/bin/env python3
# coding=utf-8
import time
import os
import sys
import Adafruit_SSD1306 as SSD
from PIL import Image, ImageDraw, ImageFont
import subprocess

class Juxi_OLED:
    def __init__(self, i2c_bus=1, debug=False):
        self.__debug = debug
        self.__i2c_bus = i2c_bus
        self.__top = -2
        self.__x = 0
        self.__total_last = 0
        self.__idle_last = 0
        self.__str_CPU = "CPU:0%"

    # Initialize OLED, return True on success, False on failure
    def begin(self):
        try:
            self.__oled = SSD.SSD1306_128_32(rst=None, i2c_bus=self.__i2c_bus, gpio=1)
            self.__oled.begin()
            self.__oled.clear()
            self.__oled.display()
            self.__width = self.__oled.width
            self.__height = self.__oled.height
            self.__image = Image.new('1', (self.__width, self.__height))
            self.__draw = ImageDraw.Draw(self.__image)
            self.__font = ImageFont.truetype("DejaVuSansMono.ttf",8)
            return True
        except:
            return False

    # Clear display, refresh=True to refresh immediately
    def clear(self, refresh=False):
        self.__draw.rectangle((0, 0, self.__width, self.__height), outline=0, fill=0)
        if refresh:
            self.refresh()

    # Add text at specified position
    def add_text(self, start_x, start_y, text, refresh=False):
        if start_x > 128 or start_x < 0 or start_y < 0 or start_y > 32:
            return
        x = int(start_x + self.__x)
        y = int(start_y + self.__top)
        self.__draw.text((x, y), str(text), font=self.__font, fill=255)
        if refresh:
            self.refresh()

    # Add text to specified line (1-4)
    def add_line(self, text, line=1, refresh=False):
        if line < 1 or line > 4:
            return
        y = int(8 * (line - 1))
        self.add_text(0, y, text, refresh)

    # Refresh OLED display
    def refresh(self):
        self.__oled.image(self.__image)
        self.__oled.display()

    # Get CPU usage
    def getCPULoadRate(self, index):
        count = 10
        if index == 0:
            f1 = os.popen("cat /proc/stat", 'r')
            stat1 = f1.readline()
            data_1 = []
            for i in range(count):
                data_1.append(int(stat1.split(' ')[i+2]))
            self.__total_last = sum(data_1)
            self.__idle_last = data_1[3]
        elif index == 4:
            f2 = os.popen("cat /proc/stat", 'r')
            stat2 = f2.readline()
            data_2 = []
            for i in range(count):
                data_2.append(int(stat2.split(' ')[i+2]))
            total_now = sum(data_2)
            idle_now = data_2[3]
            total = int(total_now - self.__total_last)
            idle = int(idle_now - self.__idle_last)
            usage = int(total - idle)
            usageRate = int(float(usage / total) * 100)
            self.__str_CPU = "CPU:" + str(usageRate) + "%"
            self.__total_last = 0
            self.__idle_last = 0
        return self.__str_CPU

    # Get system time
    def getSystemTime(self):
        cmd = "date +%H:%M:%S"
        date_time = subprocess.check_output(cmd, shell=True)
        str_Time = str(date_time).lstrip('b\'').rstrip('\\n\'')
        return str_Time

    # Get memory usage
    def getUsagedRAM(self):
        cmd = "free | awk 'NR==2{printf \"RAM:%2d%% -> %.1fGB \", 100*($2-$7)/$2, ($2/1048576.0)}'"
        FreeRam = subprocess.check_output(cmd, shell=True)
        str_FreeRam = str(FreeRam).lstrip('b\'').rstrip('\'')
        return str_FreeRam

    # Get disk usage
    def getUsagedDisk(self):
        cmd = "df -h | awk '$NF==\"/\"{printf \"SDC:%s -> %.1fGB\", $5, $2}'"
        Disk = subprocess.check_output(cmd, shell=True)
        str_Disk = str(Disk).lstrip('b\'').rstrip('\'')
        return str_Disk

    # Get local IP address
    def getLocalIP(self):
        ip = os.popen("/sbin/ifconfig enP8p1s0 | grep 'inet' | awk '{print $2}'").read()
        ip = ip[0: ip.find('\n')]
        if(ip == ''):
            ip = os.popen("/sbin/ifconfig wlP1p1s0 | grep 'inet' | awk '{print $2}'").read()
            ip = ip[0: ip.find('\n')]
            if(ip == ''):
                ip = 'x.x.x.x'
        if len(ip) > 15:
            ip = 'x.x.x.x'
        return ip

    # Main operation loop, support hot swap
    def main_program(self):
        state = False
        try:
            cpu_index = 0
            state = self.begin()
            while state:
                self.clear()
                str_CPU = self.getCPULoadRate(cpu_index)
                str_Time = self.getSystemTime()
                if cpu_index == 0:
                    str_FreeRAM = self.getUsagedRAM()
                    str_Disk = self.getUsagedDisk()
                    str_IP = "IPA:" + self.getLocalIP()
                self.add_text(0, 0, str_CPU)
                self.add_text(50, 0, str_Time)
                self.add_line(str_FreeRAM, 2)
                self.add_line(str_Disk, 3)
                self.add_line(str_IP, 4)
                self.refresh()
                cpu_index = cpu_index + 1
                if cpu_index >= 5:
                    cpu_index = 0
                time.sleep(.1)
        except:
            pass

if __name__ == "__main__":
    try:
        i2c_num = 7
        if len(sys.argv) > 1:
            if str(sys.argv[1]).isdigit():
                i2c_num = int(sys.argv[1])
        
        oled = Juxi_OLED(i2c_num, debug=True)
        while True:
            oled.main_program()
            time.sleep(2)
    except KeyboardInterrupt:
        oled.clear(True)
        del oled
        print(" Program closed! ")
        pass

4. Start Program

# Default bus 7
python3 Oled_i2c.py

# Or specify bus (e.g. bus 1)
python3 Oled_i2c.py 1

Raspberry Pi / Orange Pi Installation Steps

1. Enable I2C Interface

Enter system settings: Preferences → Raspberry Pi Configuration → Interfaces → Enable I2C option, then restart the system.

Or use command line mode:

sudo raspi-config
# Select Interface Options → I2C → Enable → Restart system

2. Install Dependencies

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

# Install required font
sudo apt-get install -y fonts-dejavu-core

3. Configure Permissions

sudo chmod a+rw /dev/i2c-* # Temporary effect, permanent effect requires udev rule configuration

4. Detect Device

i2cdetect -y 1
# Normally, device address 0x3c will be displayed

5. Create Virtual Environment (Recommended)

# Install virtual environment tool (if not installed)
sudo apt-get install -y python3-venv

# Create virtual environment
python3 -m venv oled_env

# Activate virtual environment
source oled_env/bin/activate

# Install required libraries
pip install Adafruit_SSD1306 pillow -i https://mirrors.aliyun.com/pypi/simple/

6. Run Program

python3 Oled_i2c.py 1
# If permission error occurs, check sudo configuration or I2C device permissions

Display Effect

After the program runs successfully, the OLED screen will display the following information in 4 lines:

  1. First line: CPU usage + system time
  2. Second line: Memory usage + total memory
  3. Third line: TF card usage + total capacity
  4. Fourth line: Device local IP address

Related Links