# Monochrome OLED Breakouts

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/000/654/medium800/lcds___displays_oledlorem.jpg?1396764781)

![](https://cdn-learn.adafruit.com/assets/assets/000/000/655/medium800/lcds___displays_spi12832text.jpg?1396764789)

This is a quick tutorial for our 128x64 and 128x32 pixel monochrome OLED displays. These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. Each OLED display is made of 128x64 or 128x32 individual white OLEDs, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is required. This reduces the power required to run the OLED and is why the display has such high contrast; we really like this miniature display for its crispness!

![](https://cdn-learn.adafruit.com/assets/assets/000/000/656/medium800/lcds___displays_oledfront.jpg?1396764795)

The driver chip,&nbsp; **SSD1306** &nbsp;can communicate in multiple ways including&nbsp; **I2C** ,&nbsp; **SPI** &nbsp;and&nbsp; **8-bit parallel**. However, only the 128x64 display has all these interfaces available. For the 128x32 OLED, only SPI is available. Frankly, we prefer SPI since its the most flexible and uses a small number of I/O pins so our example code and wiring diagram will use that.

For the 0.96" STEMMA QT version, **we've updated the design to add auto-reset circuitry** so that the reset pin is optional, since it speaks I2C you can easily connect it up with just two wires (plus power and ground!).&nbsp; We've even included [SparkFun qwiic](https://www.sparkfun.com/qwiic) compatible**&nbsp;[STEMMA QT](https://learn.adafruit.com/introducing-adafruit-stemma-qt)**&nbsp;connectors for the I2C bus so **you don't even need to solder!** &nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/093/886/medium800/adafruit_products_326.jpg?1596746400)

# Monochrome OLED Breakouts

## Power Requirements

## OLED Power Requirements
The OLED and driver require a 3.3V power supply and 3.3V logic levels for communication. The power requirements depend a little on how much of the display is lit but on average the display uses about 20mA from the 3.3V supply. Built into the OLED driver is a simple switch-cap charge pump that turns 3.3v-5v into a high voltage drive for the OLEDs. You can run the entire display off of one 3.3V supply or use 3.3V for the chip power and up to 4.5V for the OLED charge pump or 3.3V for the chip power and a 7-9V supply directly into the OLED high voltage pin.## 5V- ready 128x64 and 128x32 OLEDs
Unless you have the older v1 128x64 OLED, you can rest assured that your OLED is 5V ready. All 1.3" 128x64 and the small 128x32 SPI and I2C are 5V ready, if you have a v2 0.96" 128x64 OLED with the 5V ready mark on the front, it's also 5V safe. If you have an older 0.96" OLED (see below) you'll need to take extra care when wiring it to a 5V micontroller. The OLED is designed to be 5V compatible so you can power it with 3-5V and the onboard regulator will take care of the rest.  
  
All OLEDs are safe to use with 3.3V logic and power.  
![](https://cdn-learn.adafruit.com/assets/assets/000/001/301/medium800/lcds___displays_spi12832solder.jpg?1396770813)

Simply connect&nbsp; **GND** &nbsp;to ground, and&nbsp; **Vin** &nbsp;to a 3 to 5V power supply. There will be a 3.3V output on the&nbsp; **3Vo** &nbsp;pin in case you want a regulated 3.3V supply for something else.

## 0.96" 128x64 OLED
The older 0.96" 128x64 OLED is a little more complex to get running as it is not 5V compatible by default, so you have to provide it with 3.3V power.![](https://cdn-learn.adafruit.com/assets/assets/000/001/302/medium800/lcds___displays_oledback.jpg?1396770824)

- **VDD** &nbsp;is the 3.3V logic power. This must be 3 or 3.3V
- **VBAT** &nbsp;is the input to the charge pump. If you use the charge pump, this must be 3.3V to 4.2V
- **VCC&nbsp;** is the high voltage OLED pin. If you're using the internal charge pump, this must be left unconnected. If you're not using the charge pump, connect this to a 7-9V DC power supply.

For most users, we suggest connecting&nbsp; **VDD** &nbsp;and **&nbsp;VBAT** &nbsp;together to 3.3V and then leaving&nbsp; **VCC** &nbsp;unconnected.

# Monochrome OLED Breakouts

## Arduino Library & Examples

For all of the different kinds of small OLED monochrome displays, you'll need to install the Arduino libraries. The code we have is for any kind of Arduino, if you're using a different microcontroller, the code is pretty simple to adapt, the interface we use is basic bit-twiddling SPI or I2C

# Install Arduino Libraries

Using these OLEDs with Arduino sketches requires that two libraries be installed: **Adafruit\_SSD1306** , which handles the low-level communication with the hardware, and **Adafruit\_GFX** , which builds atop this to add graphics functions like lines, circles and text.

In recent versions of the Arduino IDE software (1.6.2 and later), this is most easily done through the Arduino Library Manager.

Open up the Arduino library manager:

![](https://cdn-learn.adafruit.com/assets/assets/000/084/024/medium800/adafruit_products_library_manager_menu.png?1573518575)

Search for the&nbsp; **Adafruit SSD1306** &nbsp;library and install it

![](https://cdn-learn.adafruit.com/assets/assets/000/084/023/medium800/adafruit_products_ssd1306.png?1573518516)

Search for the&nbsp; **Adafruit GFX** &nbsp;library and install it

![](https://cdn-learn.adafruit.com/assets/assets/000/084/025/medium800/adafruit_products_gfx.png?1573518658)

If using an earlier version of the Arduino IDE (prior to 1.8.10), also locate and install **Adafruit\_BusIO** (newer versions will install this dependency automatically).

We also have a great tutorial on Arduino library installation here:  
[http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use](http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use "Link: http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use")

# Run Demo!

After installing the **Adafruit\_SSD1306** and **Adafruit\_GFX** library, restart the Arduino IDE. You should now be able to access the sample code by navigating through menus in this order: **File→Examples→**** Adafruit\_SSD1306→SSD1306...**

![](https://cdn-learn.adafruit.com/assets/assets/000/031/974/medium800/lcds___displays_Screenshot_1.png?1461689893)

After you've finished wiring the display as indicated on the following pages, load the example sketch to demonstrate the capabilities of the library and display.

[The OLED SSD1306 driver is based on the Adafruit GFX library which provides all the underlying graphics functions such as drawing pixels, lines, circles, etc. For more details about what you can do with the OLED check out the GFX library tutorial](http://learn.adafruit.com/adafruit-gfx-graphics-library "Link: http://learn.adafruit.com/adafruit-gfx-graphics-library")

![](https://cdn-learn.adafruit.com/assets/assets/000/000/705/medium800/lcds___displays_oled12864logo_LRG.jpg?1396765152)

![](https://cdn-learn.adafruit.com/assets/assets/000/000/706/medium800/lcds___displays_oled12864chars_LRG.jpg?1396765158)

## Create Bitmaps with LCD Assistant

You can create bitmaps to display easily with the [LCD assistant software](http://en.radzio.dxp.pl/bitmap_converter/). First make your image using any kind of graphics software such as photoshop or Paint and save as a **Monochrome Bitmap (bmp)**

![](https://cdn-learn.adafruit.com/assets/assets/000/000/707/medium800/lcds___displays_bitmapmono.gif?1447976331)

Select the following options (You might also want to try **Horizontal** if **Vertical** is not coming out right)

![](https://cdn-learn.adafruit.com/assets/assets/000/000/708/medium800/lcds___displays_bitmapconvert.gif?1447976341)

and import your monochrome bitmap image. Save the output to a&nbsp; **cpp** &nbsp;file![](https://cdn-learn.adafruit.com/assets/assets/000/000/709/medium800/lcds___displays_bitmapsave.gif?1447976348)

You can use the output directly with our example code![](https://cdn-learn.adafruit.com/assets/assets/000/000/710/medium800/lcds___displays_bitmapout.gif?1447976355)

## Create Bitmaps with image2cpp

image2cpp was created by GitHub user javl and provides a handy way to create bitmaps without installing any additional software. Just visit [https://javl.github.io/image2cpp/,](https://javl.github.io/image2cpp/) upload an image, put in any settings that you would like to use, select a format and generate the code. You can copy the code right into your sketch. If you're interested, you can view the source in their [GitHub repository](https://github.com/javl/image2cpp).

# Monochrome OLED Breakouts

## Wiring 128x64 OLEDs

## Solder Header
  
Before you start wiring, a strip of header must be soldered onto the OLED. It is not possible to "press-fit" the header, it must be attached!  
Start by placing an 8-pin piece of header with the&nbsp; **long** ends down into a breadboard for stability

![lcds___displays_headerplace.jpg](https://cdn-learn.adafruit.com/assets/assets/000/002/616/medium640/lcds___displays_headerplace.jpg?1396785089)

Place the OLED on top so all the short ends of the header stick thru the header pads

![lcds___displays_oledplace.jpg](https://cdn-learn.adafruit.com/assets/assets/000/002/617/medium640/lcds___displays_oledplace.jpg?1396785097)

Finish by soldering each of the 8 pins to the 8 pads!

![lcds___displays_solder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/002/618/medium640/lcds___displays_solder.jpg?1396785110)

# I2C or SPI

The nice thing about the 128x64 OLEDs is that they can be used with I2C (+ an optional reset line) or SPI. SPI is generally faster than I2C but uses more pins. It's also easier for some microcontrollers to use SPI. Anyways, you can use either one with this display

## Using with I2C

The display can be used with any I2C microcontroller. Because the I2C interface is for 'writing' to the display only, you'll still have to buffer the entire 512 byte frame in the microcontroller RAM - you can't read data from the OLED (even though I2C is a bidirectional protocol).

If you have the older non-STEMMA version of the OLED, you'll need to solder the two jumpers on the back of the OLED. **Both** must be soldered 'closed' for I2C to work!

![adafruit_products_lcds___displays_oledi2c.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/883/medium640/adafruit_products_lcds___displays_oledi2c.jpg?1596745237)

For the new STEMMA-capable version, the **J1** and **J2** jumpers are closed so that the display is **by default in I2C mode!**

**There's a typo on the board, to put it into SPI, _open_ the two jumpers (as they're closed by default)**

![adafruit_products_newoled.jpg](https://cdn-learn.adafruit.com/assets/assets/000/086/658/medium640/adafruit_products_newoled.jpg?1578330932)

## Converting From I2C to SPI Mode

The original version of this display was SPI by default, and you could convert to I2C with some light soldering. Many folks using these displays did not know how to solder, didn't own an iron or were not comfortable with soldering, so we converted the board to STEMMA QT 'plug and play' I2C so no soldering is required to use in I2C mode.

To convert it back to SPI is very easy, and requires a thin screwdriver or other sharp-tipped item **be careful not to cut towards you as always so you do not accidentally cut yourself!**

https://youtu.be/SXfV4e_jpf8

## Wiring It Up!
Info: 

Warning: 

Finally, connect the pins to your Arduino

- **GND** goes to ground **(black wire on STEMMA QT version)**
- **Vin** goes to 5V **(red wire on STEMMA QT version)**
- **Data** to I2C SDA (on the Uno, this is **A4** on the Mega it is **20** and on the Leonardo digital **2** ) **(blue wire on STEMMA QT version)**
- **Clk** to I2C SCL (on the Uno, this is **A5** on the Mega it is **21** and on the Leonardo digital **3** ) **(yellow wire on STEMMA QT version)**
- **RST** to digital **4** (you can change this pin in the code, later) (Not necessary on 0.96" STEMMA QT version)

This matches the example code we have written. Once you get this working, you can try a different Reset pin (you can't change the SDA and SCL pins).  
  
Finally you can run the **File→Sketchbook→Libraries→Adafruit\_SSD1306→SSD1306\_128x64\_i2c** example. If you wired the RST pin to a GPIO pin, change `#define OLED_RESET     -1`&nbsp; to the new pin number.

https://github.com/adafruit/Adafruit_SSD1306/blob/master/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino

## Using with SPI
The breakouts are ready for SPI by default, but if you used them for I2C at some point, you'll need to remove the solder jumpers. Use wick or a solder sucker to make sure both are clear!  
If you have the older non-STEMMA version of the OLED, the breakouts are ready for SPI by default.

If you used them for I2C at some point, you'll need to remove the solder jumpers. Use wick or a solder sucker to make sure both are clear!

![lcds___displays_spijumpers.jpg](https://cdn-learn.adafruit.com/assets/assets/000/002/619/medium640/lcds___displays_spijumpers.jpg?1396785123)

If you have the newer STEMMA QT version **cut** the two jumpers instead!

![adafruit_products_938_bottom_demo_detail_orig_2020_01_720.jpg](https://cdn-learn.adafruit.com/assets/assets/000/086/687/medium640/adafruit_products_938_bottom_demo_detail_orig_2020_01_720.jpg?1578366507)

Finally, connect the pins to your Arduino -

- **GND** goes to ground
- **Vin** goes to 5V
- **DATA** to digital **9**
- **CLK** to digital **10**
- **D/C** to digital **11**
- **RST** to digital **13**
- **CS** to digital **12**

_( **Note** : If using the display with other SPI devices, D/C, CLK and DAT may be shared, but CS must be unique for each device.)_   
  
This matches the example code we have written. Once you get this working, you can try another set of pins.   
  
Finally you can run the **File→Sketchbook→Libraries→Adafruit\_SSD1306→SSD1306\_128x64\_spi** example

https://github.com/adafruit/Adafruit_SSD1306/blob/master/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino

# Monochrome OLED Breakouts

## Wiring 128x32 SPI OLED display

## 128x32 SPI OLED
The 128x32 SPI OLED is very easy to get up and running because it has built in level shifting. First up, take a piece of 0.1" header 8 pins long.  
  
![](https://cdn-learn.adafruit.com/assets/assets/000/001/124/medium800/lcds___displays_spi12832pins.jpg?1396769016)

Plug the header long end down into a breadboard and place the OLED on top. Solder the short pins into the OLED PCB.![](https://cdn-learn.adafruit.com/assets/assets/000/001/125/medium800/lcds___displays_spi12832solder.jpg?1396769023)

Finally, connect the pins to your Arduino -&nbsp; **GND** &nbsp;goes to ground,&nbsp; **Vin** &nbsp;goes to 5V,&nbsp; **DATA** &nbsp;to digital&nbsp; **9** ,&nbsp; **CLK** &nbsp;to digital&nbsp; **10** ,&nbsp; **D/C** &nbsp;to digital&nbsp; **11** ,&nbsp; **RST** &nbsp;to digital&nbsp; **13** &nbsp;and finally&nbsp; **CS** &nbsp;to digital&nbsp; **12.**  
  
_( **Note** : If using the display with other SPI devices, D/C, CLK and DAT may be shared, but CS must be unique for each device.)_&nbsp;&nbsp;  
  
This matches the example code we have written. Once you get this working, you can try another set of pins.&nbsp;&nbsp;  
  
Finally you can run the&nbsp; **File→Sketchbook→Libraries→Adafruit\_SSD1306→SSD1306\_128x32\_SPI&nbsp;example**  
  
  
Info: 

# Monochrome OLED Breakouts

## Wiring 128x32 I2C Display

## 128x32 I2C OLED
The 128x32 I2C OLED is very easy to get up and running because it has built in level shifting and regulator. First up, take a piece of 0.1" header 6 pins long.  
Plug the header long end down into a breadboard![lcds___displays_header.jpg](https://cdn-learn.adafruit.com/assets/assets/000/001/157/medium640/lcds___displays_header.jpg?1396769302)

Place the OLED on top

![lcds___displays_place.jpg](https://cdn-learn.adafruit.com/assets/assets/000/001/158/medium640/lcds___displays_place.jpg?1396769313)

Solder the short pins into the OLED PCB.![lcds___displays_soldered.jpg](https://cdn-learn.adafruit.com/assets/assets/000/001/159/medium640/lcds___displays_soldered.jpg?1396769320)

![](https://cdn-learn.adafruit.com/assets/assets/000/001/160/medium800/lcds___displays_wiring.jpg?1396769328)

Finally, connect the pins to your Arduino

- **GND** &nbsp;goes to ground
- **Vin** &nbsp;goes to 5V
- **SDA** to I2C Data **SDA** pin (on the Uno, this is **A4** on the Mega it is&nbsp; **20&nbsp;** and on the Leonardo digital&nbsp; **2** )
- **SCL** &nbsp; to I2C Clock **SCL** pin (on the Uno, this is **A5** on the Mega it is&nbsp; **21&nbsp;** and on the Leonardo digital&nbsp; **3** )
- **RST** &nbsp;to digital&nbsp; **4** &nbsp; (you can change this pin in the code, later)

This matches the example code we have written. Once you get this working, you can change the RST pin. You cannot change the I2C pins, those are 'fixed' in hardware  
  
Finally you can run the&nbsp; **File→Sketchbook→Libraries→Adafruit\_SSD1306→SSD1306\_128x32\_i2c&nbsp;** example. If you wired the RST pin to a GPIO pin, change `#define OLED_RESET     -1`&nbsp; to the new pin number.

https://github.com/adafruit/Adafruit_SSD1306/blob/master/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino

# Monochrome OLED Breakouts

## Wiring OLD 0.96" 128x64 OLED

Info: 

## 128x64 Version 1.0 OLED
The version 1 128x64 OLED runs at 3.3V and does not have a built in level shifter so you'll need to use a level shifting chip to use with a 5V microcontroller. The following will assume that is the case. If you're running a 3.3V microcontroller system, you can skip the level shifter.We'll assume you want to use this in a breadboard, take a piece of 0.1" header 10 pins long.

![lcds___displays_headercut.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/692/medium640/lcds___displays_headercut.jpg?1396765068)

Place the header in a breadboard and then place the left hand side of the OLED on top.![lcds___displays_oledheader.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/694/medium640/lcds___displays_oledheader.jpg?1396765083)

And solder the pins

![lcds___displays_oledsoldered.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/697/medium640/lcds___displays_oledsoldered.jpg?1396765103)

We'll be using the internal charge pump so connect&nbsp; **VDD** &nbsp;and&nbsp; **VBAT&nbsp;** together (they will connect to 3.3V) **.&nbsp;** GND goes to ground.![lcds___displays_oledpower.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/700/medium640/lcds___displays_oledpower.jpg?1396765097)

Place a CD4050 level shifter chip so pin one is at the top.![lcds___displays_chipplace.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/701/medium640/lcds___displays_chipplace.jpg?1396765119)

Connect pin 10 to&nbsp; **D/C** &nbsp;pin 12 to **&nbsp;CLK&nbsp;** (SPI clock) and pin 15 to&nbsp; **DAT&nbsp;** (SPI data).![lcds___displays_chipwire1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/702/medium640/lcds___displays_chipwire1.jpg?1396765126)

Connect pin 2 to&nbsp; **RES** &nbsp;(reset) and pin 4 to&nbsp; **CS** &nbsp;(chip select). Pin 1 goes to 3.3V and pin 8 to ground.  
  
_( **Note** : If using the display with other SPI devices, D/C, CLK and DAT may be shared, but CS must be unique for each device.)_

![lcds___displays_chipwire2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/703/medium640/lcds___displays_chipwire2.jpg?1396765134)

You can connect the inputs of the level shifter to any pins you want but in this case we connected digital I/O&nbsp; **13** &nbsp;to pin 3 of the level shifter,&nbsp; **12** &nbsp;to pin 5,&nbsp; **11&nbsp;** to pin 9,&nbsp; **10** &nbsp;to pin 11 and&nbsp; **9&nbsp;** to pin 14. This matches the example code we have written. Once you get this working, you can try another set of pins.![lcds___displays_wired.jpg](https://cdn-learn.adafruit.com/assets/assets/000/000/704/medium640/lcds___displays_wired.jpg?1396765142)

# Monochrome OLED Breakouts

## CircuitPython Wiring

It's easy to use OLEDs with CircuitPython and the [Adafruit CircuitPython DisplayIO SSD1306](https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306) module.&nbsp; This module allows you to easily write CircuitPython code to control the display.

You can use this sensor with any CircuitPython microcontroller board.

We'll cover how to wire the OLED to your CircuitPython microcontroller board. First assemble your OLED.

Connect the OLED to your microcontroller board as shown below.

## Adafruit OLED FeatherWing
- **Solder the Feather with female headers on top or stacking headers.**
- **Attach the OLED FeatherWing using the stacking method.**

![adafruit_products_FeatherM4_OLED_FeatherWing_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/585/medium640/adafruit_products_FeatherM4_OLED_FeatherWing_bb.jpg?1546450633)

## Adafruit 128x32 I2C OLED Display
- **Microcontroller 3V** to **OLED VIN**
- **Microcontroller GND** to **OLED GND**
- **Microcontroller SCL** to **OLED SCL**
- **Microcontroller SDA** to **OLED SDA**
- **Microcontroller D9** to **OLED RST**

![adafruit_products_FeatherM4_128_32_I2C_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/726/medium640/adafruit_products_FeatherM4_128_32_I2C_OLED_bb.jpg?1546721739)

## Adafruit 128x32 SPI OLED Display
- **Microcontroller 3V** to **OLED VIN**
- **Microcontroller GND** to **OLED GND**
- **Microcontroller SCK** to **OLED CLK**
- **Microcontroller MOSI** to **OLED Data**
- **Microcontroller D5** to **OLED CS**
- **Microcontroller D6** to **OLED D/C**
- **Microcontroller D9** to **OLED RST**

![adafruit_products_FeatherM4_128_32_SPI_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/727/medium640/adafruit_products_FeatherM4_128_32_SPI_OLED_bb.jpg?1546721926)

## Adafruit 0.96" 128x64 OLED Display STEMMA QT Version - I2C Wiring
 **You do not need to alter the jumpers on the back - I2C is the default configuration on this display!**

- **Microcontroller 3V** to **OLED Vin**  
- **Microcontroller GND** to **OLED Gnd**
- **Microcontroller SCL** to **OLED Clk**  
- **Microcontroller SDA** to **OLED Data**

Note: Connecting the OLED RST is not necessary as this revision added auto-reset circuitry so the RESET pin is not required.

![adafruit_products_0-96in_OLED_FeatherM4_STEMMA_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/882/medium640/adafruit_products_0-96in_OLED_FeatherM4_STEMMA_bb.jpg?1596745061)

## Adafruit 0.96" or 1.3" 128x64 OLED Display Original Version - I2C Wiring
Warning: 

- **Microcontroller 3V** to **OLED Vin**  
- **Microcontroller GND** to **OLED Gnd**
- **Microcontroller SCL** to **OLED Clk**  
- **Microcontroller SDA** to **OLED Data**  
- **Microcontroller D9** to **OLED Rst**

![adafruit_products_FeatherM4_128_64_I2C_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/737/medium640/adafruit_products_FeatherM4_128_64_I2C_OLED_bb.jpg?1546732943)

![adafruit_products_OLED_jumper_I2C.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/738/medium640/adafruit_products_OLED_jumper_I2C.jpg?1546732949)

![adafruit_products_FeatherM4_1_3_inch_128_64_I2C_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/755/medium640/adafruit_products_FeatherM4_1_3_inch_128_64_I2C_OLED_bb.jpg?1546737543)

![adafruit_products_1-3inch_128x64_oled_back.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/756/medium640/adafruit_products_1-3inch_128x64_oled_back.jpg?1546737562)

## Adafruit 0.96" or 1.3"&nbsp; 128x64 OLED Display - SPI Wiring
Warning: 

- **Microcontroller 3V** to **OLED Vin**
- **Microcontroller GND** to **OLED Gnd**  
- **Microcontroller SCK** to **OLED Clk**
- **Microcontroller MOSI** to **OLED Data**
- **Microcontroller D5** to **OLED CS**
- **Microcontroller D6** to **OLED DC**
- **Microcontroller D9** to **OLED Rst**

![adafruit_products_FeatherM4_128_64_SPI_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/740/medium640/adafruit_products_FeatherM4_128_64_SPI_OLED_bb.jpg?1546733303)

![adafruit_products_FeatherM4_1_3_inch_128_64_SPI_OLED_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/754/medium640/adafruit_products_FeatherM4_1_3_inch_128_64_SPI_OLED_bb.jpg?1546737464)

# Monochrome OLED Breakouts

## CircuitPython Setup

# CircuitPython Installation of DisplayIO SSD1306 Library
Warning: 

To use the SSD1306 OLED with your&nbsp;Adafruit CircuitPython&nbsp;board you'll need to install the&nbsp;[Adafruit CircuitPython DisplayIO SSD1306](https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306)&nbsp;module on your board.

First make sure you are running the&nbsp;[latest version 5.0 or later of Adafruit CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython)&nbsp;for your board.

Warning: 

Next you'll need to install the necessary libraries&nbsp;to use the hardware--carefully follow the steps to find and install these libraries from&nbsp;[Adafruit's CircuitPython library bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases).&nbsp; Our CircuitPython starter guide has [a great page on how to install the library bundle](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries).

If you choose, you can manually install the libraries individually on your board:

- **adafruit\_displayio\_ssd1306**
- **adafruit\_bus\_device**

Before continuing make sure your board's lib folder or root filesystem has the **adafruit\_displayio\_ssd1306****.mpy and&nbsp; ****adafruit\_bus\_device**** &nbsp; **files and folders** &nbsp;**copied over.

Next[&nbsp;connect to the board's serial REPL](https://learn.adafruit.com/welcome-to-circuitpython/the-repl) so you are at the CircuitPython&nbsp; **\>\>\>** &nbsp;prompt.

## Code Example Additional Libraries

For the Code Example, you will need an additional library. We decided to make use of a library so the code didn't get overly complicated.

[Adafruit_CircuitPython_Display_Text](https://github.com/adafruit/Adafruit_CircuitPython_Display_Text/releases)
Go ahead and install this in the same manner as the driver library by copying the&nbsp; **adafruit\_display\_text** folder over to the **lib** folder on your CircuitPython device.

# Monochrome OLED Breakouts

## CircuitPython Usage

Warning: 

It's easy to use OLEDs with Python and the [Adafruit CircuitPython DisplayIO SSD1306](https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306) module.&nbsp; This module allows you to easily write Python code to control the display.

To demonstrate the usage, we'll initialize the library and use Python code to control the OLED from the board's Python REPL.

# I2C Initialization

If your display is connected to the board using I2C (like if using a Feather and the FeatherWing OLED) you'll first need to initialize the I2C bus. &nbsp;First import the necessary modules:

```
import board
```

Now for either board run this command to create the I2C instance using the default SCL and SDA pins (which will be marked on the boards pins if using a Feather or similar Adafruit board):

```
i2c = board.I2C()
```

After initializing the I2C interface for your firmware as described above, you can create an instance&nbsp;of the `I2CDisplayBus`:

```auto
import displayio
import i2cdisplaybus
import adafruit_displayio_ssd1306

# Release any previously allocated resources
displayio.release_displays()

display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3c)
```

Finally, you can pass the `display_bus` in and create an instance&nbsp;of the SSD1306 I2C driver by running:

```auto
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32)
```

Now you should be seeing an image of the REPL. Note that the last two parameters to the&nbsp;`SSD1306`&nbsp;class initializer are the&nbsp; **width** &nbsp;and&nbsp; **height** &nbsp;of the display in pixels. &nbsp;Be sure to use the right values for the display you're using!

## 128 x 64 size OLEDs (or changing the I2C address)

If you are using a 128x64 display, the I2C address&nbsp;is probably&nbsp;different (`0x3d`), unless you've changed it by soldering some jumpers:

```auto
display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3d)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
```

## Adding hardware reset pin

If you have a `reset` pin (which may be required if your OLED does not have an auto-reset chip like the FeatherWing) also pass in a reset pin like so:

```auto
display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3c, reset=board.D9)
```

At this point the I2C bus and display are initialized. **Skip down to the example code section.**

# SPI Initialization

If your display is connected to the board using SPI you'll first need to initialize the SPI bus.&nbsp;

If you're using a microcontroller board, run the following commands:

```auto
import board
import displayio
import fourwire
import adafruit_displayio_ssd1306

# Release any previously allocated resources
displayio.release_displays()

spi = board.SPI()
tft_cs = board.D5
tft_dc = board.D6
tft_reset = board.D9

display_bus = fourwire.FourWire(spi, command=tft_dc, chip_select=tft_cs,
                                 reset=tft_reset, baudrate=1000000)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
```

The parameters to the FourWire initializer are the pins connected to the display's&nbsp; **DC** ,&nbsp; **CS,** and **reset**. Because we are using keyword arguments, they can be in any position.&nbsp; Again make sure to use the right pin names as you have wired up to your board!

Note that the last two parameters to the&nbsp;`SSD1306`&nbsp;class initializer are the&nbsp; **width** &nbsp;and&nbsp; **height** &nbsp;of the display in pixels. Be sure to use the right values for the display you're using!

# Example Code
https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306/blob/main/examples/displayio_ssd1306_simpletest.py

Let's take a look at the sections of code one by one.&nbsp;We start by importing the `board` so that we can initialize&nbsp;SPI,&nbsp;`displayio`,(`FourWire` or `I2CDisplayBus` depending on your display),`terminalio` for the font, a `label`, and the&nbsp;`adafruit_displayio_ssd1306`&nbsp;driver.

```auto
import board
import displayio

# from fourwire import FourWire
import terminalio
from adafruit_display_text import label
from i2cdisplaybus import I2CDisplayBus

import adafruit_displayio_ssd1306
```

Next we release any previously used displays. This is important because if the microprocessor is reset, the display pins are not automatically released and this makes them available for use again.

```
displayio.release_displays()
```

Next we define the reset line, which will be used for either SPI or I2C.

```
oled_reset = board.D9

```

If you're using I2C, you would use this section of code.&nbsp;We set the I2C object to the board's I2C with the easy shortcut function&nbsp;`board.I2C()`. By using this function, it finds the SPI module and initializes using the default SPI parameters.&nbsp;We also set the display bus to `I2CDisplay` which makes use of the I2C bus.

```auto
# Use for I2C
i2c = board.I2C()
display_bus = I2CDisplayBus(i2c, device_address=0x3c, reset=oled_reset)
```

If you're using SPI, you would use this section of code. Don't forget to update the import section accordingly. We set the SPI object to the board's SPI with the easy shortcut function `board.SPI()`. By using this function, it finds the SPI module and initializes using the default SPI parameters. We set the OLED's&nbsp; **CS** (Chip Select), and&nbsp; **DC** (Data/Command)&nbsp;pins.&nbsp;We also set the display bus to FourWire which makes use of the SPI bus. The SSD1306 needs to be slowed down to 1MHz, so we pass in the additional baudrate parameter.

```auto
spi = board.SPI()
oled_cs = board.D5
oled_dc = board.D6
display_bus = FourWire(spi, command=oled_dc, chip_select=oled_cs,
                                 reset=oled_reset, baudrate=1000000)
```

In order to make it easy to change display sizes, we'll define a few variables in one spot here. We have the display width, the display height and the border size, which we will explain a little further below. If your display is something different than these numbers, change them to the correct setting.

```
WIDTH = 128
HEIGHT = 32     # Change to 64 if needed
BORDER = 5
```

Finally, we initialize the driver with a width of the **WIDTH** variable and a height of the **HEIGHT** variable. If we stopped at this point and ran the code, we would have a terminal that we could type at and have the screen update.

```
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT)

```

![](https://cdn-learn.adafruit.com/assets/assets/000/081/203/medium800/adafruit_products_repl.jpeg?1569015565)

Next we create a background splash image. We do this by creating a group that we can add elements to and adding that group to the display. In this example, we are limiting the maximum number of elements to 10, but this can be increased if you would like. The display will automatically handle updating the group.

```auto
splash = displayio.Group()
display.root_group = splash
```

Next we create a Bitmap that is the full width and height of the display. The Bitmap is like a canvas that we can draw on. In this case we are creating the Bitmap to be the same size as the screen, but only have one color. Although the Bitmaps can handle up to 256 different colors, the display is monochrome so we only need one. We create a Palette with one color and set that color to `0xFFFFFF` which happens to be white. If were to place a different color here, `displayio` handles color conversion automatically, so it may end up black or white depending on the calculation.

```
color_bitmap = displayio.Bitmap(WIDTH, HEIGHT, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF # White
```

With all those pieces in place, we create a TileGrid by passing the bitmap and palette and draw it at&nbsp;`(0, 0)`&nbsp;which represents the display's upper left.

```
bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0, y=0)
splash.append(bg_sprite)
```

![](https://cdn-learn.adafruit.com/assets/assets/000/081/205/medium800/adafruit_products_white_box.jpeg?1569016237)

Next we will create a smaller black rectangle. The easiest way to do this is to create a new bitmap that is a little smaller than the full screen with a single color of `0x000000`, which is **black** , and place it in a specific location. In this case, we will create a bitmap that is 5 pixels smaller on each side. This is where the **BORDER** variable comes into use. It makes calculating the size of the second rectangle much easier. The screen we're using here is **128x64** and we have the BORDER set to **5&nbsp;** , so we'll want to subtract 10 from each of those numbers.

We'll also want to place it at the position&nbsp;`(5, 5)` so that it ends up centered.

```
# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(WIDTH-BORDER*2, HEIGHT-BORDER*2, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000 # Black
inner_sprite = displayio.TileGrid(inner_bitmap,
                                  pixel_shader=inner_palette,
                                  x=BORDER, y=BORDER)
splash.append(inner_sprite)
```

Since we are adding this after the first square, it's automatically drawn on top. Here's what it looks like now.

![](https://cdn-learn.adafruit.com/assets/assets/000/081/209/medium800/adafruit_products_black_box.jpeg?1569016337)

Next add a label that says "Hello World!" on top of that. We're going to use the built-in Terminal Font. In this example, we won't be doing any scaling because of the small resolution, so we'll add the label directly the main group. If we were scaling, we would have used a subgroup.

Labels are centered vertically, so we'll place it at half the HEIGHT for the Y coordinate and subtract one so it looks good. We use the `//` operator to divide because we want a whole number returned and it's an easy way to round it. We'll set the width to around 28 pixels make it appear to be centered horizontally, but if you want to change the text, change this to whatever looks good to you. Let's go with some white text, so we'll pass it a value of `0xFFFFFF`.

```
# Draw a label
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF, x=28, y=HEIGHT//2-1)
splash.append(text_area)
```

Finally, we place an infinite loop at the end so that the graphics screen remains in place and isn't replaced by a terminal.

```
while True:
    pass
```

![](https://cdn-learn.adafruit.com/assets/assets/000/081/214/medium800/adafruit_products_hello_world.jpeg?1569016522)

If you've been following along with a FeatherWing or 128x32 OLED, this is what it should look like:

![](https://cdn-learn.adafruit.com/assets/assets/000/081/283/medium800/adafruit_products_featherwing.jpeg?1569109843)

## Where to go from here

Be sure to check out this excellent&nbsp;[guide to CircuitPython Display Support Using displayio](https://learn.adafruit.com/circuitpython-display-support-using-displayio)

# Monochrome OLED Breakouts

## Python Wiring

It's easy to use OLEDs with Python and the [Adafruit CircuitPython SSD1306](https://github.com/adafruit/Adafruit_CircuitPython_SSD1306) module.&nbsp; This module allows you to easily write Python code to control the display.

We'll cover how to wire the OLED to your Raspberry Pi. First assemble your OLED.

Since there's _dozens_ of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, [please visit the guide for CircuitPython on Linux to see whether your platform is supported](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux).&nbsp;

Connect the OLED as shown below to your Raspberry Pi.

## Adafruit PIOLED
- **The PiOLED comes fully assembled. Simply plug into any Raspberry Pi as shown.**

![adafruit_products_raspi_pi_oled_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/735/medium640/adafruit_products_raspi_pi_oled_bb.jpg?1546730389)

## Adafruit 128x64 OLED Bonnet for Raspberry Pi
- **The OLED Bonnet comes fully assembled. Simply plug into the Raspberry Pi as shown.**

![adafruit_products_raspi0_oled_bonnet_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/736/medium640/adafruit_products_raspi0_oled_bonnet_bb.jpg?1546730556)

## Adafruit 128x32 I2C OLED Display
- **Pi 3.3V** to **OLED VIN**
- **Pi GND** to **OLED GND**
- **Pi SCL** to **OLED SCL**
- **Pi SDA** to **OLED SDA**
- **Pi GPIO4** to **OLED RST** (or any available GPIO pin)

![adafruit_products_raspi_128_32_i2c_oled_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/728/medium640/adafruit_products_raspi_128_32_i2c_oled_bb.jpg?1546722187)

## Adafruit 0.96" 128x64 OLED Display STEMMA QT Version - I2C Wiring
 **You do not need to alter the jumpers on the back - I2C is the default configuration on this display!**

- **Pi 3.3V** to **OLED Vin (red wire)**  
- **Pi GND** to **OLED Gnd (black wire)**  
- **Pi SCL** to **OLED Clk (yellow wire)**  
- **Pi SDA** to **OLED Data (blue wire)**  

Note: Connecting the OLED RST is not necessary as this revision added auto-reset circuitry so the RESET pin is not required.

![adafruit_products_128x64_STEMMA_Wiring_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/131/334/medium640/adafruit_products_128x64_STEMMA_Wiring_bb.png?1721258587)

## Adafruit 0.96" or 1.3" 128x64 OLED Display Original Version - I2C Wiring
 **You must solder two jumpers closed on the back of the display to use with I2C!**

&nbsp;

- **Pi 3.3V** to **OLED Vin**
- **Pi GND** to **OLED Gnd**
- **Pi SCL** to **OLED Clk**  
- **Pi SDA** to **OLED Data**  
- **Pi GPIO4** to **OLED Rst** (or any available GPIO pin)

![adafruit_products_raspi_128_64_i2c_oled_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/744/medium640/adafruit_products_raspi_128_64_i2c_oled_bb.jpg?1546733722)

![adafruit_products_OLED_jumper_I2C.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/745/medium640/adafruit_products_OLED_jumper_I2C.jpg?1546733818)

![adafruit_products_raspi_1_3_inch_128_64_i2c_oled_bb.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/752/medium640/adafruit_products_raspi_1_3_inch_128_64_i2c_oled_bb.jpg?1546737342)

![adafruit_products_1-3inch_128x64_oled_back.jpg](https://cdn-learn.adafruit.com/assets/assets/000/068/753/medium640/adafruit_products_1-3inch_128x64_oled_back.jpg?1546737364)

## Adafruit 128x32 SPI OLED Display
- **Pi 3.3V** to **OLED VIN**
- **Pi GND** to **OLED GND**
- **Pi MOSI&nbsp;** to **OLED DATA**
- **Pi SCLK&nbsp;** to **OLED CLK**
- **Pi GPIO4** to **OLED RST** (or any available GPIO pin)
- **Pi GPIO5&nbsp;** to **OLED CS&nbsp;** (or any available GPIO pin)
- **Pi GPIO6** to **OLED DC&nbsp;** (or any available GPIO pin)

![adafruit_products_rpi_spi_128x32_oled.png](https://cdn-learn.adafruit.com/assets/assets/000/081/400/medium640/adafruit_products_rpi_spi_128x32_oled.png?1569376747)

## Adafruit 0.96" or 1.3" 128x64 OLED Display - SPI Wiring
- **Pi 3.3V** to **OLED VIN**
- **Pi GND** to **OLED GND**
- **Pi MOSI&nbsp;** to **OLED DATA**
- **Pi SCLK&nbsp;** to **OLED CLK**
- **Pi GPIO4** to **OLED RST** (or any available GPIO pin)
- **Pi GPIO5&nbsp;** to **OLED CS&nbsp;** (or any available GPIO pin)
- **Pi GPIO6** to **OLED DC&nbsp;** (or any available GPIO pin)

![adafruit_products_rpi_spi_128x64_oled.png](https://cdn-learn.adafruit.com/assets/assets/000/081/401/medium640/adafruit_products_rpi_spi_128x64_oled.png?1569376764)

# Monochrome OLED Breakouts

## Python Setup

You'll need to install the Adafruit\_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. [Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux)!

## Python Installation of SSD1306 Library

Once that's done, from your command line run the following command:

```terminal
pip3 install adafruit-circuitpython-ssd1306
```

If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!

If that complains about pip3 not being installed, then run this first to install it:

```terminal
sudo apt-get install python3-pip
```

## Pillow Library

We also need PIL, the Python Imaging Library, to allow using text with custom fonts. There are several system libraries that PIL relies on, so installing via a package manager is the easiest way to bring in everything:

```terminal
sudo apt-get install python3-pil
```

## NumPy Library

NumPy is needed for the **circuitpython\_typing** library. This can be installed with the following command:

```terminal
sudo apt-get install python3-numpy
```

That's it. You should be ready to go.

## Speeding up the Display on Raspberry Pi

For the best performance, especially if you are doing fast animations, you'll want to tweak the I2C core to run at 1MHz. By default it may be 100KHz or 400KHz

To do this edit the config with `sudo nano /boot/firmware/config.txt`

and add to the end of the file

`dtparam=i2c_baudrate=1000000`

![](https://cdn-learn.adafruit.com/assets/assets/000/081/485/medium800/adafruit_products_i2c_baud.png?1569529303)

reboot to 'set' the change.

# Monochrome OLED Breakouts

## Python Usage

It's easy to use OLEDs with Python and the [Adafruit CircuitPython SSD1306](https://github.com/adafruit/Adafruit_CircuitPython_SSD1306) module.&nbsp; This module allows you to easily write Python code to control the display.

You can use this sensor with any computer that has GPIO and Python [thanks to Adafruit\_Blinka, our CircuitPython-for-Python compatibility library](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux).

To demonstrate the usage, we'll initialize the library and use Python code to control the OLED from the board's Python REPL.

Since we are running full CPython on our Linux/computer, we can take advantage of the powerful Pillow image drawing library to handle text, shapes, graphics, etc. [Pillow is a gold standard in image and graphics handling, you can read about all it can do here](https://pillow.readthedocs.io/en/stable/).

# I2C Initialization

If your display is connected to the board using I2C (like if using a PiOLED or Bonnet) you'll first need to initialize the I2C bus. &nbsp;First import the necessary modules:

```
import board
import busio
```

Now for either board run this command to create the I2C instance using the default SCL and SDA pins of your I2C host:

```
i2c = busio.I2C(board.SCL, board.SDA)
```

After initializing the I2C interface for your firmware as described above you can create an instance&nbsp;of the SSD1306 I2C driver by running:

```
import adafruit_ssd1306
oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
```

Note that the first two parameters to the `SSD1306_I2C` class initializer are the&nbsp; **width** &nbsp;and&nbsp; **height** &nbsp;of the display in pixels. &nbsp;Be sure to use the right values for the display you're using!

## 128 x 64 size OLEDs (or changing the I2C address)

If you are using a 128x64 display, the I2C address&nbsp;is probably&nbsp;different (`0x3d`), unless you've changed it by soldering some jumpers:

```
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d)
```

## Adding hardware reset pin

If you have a reset pin (which may be required if your OLED does not have an auto-reset chip like the FeatherWing) also pass in a reset pin like so:

```
import digitalio

reset_pin = digitalio.DigitalInOut(board.D4) # any pin!
oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, reset=reset_pin)
```

At this point the I2C bus and display are initialized. **Skip down to the example code section.**

# SPI Initialization

If your display is connected to the board using SPI you'll first need to initialize the SPI bus:

```
import adafruit_ssd1306
import board
import busio
import digitalio

spi = busio.SPI(board.SCK, MOSI=board.MOSI)
reset_pin = digitalio.DigitalInOut(board.D4) # any pin!
cs_pin = digitalio.DigitalInOut(board.D5)    # any pin!
dc_pin = digitalio.DigitalInOut(board.D6)    # any pin!

oled = adafruit_ssd1306.SSD1306_SPI(128, 32, spi, dc_pin, reset_pin, cs_pin)
```

Note the first two parameters to the `SSD1306_SPI` class initializer are the&nbsp; **width** &nbsp;and&nbsp; **height** &nbsp;of the display in pixels. &nbsp;Be sure to use the right values for the display you're using!

The next parameters to the initializer are the pins connected to the display's&nbsp; **DC** ,&nbsp; **reset** , and&nbsp; **CS** &nbsp;lines in that order. &nbsp;Again make sure to use the right pin names as you have wired up to your board!

# Example Code
https://github.com/adafruit/Adafruit_CircuitPython_SSD1306/blob/main/examples/ssd1306_pillow_demo.py

Let's take a look at the sections of code one by one.&nbsp;We start by importing the `board` so that we can initialize&nbsp;SPI,&nbsp;`digitalio`, several&nbsp;`PIL`&nbsp;modules for Image Drawing, and the&nbsp;`adafruit_ssd1306`&nbsp;driver.

```
import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
```

Next we define the reset line, which will be used for either SPI or I2C. If your OLED has auto-reset circuitry, you can set the `oled_reset` line to **None**

```
oled_reset = digitalio.DigitalInOut(board.D4)
```

In order to make it easy to change display sizes, we'll define a few variables in one spot here. We have the display width, the display height and the border size, which we will explain a little further below. If your display is something different than these numbers, change them to the correct setting.

```
WIDTH = 128
HEIGHT = 32     # Change to 64 if needed
BORDER = 5
```

If you're using I2C, you would use this section of code.&nbsp;We set the I2C object to the board's I2C with the easy shortcut function&nbsp;`board.I2C()`. By using this function, it finds the I2C module and initializes using the default I2C parameters. We also set up the oled with SSD1306\_I2C which makes use of the I2C bus.

```
# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3c, reset=oled_reset)
```

If you're using SPI, you would use this section of code. We set the SPI object to the board's SPI with the easy shortcut function&nbsp;`board.SPI()`. By using this function, it finds the SPI module and initializes using the default SPI parameters. We set the OLED's&nbsp; **CS** (Chip Select), and&nbsp; **DC** (Data/Command)&nbsp;pins.&nbsp;We also set up the OLED with SSD1306\_SPI which makes use of the SPI bus.

```
# Use for SPI
spi = board.SPI()
oled_cs = digitalio.DigitalInOut(board.D5)
oled_dc = digitalio.DigitalInOut(board.D6)
oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs)
```

Next we clear the display in case it was initialized with any random artifact data.

```
# Clear display.
oled.fill(0)
oled.show()
```

Next, we need to initialize PIL to create a blank image to draw on. Think of it as a virtual canvas. Since this is a monochrome display, we set it up for 1-bit color, meaning a pixel is either white or black. We can make use of the OLED's width and height properties as well. Optionally, we could have used our **WIDTH** and **HEIGHT** variables.

```
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new('1', (oled.width, oled.height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

```

Now we start the actual drawing. Here we are telling it we want to draw a rectangle from `(0,0)`, which is the upper left, to the full width and height of the display. We want it both filled in and having an outline of white, so we pass 255 for both numbers.

```
# Draw a white background
draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255)
```

If we ran the code now, it would still show a blank display because we haven't told python to use our virtual canvas yet. You can skip to the end if you would like to see how to do that.&nbsp;This is what our canvas currently looks like in memory.

![](https://cdn-learn.adafruit.com/assets/assets/000/081/416/medium800/adafruit_products_PIL_white_box.jpeg?1569432344)

Next we will create a smaller black rectangle. The easiest way to do this is to draw another rectangle a little smaller than the full screen with no fill or outline&nbsp;and place it in a specific location. In this case, we will create a rectangle that is 5 pixels smaller on each side. This is where the **BORDER** variable comes into use. It makes calculating the size of the second rectangle much easier. We want the starting coordinate, which consists of the first two parameters, to be our BORDER value. Then for the next two parameters, which are our ending coordinates, we want to subtract our border value from the width and height. Also, because this is a zero-based coordinate system, we also need to subtract 1 from each number.

```
# Draw a smaller inner rectangle
draw.rectangle((BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1),
               outline=0, fill=0)
```

Here's what our virtual canvas looks like in memory.

![](https://cdn-learn.adafruit.com/assets/assets/000/081/417/medium800/adafruit_products_PIL_black_box.jpeg?1569432353)

Now drawing text with PIL is pretty straightforward. First we start by setting the font to the default system text. After that we define our text and get the size of the text. We're grabbing the size that it would render at so that we can calculate the center position. Finally, we take the font size and screen size to calculate the position we want to draw the text at and it appears in the center of the screen.

```
# Load default font.
font = ImageFont.load_default()

# Draw Some Text
text = "Hello World!"
(font_width, font_height) = font.getsize(text)
draw.text((oled.width//2 - font_width//2, oled.height//2 - font_height//2),
          text, font=font, fill=255)

```

Finally, we need to display our virtual canvas to the OLED and we do that with 2 commands. First we set the image to the screen, then we tell it to show the image.

```
# Display image
oled.image(image)
oled.show()
```

Warning: 

Here's what the final output should look like.

![](https://cdn-learn.adafruit.com/assets/assets/000/081/421/medium800/adafruit_products_PIL_hello_world.jpeg?1569433250)

# Monochrome OLED Breakouts

## Troubleshooting

### 

The OLED driver circuit needs a small amount of time to be ready after initial power. If your code tries to write to the display too soon, it may not be ready. It will work on reset since that typically does not cycle power. If you are having this issue, try adding a small amount of delay before trying to write to the OLED.

In Arduino, use **delay()** to add a few milliseconds before calling **oled.begin()**. Adjust the amount of delay as needed to see how little you can get away with for your specific setup.

### 

The display can have image burn in for any pixels left on over a long period of time - many days. Try to avoid having the display on constantly for that length of time.

# Monochrome OLED Breakouts

## Downloads

# Software

**[You can download our SSD1306 OLED display Arduino library from github](https://github.com/adafruit/Adafruit_SSD1306)&nbsp;**which comes with example code. The library can print text, bitmaps, pixels, rectangles, circles and lines. It uses 1K of RAM since it needs to buffer the entire display but its very fast! The code is simple to adapt to any other microcontroller. You'll also have to install the&nbsp;[Adafruit GFX graphics core library at this github repo](https://github.com/adafruit/Adafruit-GFX-Library)&nbsp;and install it after you've gotten the OLED driver library.

You can check out a simulator for these OLEDs at [https://wokwi.com/arduino/libraries/Adafruit\_SSD1306](https://wokwi.com/arduino/libraries/Adafruit_SSD1306)

# Datasheets

- [UG-2864HSWEG01](http://www.adafruit.com/datasheets/UG-2864HSWEG01.pdf)&nbsp;Datasheet
- [UG-2832HSWEG02](https://cdn-shop.adafruit.com/datasheets/UG-2832HSWEG02.pdf) Datasheet
- [UG-2864HSWEG01](http://www.adafruit.com/datasheets/UG-2864HSWEG01%20user%20guide.pdf)&nbsp;User Guide
- [UG-2832HSWEG04](https://cdn-shop.adafruit.com/datasheets/UG-2832HSWEG04.pdf) Datasheet
- [UG-2864KSWLG01](https://cdn-learn.adafruit.com/assets/assets/000/100/779/original/2011241005_UG-Univision-Semicon-UG-2864KSWLG01_C113322.pdf?1616084674) Datasheet
- [SSD1306](http://www.adafruit.com/datasheets/SSD1306.pdf)&nbsp;Datasheet

# Files

- [EagleCAD PCB files for 128x32 0.91" SPI display&nbsp;PCB](https://github.com/adafruit/Adafruit-128x32-SPI-OLED-breakout-board-PCB "Link: https://github.com/adafruit/Adafruit-128x32-SPI-OLED-breakout-board-PCB")
- [EagleCAD PCB files for 128x32 0.91" I2C display on GitHub](https://github.com/adafruit/Adafruit-128x32-I2C-OLED-Breakout-PCB)
- [EagleCAD PCB files for 128x64 0.96" display on GitHub](https://github.com/adafruit/Adafruit-128x64-Monochrome-OLED-PCB "Link: https://github.com/adafruit/Adafruit-128x64-Monochrome-OLED-PCB")
- [EagleCAD PCB files for 128x64 1.3" display on GitHub](https://github.com/adafruit/Adafruit-1.3inch-128x64-Mono-OLED-PCB)
- [Fritzing objects available in the Adafruit Fritzing Library](https://github.com/adafruit/Fritzing-Library)

# Schematic & Fabrication Print for 0.96" OLED - STEMMA QT version
![](https://cdn-learn.adafruit.com/assets/assets/000/093/884/medium800/adafruit_products_0-96in_OLED_sch.png?1596746114)

![](https://cdn-learn.adafruit.com/assets/assets/000/093/885/medium800/adafruit_products_0-96in_OLED_fab_print.png?1596746128)

# Schematic & Fabrication Print for 0.96" OLED - Original version
![](https://cdn-learn.adafruit.com/assets/assets/000/036/493/medium800/lcds___displays_schem.png?1476374564)

![](https://cdn-learn.adafruit.com/assets/assets/000/036/494/medium800/lcds___displays_fabprint.png?1476374574)

# Schematic & Fabrication Print for 1.3" OLED
![](https://cdn-learn.adafruit.com/assets/assets/000/036/258/medium800/lcds___displays_schem.png?1475774124)

![](https://cdn-learn.adafruit.com/assets/assets/000/036/259/medium800/lcds___displays_fabprint.png?1475774133)

# Schematic & Fabrication Print for 1.3" OLED STEMMA QT

**As of Nov 20, 2019** we've done a re-design to make the display more plug and play. There is now an auto-reset circuit so that it will reset the display on power up. We've also changed the default protocol to be I2C instead of SPI. **To convert to SPI mode you will need to cut two jumpers (there's a typo on the PCB).** We have also added two STEMMA QT / Qwiic connectors for plug and play usage! The board size, mounting holes and layout has changed slightly to accommodate these changes.

![](https://cdn-learn.adafruit.com/assets/assets/000/087/763/medium800/adafruit_products_1-3_STEMMA_OLED_sch.png?1580240604)

![](https://cdn-learn.adafruit.com/assets/assets/000/087/765/medium800/adafruit_products_1-3_STEMMA_OLED_fab_print.png?1580241586)

# Schematic & Fabrication Print for 0.91" 128x32 I2C
![](https://cdn-learn.adafruit.com/assets/assets/000/036/286/medium800/lcds___displays_schem.png?1476130301)

![](https://cdn-learn.adafruit.com/assets/assets/000/036/287/medium800/lcds___displays_fabprint.png?1476130309)

# Schematic & Fabrication Print for 0.91" 128x32 I2C STEMMA QT

**As of Nov 20, 2019** we've done a re-design to make the display more plug and play. There is now an auto-reset circuit so that it will reset the display on power up. We've also changed the default protocol to be I2C instead of SPI. **To convert to SPI mode you will need to cut two jumpers (there's a typo on the PCB).** We have also added two STEMMA QT / Qwiic connectors for plug and play usage! The board size, mounting holes and layout has changed slightly to accommodate these changes.

![](https://cdn-learn.adafruit.com/assets/assets/000/087/761/medium800/adafruit_products_0-91_STEMMA_OLED_sch.png?1580240102)

![](https://cdn-learn.adafruit.com/assets/assets/000/087/766/medium800/adafruit_products_0-91_STEMMA_OLED_fab_print.png?1580241609)

# Schematic & Fabrication Print for 0.91" 128x32 SPI
![](https://cdn-learn.adafruit.com/assets/assets/000/036/507/medium800/lcds___displays_schem.png?1476387070)

![](https://cdn-learn.adafruit.com/assets/assets/000/036/508/medium800/lcds___displays_fabprint.png?1476387079)


## Featured Products

### Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic

[Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic](https://www.adafruit.com/product/938)
These displays are small, only about 1.3" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x64 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

Out of Stock
[Buy Now](https://www.adafruit.com/product/938)
[Related Guides to the Product](https://learn.adafruit.com/products/938/guides)
### Monochrome 0.96" 128x64 OLED Graphic Display - STEMMA QT

[Monochrome 0.96" 128x64 OLED Graphic Display - STEMMA QT](https://www.adafruit.com/product/326)
These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x64 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

Out of Stock
[Buy Now](https://www.adafruit.com/product/326)
[Related Guides to the Product](https://learn.adafruit.com/products/326/guides)
### Monochrome 128x32 SPI OLED graphic display

[Monochrome 128x32 SPI OLED graphic display](https://www.adafruit.com/product/661)
These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x32 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

In Stock
[Buy Now](https://www.adafruit.com/product/661)
[Related Guides to the Product](https://learn.adafruit.com/products/661/guides)
### Monochrome 128x32 I2C OLED graphic display

[Monochrome 128x32 I2C OLED graphic display](https://www.adafruit.com/product/931)
These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x32 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/931)
[Related Guides to the Product](https://learn.adafruit.com/products/931/guides)
### Monochrome 0.91" 128x32 I2C OLED Display - STEMMA QT / Qwiic

[Monochrome 0.91" 128x32 I2C OLED Display - STEMMA QT / Qwiic](https://www.adafruit.com/product/4440)
These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x32 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

In Stock
[Buy Now](https://www.adafruit.com/product/4440)
[Related Guides to the Product](https://learn.adafruit.com/products/4440/guides)

## Related Guides

- [4x4 Rotary Encoder MIDI Messenger](https://learn.adafruit.com/4x4-rotary-encoder-midi-messenger.md)
- [GPS Dog Collar](https://learn.adafruit.com/gps-dog-collar.md)
- [Monitor Your Greenhouse with a No-Code Environmental Sensor](https://learn.adafruit.com/monitor-your-greenhouse-with-a-no-code-environmental-sensor.md)
- [MIDI for Makers](https://learn.adafruit.com/midi-for-makers.md)
- [MIDI Melody Maker](https://learn.adafruit.com/midi-melody-maker.md)
- [Adafruit FT232H With SPI & I2C Devices](https://learn.adafruit.com/adafruit-ft232h-with-spi-and-i2c-libraries.md)
- [CircuitPython OLED and Dual Knob Sketcher](https://learn.adafruit.com/circuitpython-oled-knob-sketcher.md)
- [USB MIDI Keyset Controller](https://learn.adafruit.com/midi-keyset.md)
- [Pico W HTTP Server with CircuitPython](https://learn.adafruit.com/pico-w-http-server-with-circuitpython.md)
- [Faderwave Synthesizer](https://learn.adafruit.com/faderwave-synthesizer.md)
- [Gravity Falls Memory Gun](https://learn.adafruit.com/gravity-falls-memory-gun.md)
- [CircuitPython Powered Sip & Puff with ST LPS33HW Pressure Sensor](https://learn.adafruit.com/st-lps33-and-circuitpython-sip-and-puff.md)
- [Toddler Timer](https://learn.adafruit.com/toddler-timer.md)
- [Stepper Motor Turntable](https://learn.adafruit.com/stepper-motor-turntable.md)
- [Generating Text with ChatGPT, Pico W & CircuitPython](https://learn.adafruit.com/generating-text-with-chatgpt-pico-w-circuitpython.md)
