Skip to main content

How to use display

This guide explains how to use the Codi:bit display with the new buffer-based API.

Overview

The Codi:bit display uses a buffer-based approach where drawing commands are stored in an internal buffer and then output to the screen using the show() function. This approach provides better performance and more control over the display.

🔬 Technical Background

Background: OLED displays consist of a memory buffer (128×64 pixel data) and the actual screen.

Operation:

  • draw_ functions only store pixel data in the buffer
  • show() function transfers the entire buffer to the screen
  • show_ functions internally call show() each time, updating the screen every time

Result: Using show_ functions in infinite loops causes the screen to flicker multiple times. Using draw_ functions and then calling show() once provides smooth display.

💡 For detailed comparison and usage patterns, see the Understanding draw_ vs show_ Functions section below.

Basic Usage Pattern

from codibit import display

# 1. Clear the screen
display.clear()

# 2. Perform drawing operations
display.draw_text("Hello", 0, 0)
display.draw_circle(32, 32, 10)

# 3. Output to screen
display.show()

Drawing Text

Basic Text Drawing

# Draw text at position (0, 0)
display.draw_text("Hello", 0, 0)
display.show()

Multiple Lines

display.draw_text("Line 1", 0, 0)
display.draw_text("Line 2", 0, 10)
display.draw_text("Line 3", 0, 20)
display.show()

Text Positioning

# Center text horizontally
text = "Hello"
x = (128 - len(text) * 6) // 2 # Approximate character width
display.draw_text(text, x, 0)
display.show()

Drawing Shapes

Rectangles

# Empty rectangle
display.draw_rectangle(10, 10, 20, 15)

# Filled rectangle
display.draw_rectangle(40, 10, 20, 15, fill=True)
display.show()

Circles

# Empty circle
display.draw_circle(32, 32, 10)

# Filled circle
display.draw_circle(64, 32, 8, fill=True)
display.show()

Lines

# Draw a cross
display.draw_line(0, 0, 50, 50)
display.draw_line(0, 50, 50, 0)
display.show()

Triangles

# Empty triangle
display.draw_triangle(10, 10, 20, 40, 40, 40)

# Filled triangle
display.draw_triangle(50, 10, 60, 40, 80, 40, fill=True)
display.show()

Working with Images

Built-in Icons

from codibit import Image

# Draw built-in icons using Image objects
display.draw_image(Image.HEART, 0, 0)
display.draw_image(Image.HAPPY, 20, 0)
display.draw_image(Image.SAD, 40, 0)
display.show()

Icon Scaling

# Draw icons at different scales using Image objects
display.draw_image(Image.HEART, 0, 0, scale=1) # 5x5
display.draw_image(Image.HAPPY, 20, 0, scale=2) # 10x10
display.draw_image(Image.SAD, 50, 0, scale=3) # 15x15
display.show()

Custom Images

# Create custom image from string
custom = Image('90009:09090:00900:09090:90009:')
display.draw_image(custom, 0, 20)
display.show()

Pixel-Level Control

Setting Individual Pixels

# Draw a simple pattern
for i in range(0, 128, 2):
display.set_pixel(i, 32, 1)
display.show()

Reading Pixel States

# Check if a pixel is on
if display.get_pixel(10, 20):
print("Pixel is on")
else:
print("Pixel is off")

Understanding draw_ vs show_ Functions

Correct Usage Patterns

import time
from codibit import *

# Animation in infinite loop
while True:
display.clear() # Clear buffer
display.draw_text("Hello", 0, 0) # Draw text to buffer
display.draw_circle(32, 32, 10) # Draw circle to buffer
display.show() # Display all content at once
sleep(0.5)

Advantages:

  • Smooth animation without flickering
  • Memory efficient (single update)
  • Performance optimized

✅ Using show_ functions for static screens

from codibit import *

# Static screen composition
display.clear()
display.show_text("Hello", 0, 0) # Immediate display
display.show_circle(32, 32, 10) # Immediate display

Advantages:

  • Simple and intuitive
  • Suitable for static screen composition
  • Concise code

❌ Using show_ functions in infinite loops (Avoid this)

import time
from codibit import *

# Problematic code - causes flickering
while True:
display.clear()
display.show_text("Hello", 0, 0) # Immediate display
display.show_circle(32, 32, 10) # Immediate display
sleep(0.5)

Problems:

  • Flickering occurs: Screen updates with each show_ function call
  • Performance degradation: Unnecessary screen updates cause performance issues
  • Visual discomfort: Poor user experience

Flickering Issue Resolution

Cause

Using multiple show_ functions in infinite loops:

  1. show_text() call → Screen update
  2. show_circle() call → Screen update

Each step updates the screen, causing flickering.

Solution

Use draw_ functions in infinite loops and call show() only once at the end:

# Correct approach
while True:
display.clear()
display.draw_text("Hello", 0, 0) # Draw to buffer only
display.draw_circle(32, 32, 10) # Draw to buffer only
display.show() # Display once
sleep(0.5)

Performance Optimization

Batch Drawing Operations

# Efficient: Multiple operations, single show()
display.clear()
display.draw_text("Hello", 0, 0)
display.draw_circle(32, 32, 10)
display.draw_rectangle(10, 10, 20, 15)
display.show() # Single output operation

Buffer Control for Performance

# For performance optimization: clear() + multiple operations
display.clear() # Clear buffer only, no output
display.draw_text("Hello", 0, 0)
display.draw_circle(32, 32, 10)
display.draw_rectangle(10, 10, 20, 15)
display.show() # Single output operation

# For immediate feedback: clear_immediate() for simple operations
display.clear_immediate() # Clear and output immediately
display.draw_text("Status", 0, 0)
display.show()

Avoid Frequent Updates

# Inefficient: Multiple show() calls
display.draw_text("Hello", 0, 0)
display.show() # Don't do this
display.draw_circle(32, 32, 10)
display.show() # Don't do this

# Efficient: Single show() call
display.draw_text("Hello", 0, 0)
display.draw_circle(32, 32, 10)
display.show() # Do this instead

Common Patterns

Status Display

def show_status(message, value):
display.clear()
display.draw_text(message, 0, 0)
display.draw_text(str(value), 0, 20)
display.show()

# Usage
show_status("Temp:", "25C")

Progress Bar

def draw_progress_bar(progress, x=10, y=30, width=100, height=10):
# Background
display.draw_rectangle(x, y, width, height, fill=True)
# Progress
progress_width = int(width * progress / 100)
display.draw_rectangle(x, y, progress_width, height, fill=True)
display.show()

# Usage
draw_progress_bar(75) # 75% progress
def show_menu(items, selected_index):
display.clear()
y = 0
for i, item in enumerate(items):
if i == selected_index:
display.draw_text(f"> {item}", 0, y)
else:
display.draw_text(f" {item}", 0, y)
y += 10
display.show()

# Usage
menu_items = ["Option 1", "Option 2", "Option 3"]
show_menu(menu_items, 1) # Highlight second option

Animation

Simple Animation

import time

# Animate a moving circle
for x in range(0, 128, 5):
display.clear()
display.draw_circle(x, 32, 5)
display.show()
sleep(0.1)

Blinking Text

import time

# Blinking text
for _ in range(5):
display.clear()
display.draw_text("Hello", 0, 0)
display.show()
sleep(0.5)

display.clear()
display.show()
sleep(0.5)

Error Handling

Safe Drawing

def safe_draw_text(text, x, y):
try:
display.draw_text(text, x, y)
return True
except:
return False

# Usage
if safe_draw_text("Hello", 0, 0):
display.show()
else:
print("Failed to draw text")

Tips and Best Practices

  1. Always call show(): After drawing operations, always call show() to display the content
  2. Clear before drawing: Use clear() to start with a clean screen
  3. Batch operations: Group multiple drawing operations before calling show()
  4. Check coordinates: Ensure coordinates are within the display bounds (0-127 for x, 0-63 for y)
  5. Use built-in icons: Leverage the built-in icons using Image objects for type safety and IDE support
  6. Consider performance: Minimize the number of show() calls for better performance
  7. Test visibility: Ensure text and graphics are visible against the background
  8. Choose clear method: Use clear() for performance optimization with multiple operations, clear_immediate() for immediate feedback
  9. Use draw_ functions in infinite loops: For animations or games, use draw_ functions and call show() only once at the end
  10. Use show_ functions for static screens: For screens displayed only once, use show_ functions to keep code concise
  11. Avoid flickering: Don't use show_ functions in infinite loops as they cause flickering

Hardware Limitations

  • Resolution: 128x64 pixels
  • Color: Monochrome (white/black only)
  • Pixel values: Only 0 (off) or 1 (on)
  • Memory: Limited buffer space, avoid very large images
  • Refresh rate: Consider the display's refresh capabilities for animations