1 bit OLED display controller


ssd1306 provides support for the SSD1306 monochrome OLED display controller via I²C or SPI in 4-wire mode.

It can control displays up to 128x64 in size.


The driver as the following functionality:

  • Differential updates. Only the differing bits are sent, saving bus bandwidth!
  • Support for both I²C and SPI connectivity
  • Scrolling
  • Support for any display size


Use cmd/ssd1306 to stream animanted GIFs to the display.



Purpose: display an animated GIF.

This example uses a ssd1306. The frames in the GIF are resized and centered first to reduce the CPU overhead.

package main

import (


// convertAndResizeAndCenter takes an image, resizes and centers it on a
// image.Gray of size w*h.
func convertAndResizeAndCenter(w, h int, src image.Image) *image.Gray {
    src = resize.Thumbnail(uint(w), uint(h), src, resize.Bicubic)
    img := image.NewGray(image.Rect(0, 0, w, h))
    r := src.Bounds()
    r = r.Add(image.Point{(w - r.Max.X) / 2, (h - r.Max.Y) / 2})
    draw.Draw(img, r, src, image.Point{}, draw.Src)
    return img

func main() {
    // Load all the drivers:
    if _, err := host.Init(); err != nil {

    // Open a handle to the first available I²C bus:
    bus, err := i2creg.Open("")
    if err != nil {

    // Open a handle to a ssd1306 connected on the I²C bus:
    dev, err := ssd1306.NewI2C(bus, 128, 64, false)
    if err != nil {

    // Decodes an animated GIF as specified on the command line:
    if len(os.Args) != 2 {
        log.Fatal("please provide the path to an animated GIF")
    f, err := os.Open(os.Args[1])
    if err != nil {
    g, err := gif.DecodeAll(f)
    if err != nil {

    // Converts every frame to image.Gray and resize them:
    imgs := make([]*image.Gray, len(g.Image))
    for i := range g.Image {
        imgs[i] = convertAndResizeAndCenter(dev.W, dev.H, g.Image[i])

    // Display the frames in a loop:
    for i := 0; ; i++ {
        index := i % len(imgs)
        c := time.After(time.Duration(10*g.Delay[index]) * time.Millisecond)
        img := imgs[index]
        dev.Draw(img.Bounds(), img, image.Point{})

Smoke test

Setup for SSD1306 smoke test:

  • Two SSD1306 connected to a Raspberry Pi 3:
    • the left one is connected via SPI:
    • the right one is connected via I²C

It confirms that two SSD1306 controllers can be driven simultaneously, one connected via I²C, one via SPI. They shall display the same output.


The periph authors do not endorse any specific seller. These are only provided for your convenience.