CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-luma-oled

Display drivers for SSD1306/SSD1309/SSD1322/SSD1325/SSD1327/SSD1331/SSD1351/SSD1362/SH1106/SH1107/WS0010 OLED matrix displays

Pending
Overview
Eval results
Files

color-displays.mddocs/

Color Displays

16-bit color (5-6-5 RGB) OLED displays supporting full-color rendering with 65,536 colors. These displays provide vibrant graphics and images with hardware-accelerated color processing and framebuffer optimization.

Capabilities

SSD1331 Display

Serial interface to a 16-bit color SSD1331 OLED display with hardware acceleration for drawing primitives and color mode support.

class ssd1331:
    def __init__(self, serial_interface=None, width=96, height=64, rotate=0, framebuffer=None, **kwargs):
        """
        Initialize SSD1331 color OLED display.

        Parameters:
        - serial_interface: Serial interface (usually luma.core.interface.serial.spi)
        - width: Number of horizontal pixels (default: 96)
        - height: Number of vertical pixels (default: 64)
        - rotate: Rotation value 0-3 (0°, 90°, 180°, 270°) (default: 0)
        - framebuffer: Framebuffering strategy (diff_to_previous or full_frame)
        """

    def contrast(self, level):
        """
        Set display contrast level.

        Parameters:
        - level: Contrast level 0-255

        Note: Setting to low values may not dim display significantly.
        Not suitable for fade-in/out animations.
        """

Supported Resolutions: (96,64)

Usage example:

from luma.core.interface.serial import spi
from luma.oled.device import ssd1331
from luma.core.render import canvas

# Initialize device with SPI
serial = spi(port=0, device=0, bus_speed_hz=8000000)
device = ssd1331(serial)

# Draw colorful content
with canvas(device) as draw:
    # RGB color tuples
    draw.rectangle((0, 0, 96, 64), fill=(0, 0, 255))      # Blue background
    draw.ellipse((10, 10, 86, 54), fill=(255, 0, 0))      # Red circle
    draw.text((20, 25), "Color!", fill=(255, 255, 255))    # White text

# Adjust contrast
device.contrast(128)  # Medium contrast

SSD1351 Display

Serial interface to a 16-bit color SSD1351 OLED display with advanced features including BGR mode, offset support, and enhanced color management.

class ssd1351:
    def __init__(self, serial_interface=None, width=128, height=128, rotate=0, framebuffer=None, h_offset=0, v_offset=0, bgr=False, **kwargs):
        """
        Initialize SSD1351 color OLED display.

        Parameters:
        - serial_interface: Serial interface (usually luma.core.interface.serial.spi)
        - width: Number of horizontal pixels (default: 128)
        - height: Number of vertical pixels (default: 128)
        - rotate: Rotation value 0-3 (0°, 90°, 180°, 270°) (default: 0)
        - framebuffer: Framebuffering strategy (diff_to_previous or full_frame)
        - h_offset: Horizontal offset in pixels (default: 0)
        - v_offset: Vertical offset in pixels (default: 0)
        - bgr: Set to True for BGR pixel order instead of RGB (default: False)
        """

    def contrast(self, level):
        """
        Set display contrast level for all color channels.

        Parameters:
        - level: Contrast level 0-255
        """

    def command(self, cmd, *args):
        """
        Send command and optional arguments to the display.

        Parameters:
        - cmd: Command byte
        - args: Optional command arguments
        """

Supported Resolutions: (96,96), (128,128), (128,96)

Usage example:

from luma.core.interface.serial import spi
from luma.oled.device import ssd1351
from luma.core.framebuffer import full_frame

# Initialize with custom settings
serial = spi(port=0, device=0, bus_speed_hz=8000000)
device = ssd1351(serial, width=128, height=128, 
                 framebuffer=full_frame(), bgr=False)

# Create gradient effect
with canvas(device) as draw:
    for i in range(128):
        color = (i * 2, 255 - i * 2, 128)
        draw.line([(i, 0), (i, 127)], fill=color)

# Fine-tune contrast
device.contrast(200)

# Send custom command
device.command(0xA6)  # Normal display mode

Working with Color Images

Color displays support 24-bit RGB PIL Images which are automatically converted to 16-bit 5-6-5 RGB format:

from PIL import Image

# Load and display a color image
img = Image.open("photo.jpg")
img = img.resize((128, 128))  # Resize to display dimensions
img = img.convert("RGB")      # Ensure RGB mode

# Display the image
device.display(img)

# Or use with canvas for overlay graphics
with canvas(device) as draw:
    draw.bitmap((0, 0), img)
    draw.text((10, 10), "Overlay Text", fill=(255, 255, 0))

Performance Optimization

Framebuffer Strategies

Color displays benefit significantly from framebuffer optimization:

from luma.core.framebuffer import diff_to_previous, full_frame

# Default - only update changed pixels (recommended)
device1 = ssd1351(serial, framebuffer=diff_to_previous())

# Always update entire display
device2 = ssd1351(serial, framebuffer=full_frame())

Color Format Optimization

The displays use 16-bit 5-6-5 RGB format internally:

# Efficient color definitions (reduced precision)
RED = (248, 0, 0)      # Maps to 5-bit red
GREEN = (0, 252, 0)    # Maps to 6-bit green  
BLUE = (0, 0, 248)     # Maps to 5-bit blue

# These give the same result as full precision
RED_FULL = (255, 0, 0)
GREEN_FULL = (0, 255, 0)
BLUE_FULL = (0, 0, 255)

Common Patterns

Error Handling

import luma.core.error

try:
    device = ssd1351(serial, width=200, height=200)
except luma.core.error.DeviceDisplayModeError as e:
    print(f"Unsupported resolution: {e}")

BGR Mode Usage

Some displays have BGR pixel ordering:

# For displays with BGR pixel order
device = ssd1351(serial, bgr=True)

# Colors will be automatically swapped
with canvas(device) as draw:
    draw.rectangle((0, 0, 50, 50), fill=(255, 0, 0))  # Still specify as RGB

Display Offsets

Handle displays with memory offsets:

# Display with offset positioning
device = ssd1351(serial, h_offset=16, v_offset=8)

# Drawing coordinates remain the same
with canvas(device) as draw:
    draw.text((0, 0), "Top Left")  # Automatically accounts for offset

Install with Tessl CLI

npx tessl i tessl/pypi-luma-oled

docs

character-displays.md

color-displays.md

greyscale-displays.md

index.md

interfaces.md

monochrome-displays.md

tile.json