Display drivers for SSD1306/SSD1309/SSD1322/SSD1325/SSD1327/SSD1331/SSD1351/SSD1362/SH1106/SH1107/WS0010 OLED matrix 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.
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 contrastSerial 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 modeColor 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))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())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)import luma.core.error
try:
device = ssd1351(serial, width=200, height=200)
except luma.core.error.DeviceDisplayModeError as e:
print(f"Unsupported resolution: {e}")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 RGBHandle 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 offsetInstall with Tessl CLI
npx tessl i tessl/pypi-luma-oled