PyRaspBeta

OLED 128×64 (I²C)

A 0.96″ SSD1306 OLED is a 128×64 pixel monochrome display that makes its own light. It costs $8 and shows real graphics — sensor plots, big numbers, small icons — where a character LCD can only show text. Everything is drawn on the Pi into a framebuffer and pushed over I²C one screen at a time. The LCD and TM1637 pages cover the simpler displays.

OLED 128×64 (I²C)

Pins

PinWhat it isType
GNDGroundground
VCCSupply 3.3–5 Vpower
SCLI²C clockio
SDAI²C dataio
SettingTypeRangeDefault
addressenum0x3C, 0x3D0x3C
colorenumwhite, blue, yellow-bluewhite

VCC takes 3.3–5 V, GND is ground, and SCL/SDA are the Pi's I²C pins. Most modules have no reset pin. The address setting picks 0x3C (the usual default) or 0x3D, and color picks which panel is drawn.

Wiring it in circuit.py

circuit.py
from wiring import *

pi = Pi()

oled = OLED()

pi.V3_3 >> oled.vcc
oled.gnd >> pi.GND
pi.SDA >> oled.sda
pi.SCL >> oled.scl

Driving it in main.py

The runtime ships Adafruit's adafruit_ssd1306 and its framebuffer library, so this example runs here and on a real Pi with pip install adafruit-circuitpython-ssd1306:

main.py
import board
import adafruit_ssd1306
from time import sleep

oled = adafruit_ssd1306.SSD1306_I2C(128, 64, board.I2C())

frame = 0
while True:
    oled.fill(0)
    oled.text("PyRasp", 24, 4, 1)
    oled.rect(0, 20, 128, 44, 1)
    oled.fill_rect(8 + frame % 100, 30, 12, 24, 1)
    oled.show()
    frame += 4
    sleep(0.1)

The drawing methods — pixel, hline, vline, rect, fill_rect, text — write into memory; nothing appears until show() pushes the framebuffer.

Electrical notes

  • Supply 3–5 V. The model loads the rail with a fixed 8 mA; the datasheet's figure for all 128×64 pixels lit is about 20 mA, and a real panel's draw rises with the lit fraction — which is why OLEDs are prized for low-power projects.
  • Two addresses, 0x3C or 0x3D, chosen by a solder jumper on the module.
  • The controller needs its charge pump: nothing lights until the init sequence writes 0x8D, 0x14 (charge pump on) and 0xAF (display on). Libraries do this in their constructor.
  • Display RAM is organised in 8 pages of vertical 8-pixel strips; a framebuffer library hides that, but raw-command code must set a page and column before each byte.
  • Segment remap (0xA1) and COM scan reverse (0xC8) orient the glass; without them an image comes out rotated 180°. Start line and display offset shift which row of RAM lands at the top.
  • The two-colour version has its top 16 rows wired yellow; inside it is still one monochrome controller.

Simulator vs real hardware

  • The part decodes the controller's real command and data streams — control bytes 0x00/0x40 (streams) and 0x80/0xC0 (single byte), multi-byte commands with their arguments, page/horizontal/vertical addressing, contrast, invert and all-on — and renders the mapped RAM to the canvas. Adafruit's driver and raw smbus2 code both work.
  • Reading back returns the status byte 0x03; real drivers rarely do, and some modules cannot read at all.
  • Text uses the vendored 5×8 font (font5x8.bin) exactly as on hardware, so a mis-drawn string looks the same; the canvas shows lit pixels, with no anti-aliasing.
  • The address and colour settings are props: they change what the part answers and how it is painted, not the protocol.

Going deeper

Further reading