0.91 inch OLED Display 128X64

🎮 The Big Title

Microproject Image

Module Goal: the big canvas four times the pixels of the mini-board, multiple text sizes, real drawing shapes, and true animation. It ends with the course's first video game: Rock-Paper-Scissors, robot vs. you, faces and all. 

🔍 Detective note: if this screen stays dark with address 0x3c, some 0.96" modules use 0x3d swap the address in the setup block. Two OLEDs, two possible house numbers. 

📦 CONCEPT BOX Four times the canvas 

128 × 64 = 8192 glowing dots, arranged in a coordinate system: 

  • x grows to the right: 0 (left wall) → 127 (right wall)
  • y grows DOWNWARD: 0 (top) → 63 (bottom) upside down from math class, standard for screens! 

Three new powers arrive: 

  1. Text sizes: size 1 is small, size 2 doubles it, size 3 fills the stage. Big text = headlines.
  2. Shapes: rect (outline), fill_rect (solid block), line, pixel you draw geometry.
  3. Animation: redraw the scene at a new position, publish, repeat and the eye sees movement. 

Goal: 

your robot's name, huge and centered the first impression. 

Concepts: 

Text Size · Centering · First Impressions

import machine # Controls the board hardware
import oled128x64 # Controls the OLED display
# Sets up the I2C connection for the OLED
# pin25 corresponds to 3 on the Sensor Shield V5.0
# pin26 corresponds to 2 on the Sensor Shield V5.0
# Sets up the OLED as a 128 x 64 pixel display
i2c_extend = machine.SoftI2C(scl = machine.Pin(26), sda = machine.Pin(25), freq = 100000)
oled = oled128x64.OLED(i2c_extend,address=0x3c,font_address=0x3A0000)
# Publish
oled.shows("CLU-BOTS",x = 0,y = 20,size = 2,center = True)	# The name, triple size, dead center

💡 Note: size = 3 means each text pixel becomes a 3×3 block triple width, triple height. Try 1, 2, then 3 and watch the same words grow from sticky-note to billboard. Every dot tripled: size is just multiplication applied to the whole drawing. Then reposition with y: 20 puts the title near the vertical middle of 64 rows. First impressions are a coordinate decision.

🎮 The Position Laboratory

Microproject Image

Goal: 

visit the four corners of the screen mastering the x/y grid by traveling. 

Concepts: 

Coordinates · Screen Geography · Sequenced Layouts

import machine # Controls the board hardware
import oled128x64 # Controls the OLED display
import time	# Controls pauses and timing
# Sets up the I2C connection for the OLED
# pin25 corresponds to 3 on the Sensor Shield V5.0
# pin26 corresponds to 2 on the Sensor Shield V5.0
# Sets up the OLED as a 128 x 64 pixel display
i2c_extend = machine.SoftI2C(scl = machine.Pin(26), sda = machine.Pin(25), freq = 100000)
oled = oled128x64.OLED(i2c_extend,address=0x3c,font_address=0x3A0000)	# Wakes the screen
while True:	# Tour forever
    oled.fill(0)	# Clear
    oled.show()	# Publish the wipe
    oled.shows("TOP LEFT",x = 0,y = 0,size = 1,space = 0,center = False)	# The origin corner
    oled.show()	# Publish
    time.sleep(1)	# Admire for 1 second
    oled.fill(0)	# Clear
    oled.show()	# Publish
    oled.shows("TOP CENTER",x = 60,y = 0,size = 1,space = 0,center = True)	# center
    oled.show()	# Publish
    time.sleep(1)	# Admire
    oled.fill(0)	# Clear
    oled.show()	# Publish
    oled.shows("BOTTOM L",x = 0,y = 50,size = 1,space = 0,center = False)	# South-west corner
    oled.show()	# Publish
    time.sleep(1)	# Admire
    oled.fill(0)	# Clear
    oled.show()	# Publish
    oled.shows("BOTTOM C",x = 60,y = 50,size = 1,space = 0,center = True)	# South-center corner
    oled.show()	# Publish
    time.sleep(1)	# Admire

💡 Note: you just learned screen geography the best way by visiting it. Two honest observations: x=60 doesn't fully clear the right side (text is wider than 64 px at size 1 some letters may touch), and y=55 is the safe bottom because tall letters need headroom. Safe margins are discovered, not calculated nudge numbers until it looks right; that IS the skill.

🎮 The Boss Health Bar

Microproject Image

Goal: 

a battle-game health bar that drains from 100 to 0 outline, inner fill, percent counter, and the GAME OVER moment. 

Concepts: 

rect + fill_rect Together · Draining Animation · Game Feedback

import machine # Controls the board hardware
import oled128x64 # Controls the OLED display
import time	# Controls pauses and timing
# Sets up the I2C connection for the OLED
# pin25 corresponds to 3 on the Sensor Shield V5.0
# pin26 corresponds to 2 on the Sensor Shield V5.0
# Sets up the OLED as a 128 x 64 pixel display
i2c_extend = machine.SoftI2C(scl = machine.Pin(26), sda = machine.Pin(25), freq = 100000)
oled = oled128x64.OLED(i2c_extend,address=0x3c,font_address=0x3A0000)
print("BOSS BATTLE the bar is draining!")	# Backstage narration
oled.shows('BOSS',x = 0,y = 0,size = 2,space = 0,center = True)	# The boss's name above the bar
oled.show()	# Publish the name
for health in range(100, -1, -10):	# health drains 100,90,80...0
    oled.fill(0)	# Clear the whole canvas
    oled.shows('BOSS',x = 0,y = 0,size = 2,space = 0,center = True)	# Rewrite the name
    oled.shows(('HP ' + str(health)),x = 10,y = 50,size = 1,space = 0,center = False)	# The numeric HP below
    oled.rect(8, 28, 112, 14, 1)	# The bar's OUTLINE (a hollow rectangle)
    if health > 0:	# Only draw fill while alive
        oled.fill_rect(10, 30, health, 10, 1)	# The solid fill: width = health!
    oled.show()	# Publish the frame
    print("Boss HP:", health)	# Serial narration
    time.sleep_ms(700)	# Dramatic drain speed
oled.shows('GAME OVER',x = 0,y = 20,size = 2,space = 0,center = True)	# The verdict, big
oled.show()	# Publish it
print("DEFEATED! The boss is gone.")	# Grand ending

Serial Monitor: 

BOSS BATTLE the bar is draining! 

Boss HP: 100 

Boss HP: 90 

... 

Boss HP: 10 

Boss HP: 0

 DEFEATED! The boss is gone. 

💡 Note: the outline + fill teamwork is a real technique: rect draws the empty frame (112 wide, fixed forever), and fill_rect draws the living part whose width equals the health. The frame stays, the fill shrinks inside it exactly how health bars, volume bars and battery icons work in every game and phone. And the drama secret: the if health > 0 guard at zero, no fill at all, an empty shell. One conditional turned a graph into a story.

🎮 The Sliding Heart

Microproject Image

Goal: 

true animation a Heart image crosses the screen from left wall to right wall, frame by frame. 

Concepts: 

Frame Animation · Position Loops · Persistence of Vision

import machine # Controls the board hardware
import oled128x64 # Controls the OLED display
import time	# Controls pauses and timing
from expression_picture import Heart	# Brings the Heart image
# Sets up the I2C connection for the OLED
# pin25 corresponds to 3 on the Sensor Shield V5.0
# pin26 corresponds to 2 on the Sensor Shield V5.0
# Sets up the OLED as a 128 x 64 pixel display
i2c_extend = machine.SoftI2C(scl = machine.Pin(26), sda = machine.Pin(25), freq = 100000)
oled = oled128x64.OLED(i2c_extend,address=0x3c,font_address=0x3A0000)	# Wakes the screen
print("The heart is sliding across!")	# Backstage narration
for x in range(0, 113, 8):	# x marches right: 0,8,16...112
    oled.fill(0)	# Wipe the previous frame completely
    oled.image(Heart,x = x,y = 2,size = 1)	# Draw the heart at the NEW position
    oled.show()	# Publish the frame
    time.sleep_ms(100)	# 10 frames per second smooth!
print("The heart arrived!")	# Ending

💡 Note: this is the entire secret of animation, the same one used by cartoons, films and games: nothing actually moves the frames change fast and your eye lies to you. Each loop turn: erase everything, draw the heart 8 pixels further right, publish, pause 100 ms. At 10 frames per second, the jumps melt into gliding. Two experiments: raise the sleep to 400 ms and watch it become a slideshow (proof the eye did the moving), and change y to 0 or 50 to change the lane. You are one loop away from Pong.

🎮 Rock-Paper-Scissors Showdown

Microproject Image

Goal: 

the first video game of the course. You type R, P or S; the robot picks secretly at random and shows its hand as an image; the logic judges the round; the score accumulates. Type STOP for the final verdict. 

Concepts: 

Random Opponent · Game Logic (Win Combinations) · Score Keeping · Complete Synthesis

import machine # Controls the board hardware
import oled128x64 # Controls the OLED display
import time	# Controls pauses and timing
import random	# Controls random numbers
from expression_picture import Rock	# Brings the Rock image
from expression_picture import Paper	# Brings the Paper image
from expression_picture import Scissors	# Brings the Scissors image
# Sets up the I2C connection for the OLED
# pin25 corresponds to 3 on the Sensor Shield V5.0
# pin26 corresponds to 2 on the Sensor Shield V5.0
# Sets up the OLED as a 128 x 64 pixel display
i2c_extend = machine.SoftI2C(scl = machine.Pin(26), sda = machine.Pin(25), freq = 100000)
oled = oled128x64.OLED(i2c_extend,address=0x3c,font_address=0x3A0000)	# Wakes the screen
my_wins = 0	# Your score
robot_wins = 0	# The robot's score
print("=== ROCK PAPER SCISSORS ===")	# Title
print("Type R, P or S STOP to end")	# The rules
while True:	# The match runs until STOP
    choice = input("Your move: ")	# Wait for your play
    if choice == "STOP":	# The quit command
        break	# Leave the match
    my = 0	# Assume an invalid move for now
    if choice == "R":	# You played Rock
        my = 1	# Rock's secret code is 1
    elif choice == "P":	# You played Paper
        my = 2	# Paper's secret code is 2
    elif choice == "S":	# You played Scissors
        my = 3	# Scissors' secret code is 3
    else:	# Unknown input
        print("Use R, P or S only!")	# The referee warns you
    if my > 0:	# Only play valid rounds
        robot = random.randint(1, 3)	# The robot secretly picks 1, 2 or 3
        oled.fill(0)	# Clear the arena
        oled.show()	# Publish the wipe
        oled.shows(('YOU: ' + choice),x = 0,y = 0,size = 1,space = 0,center = False)
	# Your move, top-left
        if robot == 1:	# Robot drew Rock
            oled.image(Rock,x = 40,y = 4,size = 1)	# Show its hand
            robot_name = "ROCK"	# Name for the report
        elif robot == 2:	# Robot drew Paper
            oled.image(Paper,x = 40,y = 4,size = 1)	# Show its hand
            robot_name = "PAPER"	# Name
        else:	# Robot drew Scissors
            oled.image(Scissors,x = 40,y = 4,size = 1)	# Show its hand
            robot_name = "SCISSORS"	# Name
        oled.show()	# Publish the arena
        print("Robot plays:", robot_name)	# Serial reveals it
        if my == robot:	# Same codes same move!
            print("TIE! Nobody scores")	# The verdict
        elif (my == 1 and robot == 3) or (my == 2 and robot == 1) or (my == 3 and robot == 2):	# Rock beats Scissors, Paper beats Rock, Scissors beats Paper
            my_wins += 1	# Your score grows
            print("YOU WIN! Score:", my_wins, "-", robot_wins)	# The verdict
        else:	# Every other case
            robot_wins += 1	# Robot scores
            print("ROBOT WINS! Score:", my_wins, "-", robot_wins)	# The verdict
        time.sleep_ms(2000)	# Admire the arena before the next round
print("========== FINAL SCORE ==========")	# The summary wall
print("You:", my_wins, "| Robot:", robot_wins)	# Both tallies
if my_wins > robot_wins:	# You scored more?
    print("CHAMPION: YOU! The machines bow.")	# Glory
elif robot_wins > my_wins:	# Robot scored more?
    print("CHAMPION: THE ROBOT. Rematch?")	# Defeat, politely
else:	# Equal scores
    print("A DRAW! Perfect balance.")	# Harmony

Serial Monitor: 

=== ROCK PAPER SCISSORS === 

Type R, P or S STOP to end 

Your move: R 

Robot plays: SCISSORS 

YOU WIN! Score: 1 - 0 

Your move: P 

Robot plays: SCISSORS 

ROBOT WINS! Score: 1 - 1 

Your move: S 

Robot plays: S 

TIE! Nobody scores 

Your move: STOP 

========== FINAL SCORE ========== 

You: 1 | Robot: 1 

A DRAW! Perfect balance. 

💡 Note the graduation exercise: every idea you own appears on stage one last time. The command menu and input() (Module 1) · the else safety net (Mini-Assistant) · random numbers (the Dice) · break (Security System) · clear-publish frames (today) · and the crown jewel, the win-combination logic: (Rock beats Scissors) OR (Paper beats Rock) OR (Scissors beats Paper) one line holding the entire rules of the game. Design challenge for advanced teams: the robot plays purely randomly it can be beaten by pattern-spotting humans. Could it remember your last move and counter it? That single upgrade turns a toy into a strategy opponent... and it needs exactly one memory variable you already know how to use. The displays family is complete: your robot can now speak, show its face, draw, animate and play. Next stop the human controls: six buttons and two axes waiting on a shield.