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

character-displays.mddocs/

Character/Text Displays

Text-oriented OLED displays that support both graphical rendering and character-based text display with embedded fonts. These displays combine the flexibility of graphics with the convenience of character addressing.

Capabilities

WS0010 Display

Serial interface to a monochrome Winstar WS0010 OLED display with character support, embedded fonts, and both graphical and text modes.

class ws0010:
    def __init__(self, serial_interface=None, width=100, height=16, undefined='_', font=None, selected_font=0, exec_time=1e-6 * 50, rotate=0, framebuffer=None, **kwargs):
        """
        Initialize WS0010 OLED character display.

        Parameters:
        - serial_interface: Parallel interface (luma.core.interface.serial.parallel)
        - width: Number of horizontal pixels (default: 100)
        - height: Number of vertical pixels (default: 16)
        - undefined: Character to display for missing glyphs (default: '_')
        - font: Override internal font with PIL.ImageFont (optional)
        - selected_font: Select embedded font table by name/number (default: 0)
        - exec_time: Command execution time in seconds (default: 50µs)
        - rotate: Rotation value 0-3 (0°, 90°, 180°, 270°) (default: 0)
        - framebuffer: Framebuffering strategy (diff_to_previous or full_frame)
        """

    def display(self, image):
        """
        Display a 1-bit PIL Image on the WS0010 OLED.

        Parameters:
        - image: PIL.Image in mode "1" (1-bit monochrome)
        """

    def get_font(self, ft):
        """
        Load embedded font by index or name.

        Parameters:
        - ft: Font index (int) or name (str)

        Returns:
        Font object for the specified embedded font
        """

    @property
    def text(self) -> str:
        """Get the current text content displayed on screen."""

    @text.setter
    def text(self, value: str):
        """
        Set text content to display on screen.

        Parameters:
        - value: Text string to display, supports newlines
        """

Supported Resolutions: (40,8), (40,16), (60,8), (60,16), (80,8), (80,16), (100,8), (100,16)

Available Embedded Fonts:

NumberNameFontSize
0FT00English Japanese5x8
1FT01Western European I5x8
2FT10English Russian5x8
3FT11Western European II5x8
4FT00_10English Japanese5x10
5FT01_10Western European I5x10
6FT10_10English Russian5x10
7FT11_10Western European II5x10

Usage example:

from luma.core.interface.serial import parallel
from luma.oled.device import ws0010

# Initialize with parallel interface
serial = parallel(RS=7, E=8, PINS=[25, 24, 23, 18])
device = ws0010(serial, width=100, height=16, selected_font='FT01')

# Display text using character interface
device.text = "WS0010 Display\nLine 2 Text"

# Or use graphical interface
with canvas(device) as draw:
    draw.text((0, 0), "Graphics Mode", fill="white")
    draw.rectangle((0, 8, 100, 16), outline="white")

# Load and use different fonts
font = device.get_font('FT11')  # Western European II
device.text = "Çafé naïve résumé"

Winstar WEH Display

Character-based Winstar WEH OLED display using the WS0010 controller with grid-optimized font rendering.

class winstar_weh(ws0010):
    def __init__(self, serial_interface=None, width=16, height=2, **kwargs):
        """
        Initialize Winstar WEH character OLED display.

        Parameters:
        - serial_interface: Parallel interface (luma.core.interface.serial.parallel)
        - width: Number of characters per line (default: 16)
        - height: Number of lines (default: 2)
        - undefined: Character to display for missing glyphs (default: '_')
        - font: Override internal font with PIL.ImageFont (optional)
        - default_table: Select embedded font table (optional)
        - embedded_font: Select font size "5x8" or "5x10" (default: "5x8")
        - exec_time: Command execution time in seconds (default: 50µs)
        - rotate: Rotation value 0-3 (0°, 90°, 180°, 270°) (default: 0)
        - framebuffer: Framebuffering strategy (diff_to_previous or full_frame)

        Note: Width/height specified in characters, not pixels.
        Internal pixel dimensions are width*5 x height*8.
        """

Usage example:

from luma.core.interface.serial import parallel
from luma.oled.device import winstar_weh

# Initialize 16x2 character display
serial = parallel(RS=7, E=8, PINS=[25, 24, 23, 18])
device = winstar_weh(serial, width=16, height=2)

# Display character-based text
device.text = "Line 1 Text\nLine 2 Text"

# Text automatically wraps at character boundaries
device.text = "This is a long line of text that will wrap"

Character vs Graphical Modes

Character Mode

Character mode uses the text property for simple text display:

# Character mode - automatic font rendering
device.text = "Hello World!\nSecond Line"

# Supports basic formatting
device.text = "Temperature: 23°C\nHumidity: 65%"

# Unicode characters (if font supports them)
device.text = "Café naïve résumé"

Graphical Mode

Graphical mode provides full drawing capabilities:

# Graphical mode - full PIL drawing
with canvas(device) as draw:
    draw.text((0, 0), "Custom Graphics", fill="white")
    draw.line([(0, 8), (100, 8)], fill="white")
    draw.rectangle((10, 10, 90, 15), outline="white")
    draw.point([(5, 5), (95, 5)], fill="white")

Font Management

Using Embedded Fonts

# Select font during initialization
device = ws0010(serial, selected_font='FT01')  # Western European

# Or load font dynamically
font_obj = device.get_font(2)  # English Russian (FT10)

# Access font by name or number
font1 = device.get_font('FT11_10')  # 5x10 Western European II
font2 = device.get_font(7)          # Same font by number

Custom Fonts

from PIL import ImageFont

# Use custom PIL font instead of embedded fonts
custom_font = ImageFont.load("custom.pil")
device = ws0010(serial, font=custom_font)

# Embedded fonts are bypassed when custom font is provided
device.text = "Custom Font Text"

Interface Configuration

Character displays typically use parallel interfaces:

from luma.core.interface.serial import parallel

# Standard parallel configuration
serial = parallel(
    RS=7,                    # Register Select pin
    E=8,                     # Enable pin  
    PINS=[25, 24, 23, 18]   # Data pins (D4-D7 for 4-bit mode)
)

# 8-bit mode (if supported)
serial = parallel(
    RS=7, E=8,
    PINS=[25, 24, 23, 18, 17, 16, 15, 14]  # D0-D7 for 8-bit mode
)

Common Patterns

Error Handling

import luma.core.error

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

Display Initialization

Character displays have longer initialization times:

from time import sleep

# Initialize device
device = ws0010(serial)

# Device automatically sleeps 0.5s during initialization
# Additional delays may be needed for complex setups
sleep(0.1)

device.text = "Ready!"

Grid Considerations for WEH Displays

WEH displays have 1-pixel gaps every 5th column:

# WEH displays have grid structure
device = winstar_weh(serial, width=16, height=2)

# Text interface automatically handles grid
device.text = "Grid Aligned"

# For graphics, be aware of grid gaps
with canvas(device) as draw:
    # Gaps occur at x = 5, 10, 15, 20, etc.
    draw.text((0, 0), "Account for gaps in graphics")

Performance Tips

# Use appropriate framebuffer for usage pattern
from luma.core.framebuffer import diff_to_previous, full_frame

# For frequently changing text
device = ws0010(serial, framebuffer=diff_to_previous())

# For static or infrequent updates
device = ws0010(serial, framebuffer=full_frame())

# Reset display if needed (4-bit mode only)
# Device automatically resets when in 4-bit mode for synchronization

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