nimphea/dev/oled_sh1106

Source   Edit  

SH1106 OLED Display driver for libDaisy Nim wrapper

The SH1106 is a popular and cost-effective alternative to the SSD1306 OLED controller. It is nearly identical to the SSD130x series, with the primary difference being the column addressing scheme used in the Update() method. This driver extends the SSD130x driver and only overrides the Update() implementation.

Features:

  • 128x64 monochrome display support
  • I2C and 4-wire SPI transport options
  • Compatible with SSD130x API (drop-in replacement)
  • Same drawing functions as SSD130x (pixel, line, rect, circle, etc.)

Hardware Notes:

  • Common in cheap OLED modules (often labeled "SSD1306 compatible")
  • Column addressing differs: uses 0x02 base instead of 0x00
  • Uses same transports (SSD130xI2CTransport, SSD130x4WireSpiTransport)

Example - I2C display:

import nimphea
import nimphea/dev/oled_sh1106

var display = initSH1106I2c(128, 64)
display.fill(false)
display.drawPixel(64, 32, true)
display.drawCircle(64, 32, 10, true)
display.update()

Example - SPI display (faster updates):

import nimphea
import nimphea/dev/oled_sh1106

var display = initSH1106Spi(128, 64)
while true:
  display.fill(false)
  display.drawRect(10, 10, 108, 44, true)
  display.update()
  hw.delay(50)

Differences from SSD130x:

  • Update() uses different column start address (0x02 vs 0x00)
  • Same initialization sequence
  • Same framebuffer format
  • Same drawing API

Types

SH1106I2c128x64 {.importcpp: "SH1106I2c128x64".} = object
Source   Edit  
SH1106I2cConfig {.importcpp: "SH1106I2c128x64::Config", bycopy.} = object
  transport_config* {.importc: "transport_config".}: SSD130xI2CTransportConfig
Source   Edit  
SH1106Spi128x64 {.importcpp: "SH1106Spi128x64".} = object
Source   Edit  
SH1106SpiConfig {.importcpp: "SH1106Spi128x64::Config", bycopy.} = object
  transport_config* {.importc: "transport_config".}: SSD130x4WireSpiTransportConfig
Source   Edit  
SSD130x4WireSpiTransportConfig {.importcpp: "daisy::SSD130x4WireSpiTransport::Config",
                                 bycopy.} = object
  spi_config* {.importc: "spi_config".}: SpiConfig
  pin_config* {.importc: "pin_config".}: SSD130xSpiPinConfig
  useDma* {.importc: "useDma".}: bool
Source   Edit  
SSD130xI2CTransportConfig {.importcpp: "daisy::SSD130xI2CTransport::Config",
                            bycopy.} = object
  i2c_config* {.importc: "i2c_config".}: I2CConfig
  i2c_address* {.importc: "i2c_address".}: uint8
Source   Edit  
SSD130xSpiPinConfig {.importcpp: "daisy::SSD130x4WireSpiTransport::Config::pin_config",
                      bycopy.} = object
  dc* {.importc: "dc".}: Pin
  reset* {.importc: "reset".}: Pin
Source   Edit  

Consts

SH1106_I2C_ADDRESS_ALT = 0x0000003D
Alternate I2C address (set via jumper on some modules) Source   Edit  
SH1106_I2C_ADDRESS_DEFAULT = 0x0000003C
Default I2C address for SH1106 displays Source   Edit  

Procs

proc Defaults(config: var SSD130x4WireSpiTransportConfig) {.
    importcpp: "#.Defaults()", header: "daisy_seed.h", ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc Defaults(config: var SSD130xI2CTransportConfig) {.
    importcpp: "#.Defaults()", header: "daisy_seed.h", ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc drawCircle(display: var OledSH1106; x0, y0, radius: int; on: bool = true)

Draw a circle outline using midpoint circle algorithm

Parameters:

  • x0, y0 - Center point
  • radius - Circle radius in pixels
  • on - true for white, false for black
Source   Edit  
proc drawLine(display: var OledSH1106; x0, y0, x1, y1: int; on: bool = true)

Draw a line using Bresenham's algorithm

Parameters:

  • x0, y0 - Start point
  • x1, y1 - End point
  • on - true for white, false for black
Source   Edit  
proc drawPixel(display: var OledSH1106; x, y: int; on: bool = true)

Draw a single pixel

Parameters:

  • x, y - Pixel coordinates (0-based)
  • on - true for white, false for black
Source   Edit  
proc drawRect(display: var OledSH1106; x, y, w, h: int; on: bool = true)

Draw a rectangle outline

Parameters:

  • x, y - Top-left corner
  • w, h - Width and height
  • on - true for white, false for black
Source   Edit  
proc fill(display: var OledSH1106; on: bool = true)

Fill entire display with a color

Parameters:

  • on - true for white, false for black
Source   Edit  
proc fillRect(display: var OledSH1106; x, y, w, h: int; on: bool = true)

Draw a filled rectangle

Parameters:

  • x, y - Top-left corner
  • w, h - Width and height
  • on - true for white, false for black
Source   Edit  
proc height(display: OledSH1106): int {.inline.}
Get display height in pixels Source   Edit  
proc update(display: var OledSH1106)
Send framebuffer to display hardware Call this after drawing to make changes visible Source   Edit  
proc width(display: OledSH1106): int {.inline.}
Get display width in pixels Source   Edit  

Templates

template initSH1106I2c(width, height: static[int];
                       sclPin: Pin = newPin(PORTB, 8);
                       sdaPin: Pin = newPin(PORTB, 9);
                       address: uint8 = 0x0000003C): untyped

Initialize SH1106 OLED via I2C

Parameters:

  • width, height - Display dimensions (only 128x64 supported)
  • sclPin - I2C clock pin (default: PB8)
  • sdaPin - I2C data pin (default: PB9)
  • address - I2C address (default: 0x3C, alt: 0x3D)

Returns: Initialized display instance

Example:

var oled = initSH1106I2c(128, 64)
oled.fill(false)
oled.drawPixel(64, 32, true)
oled.update()

Source   Edit  
template initSH1106Spi(width, height: static[int];
                       dcPin: Pin = newPin(PORTB, 4);
                       resetPin: Pin = newPin(PORTB, 15);
                       sclkPin: Pin = newPin(PORTG, 11);
                       mosiPin: Pin = newPin(PORTB, 5);
                       nssPin: Pin = newPin(PORTG, 10)): untyped

Initialize SH1106 OLED via SPI (faster than I2C)

Parameters:

  • width, height - Display dimensions (only 128x64 supported)
  • dcPin - Data/Command pin (default: PB4)
  • resetPin - Reset pin (default: PB15)
  • sclkPin - SPI clock pin (default: PG11)
  • mosiPin - SPI MOSI pin (default: PB5)
  • nssPin - SPI chip select pin (default: PG10)

Returns: Initialized display instance

Example:

var oled = initSH1106Spi(128, 64)
while true:
  oled.fill(false)
  oled.drawCircle(64, 32, 20, true)
  oled.update()
  hw.delay(50)

Source   Edit