Overview

A Feather board without ambition is a Feather board without FeatherWings! This is the FeatherWing OLED: it adds a 128x32 monochrome OLED plus 3 user buttons to any Feather main board. Using our Feather Stacking Headers or Feather Female Headers you can connect a FeatherWing on top of your Feather board and let the board take flight!

These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. This screen is made of 128x32 individual white OLED pixels and 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! We also toss on a reset button and three mini tactile buttons called A B and C so you can add a mini user interface to your feather.

Tested works with all of our Feather boards. The OLED uses only the two I2C pins on the Feather, and you can pretty much stack it with any other FeatherWing, even ones that use I2C since that is a shared bus.

Pinouts

The OLED FeatherWing plugs into any Feather and adds a cute little display. To make it as cross-platform compatible as possible, we use only I2C to control the display. This is not as fast as SPI but it uses only two pins, can share the I2C bus and is fine for the small 128x32 pixel OLED.

Power Pins

OLED displays do not have a backlight, and are fairly low power, this display will draw about 10mA when in use. The display uses 3V power and logic so we just connect to the 3V and GND pins from the feather, as indicated above.

I2C Data Pins

The cute little OLED does all of the data transfer over the I2C pins, highlighed above SDA and SCL. No other pins are required. There are two 2.2K pullups to 3V on each.

These pins can be shared with other I2C devices.

The I2C address is 0x3C and cannot be changed

Optional Buttons

We had a little bit of space so we added three mini tactile buttons that you can use for user interface. We label them A B and C because each Feather has slightly different pin numbering schemes and we wanted to make it 'universal'

If you're using ATmega328P, Atmega32u4, ATSAMD51 M4 or ATSAMD21 M0 Feather

  • Button A is #9 (note this is also used for the battery voltage divider so if you want to use both make sure you disable the pullup when you analog read, then turn on the pullup for button reads)
  • Button B is #6
  • Button C is #5

If you're using ESP8266:

  • Button A is #0
  • Button B is #16
  • Button C is #2

If you're using WICED/STM32 Feather

  • Button A is #PA15
  • Button B is #PC7
  • Button C is #PC5

Button B has a 100K pullup on it so it will work with the ESP8266 (which does not have an internal pullup available on that pin). You will need to set up a pullup on all other pins for the buttons to work.

Reset Button

Sometimes its nice to be able to restart your program, so we also have a reset button. It is tied to the RST pin marked above.

Assembly

Prepare the header strip:

Cut the strip to length if necessary. It will be easier to solder if you insert it into a breadboard - long pins down

Add the FeatherWing:

Place the featherwing over the pins so that the short pins poke through the two rows of breakout pads

And Solder!

Be sure to solder all pins for reliable electrical contact.

(For tips on soldering, be sure to check out our Guide to Excellent Soldering).

 

Start by soldering the first row of header

Now flip around and solder the other row completely

You're done with the two header strips.

 

Check your solder joints visually and continue onto the next steps

OK You're done! You can now plug your FeatherWing into your Feather and get your OLED on! 

Arduino Code

The OLED display we use is well supported and works for all Feathers, all you need is a little library support and you will be drawing in no time!

Install Arduino Libraries

Using the OLED FeatherWing 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, which you’ll find in the “Sketch” menu: Sketch→Include Library→Manage Libraries…

Enter “ssd1306” in the search field, locate the Adafruit SSD1306 library and select “Install” (or “Upgrade” if you have an older version). Then repeat the same for “gfx” and the Adafruit GFX library.

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

Run Example Code

We have a basic demo that works with all Feathers, so compile/upload this sketch:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

// OLED FeatherWing buttons map to different pins depending on board:
#if defined(ESP8266)
  #define BUTTON_A  0
  #define BUTTON_B 16
  #define BUTTON_C  2
#elif defined(ESP32)
  #define BUTTON_A 15
  #define BUTTON_B 32
  #define BUTTON_C 14
#elif defined(ARDUINO_STM32_FEATHER)
  #define BUTTON_A PA15
  #define BUTTON_B PC7
  #define BUTTON_C PC5
#elif defined(TEENSYDUINO)
  #define BUTTON_A  4
  #define BUTTON_B  3
  #define BUTTON_C  8
#elif defined(ARDUINO_FEATHER52832)
  #define BUTTON_A 31
  #define BUTTON_B 30
  #define BUTTON_C 27
#else // 32u4, M0, M4, nrf52840 and 328p
  #define BUTTON_A  9
  #define BUTTON_B  6
  #define BUTTON_C  5
#endif

void setup() {
  Serial.begin(9600);

  Serial.println("OLED FeatherWing test");
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

  Serial.println("OLED begun");

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  display.display();

  Serial.println("IO test");

  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Connecting to SSID\n'adafruit':");
  display.print("connected!");
  display.println("IP: 10.0.1.23");
  display.println("Sending val #0");
  display.setCursor(0,0);
  display.display(); // actually display all of the above
}

void loop() {
  if(!digitalRead(BUTTON_A)) display.print("A");
  if(!digitalRead(BUTTON_B)) display.print("B");
  if(!digitalRead(BUTTON_C)) display.print("C");
  delay(10);
  yield();
  display.display();
}

You should see the OLED display a splash screen then spit out some text (it’s a make-believe WiFi connection status screen…this doesn’t actually do anything, just showing how typical project might look). If you press the A B or C buttons it will also print those out.

Do more!

You can use any of the Adafruit GFX library commands to draw onto your OLED, that means that you get all sorts of shapes, fonts, lines, etc available. Check out GFX for all the underlying graphics support functions and how they work

Remember you need to call display() after drawing to refresh the screen!

CircuitPython and Python Wiring

It's easy to use OLEDs with CircuitPython and the Adafruit CircuitPython SSD1306 module.  This module allows you to easily write Python code to control the display.

You can use this sensor with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.

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

CircuitPython Microcontroller Wiring

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 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 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 0.96" or 1.3" 128x64 OLED Display - I2C Wiring

You must solder two jumpers closed on the back of the display to use with I2C!

 

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

Adafruit 0.96" or 1.3"  128x64 OLED Display - SPI Wiring

  • 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

Python Wiring

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

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 128x64 OLED Bonnet for Raspberry Pi

  • The OLED Bonnet comes fully assembled. Simply plug into the Raspberry Pi as shown.

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 0.96" or 1.3" 128x64 OLED Display - I2C Wiring

You must solder two jumpers closed on the back of the display to use with I2C!

 

  • 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)

CircuitPython and Python Setup

CircuitPython Installation of SSD1306 Library

To use the SSD1306 OLED with your Adafruit CircuitPython board you'll need to install the Adafruit CircuitPython SSD1306 module on your board.

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  Our CircuitPython starter guide has a great page on how to install the library bundle.

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

  • adafruit_ssd1306
  • adafruit_bus_device
  • adafruit_framebuf

Before continuing make sure your board's lib folder or root filesystem has the adafruit_ssd1306.mpy, adafruit_bus_device and adafruit_framebuf files and folders copied over.

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

Python Installation of SSD1306 Library

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!

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

  • sudo 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!

CircuitPython and Python Usage

It's easy to use OLEDs with CircuitPython and the Adafruit CircuitPython SSD1306 module.  This module allows you to easily write Python code to control the display.

You can use this sensor with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.

To demonstrate the usage, we'll initialise 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.  First import the necessary modules:

Download: file
import board
import busio

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):

Download: file
i2c = busio.I2C(board.SCL, board.SDA)

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

Download: file
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 width and height of the display in pixels.  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 is probably different (0x3d), unless you've changed it by soldering some jumpers:

Download: file
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:

Download: file
import digitalio

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

If you're using a Raspberry Pi, run the following commands:

Download: file
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 drawing section.

SPI Initialization

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

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

Download: file
import adafruit_ssd1306
import board
import busio
import digitalio

spi = busio.SPI(board.SCK, MOSI=board.MOSI)
dc_pin = digitalio.DigitalInOut(board.D6)    # any pin!
reset_pin = digitalio.DigitalInOut(board.D9) # any pin!
cs_pin = digitalio.DigitalInOut(board.D5)    # 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 width and height of the display in pixels.  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 DCreset, and CS lines in that order.  Again make sure to use the right pin names as you have wired up to your board!

Drawing

The SSD1306 module currently supports a basic set of commands to draw on the display.  You can set individual pixels, fill the screen, and write lines of text. 

To fill or clear the entire screen use the fill function.  This function takes a parameter which specifies the color to fill with, either 0 for black or 1 for white.  For example to fill the screen white:

Download: file
oled.fill(1)
oled.show()

Notice the fill function doesn't actually change the display.  You must call show after making drawing commands to send the updated pixel data to the display!

To clear the screen to black just call fill again but with the color 0:

Download: file
oled.fill(0)
oled.show()

To set a pixel use the pixel function.  This function takes the following parameters:

  • Pixel X position
  • Pixel Y position
  • Pixel color (0 = black, 1 = white)

For example to set the first pixel white:

Download: file
oled.pixel(0, 0, 1)
oled.show()

Try setting other pixels white by changing the X and Y position.  Remember you have to call show after setting pixels to see them appear!

Text

To write text to your display, you must download a font file and copy it to your CIRCUITPY drive. Click the button below to download the file, and then copy font5x8.bin to your CIRCUITPY drive.

You can write a line of text with the text function.  This function takes the following parameters:

  • String of text
  • Text X position
  • Text Y position
  • Text color (0 = black, 1 = white)

For example to clear the screen and then write two lines of text:

Download: file
oled.fill(0)
oled.text('Hello', 0, 0, 1)
oled.text('World', 0, 10, 1)
oled.show()

Notice the second line of text starts at Y position 10, this moves it down the display 10 pixels so it's below the first line of text.  The font used by the text function is 8 pixels tall so a size of 10 gives a bit of room between the lines.

Invert

Finally you can invert the display colors with the invert function:

Download: file
oled.invert(True)

Note that the invert function doesn't need to have show called after it to see the change.

To go back to a non-inverted display run:

Download: file
oled.invert(False)

That's all there is to drawing on the SSD1306 OLED display with CircuitPython!  The drawing functions are basic but provide building blocks for more advanced usage.  For example you can display text with sensor readings or other state, or even program a simple game like pong!

Full Example Code

# Basic example of clearing and drawing pixels on a SSD1306 OLED display.
# This example and library is meant to work with Adafruit CircuitPython API.
# Author: Tony DiCola
# License: Public Domain

# Import all board pins.
from board import SCL, SDA
import busio

# Import the SSD1306 module.
import adafruit_ssd1306


# Create the I2C interface.
i2c = busio.I2C(SCL, SDA)

# Create the SSD1306 OLED class.
# The first two parameters are the pixel width and pixel height.  Change these
# to the right size for your display!
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
# Alternatively you can change the I2C address of the device with an addr parameter:
#display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x31)

# Clear the display.  Always call show after changing pixels to make the display
# update visible!
display.fill(0)
display.show()

# Set a pixel in the origin 0,0 position.
display.pixel(0, 0, 1)
# Set a pixel in the middle 64, 16 position.
display.pixel(64, 16, 1)
# Set a pixel in the opposite 127, 31 position.
display.pixel(127, 31, 1)
display.show()

Troubleshooting

Display does not work on initial power but does work after a reset.

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.

Download

This guide was first published on Apr 26, 2016. It was last updated on Apr 26, 2016.