Introduction: Graphics on a SSD1306 I2C OLED 128x64 Display With CircuitPython Using an Itsybitsy M4 Express

About: Retired teacher of computing - started 1967 with FORTRAN IV. I now play with development boards such as Raspberry Pi, Pico, Arduino, micro:bit and Adafruit CircuitPython boards like the Insybitsy M4 and Circui…

The SSD1306 OLED display is a small (0.96"), inexpensive, widely available, I2C, monochrome graphical display with 128x64 pixels, which is easily interfaced (only 4 wires) to microprocessor development boards such as a Raspberry Pi, Arduino or Adafruit Itsybitsy M4 Express, CircuitPlayground Express or other CircuitPython devices. Drivers can be downloaded from the internet.

Graphical routines for Arduinos have been available for some time but not for other development systems.

The basic device drivers allow users to :

  • Clear the screen to black or white. oled.fill(c)
  • Write a text string to the screen at a specified (x, y) position oled.text("Text", x, y, c)
  • Draw a dot at a specified (x, y) position oled.pixel(x, y, c)
  • Load a picture file to the screen. (Not used in this project)
  • Update the display

This Instructable will demonstrate, with simple procedures, how to draw, interactively:

  • lines
  • circles
  • hollow boxes
  • solid blocks
  • pre-defined characters

I will be using an Adafruit Itsybitsy M4 Express to demonstrate the methods but the code, in Python, can easily be ported to other development systems.

I chose the Itsybitsy M4 for this demonstration because it is inexpensive, powerful, easy to program, includes analogue and digital Input/Output, has plenty of memory, has easily located documentation and help forums on the Internet, is very easy to set up initially and supports CircuitPython, a version of Python ideal for those new to coding.

Once you have set up your Itsybitsy and SSD1306 this is a very simple breadboard build. There is no typing, all the files can be downloaded.

This is an inexpensive and easy project to build but introduces some intermediate/advanced ideas. I hope you will give it a try. I was impressed with this little display.

Step 1: What We Need for This Project


  • SSD1306 I2C mono display 128x64 pixels
  • Itsybitsy M4 Express
  • microUSB to USB cable - to program the board
  • Breadboard
  • 1 10K Ohm potentiometer
  • 1 button switch
  • connecting wire - various colours can help
  • Computer (to write the code and upload it) - a very old laptop will do.


  • Mu editor - for writing code and uploading the script to the Itsybitsy

Setting up the Itsybitsy is explained here:

The latest version of CircuitPython:

CircuitPython libraries:

Mu Editor:

Step 2: The Circuit

This is a very simple circuit to set up. The next page illustrates the finished breadboard with coloured wires to make things easy.

Step 3: Breadboard Version of the Circuit

There are power rails at the top and bottom of the breadboard. With red wire join the +ve rails together. With black wire join the -ve rails together.

Join the 3V pin of the Itsybitsy to the lower +ve rail - red wire. (Column 12)

Join the G (GND) pin of the Itsybitsy to the top -ve rail - black wire. (Column 12)

In columns 33 and 34, connect the SSD1306 VCC and GND pins to the top power rails.

With a pink wire join the SCL pins together.

With a grey wire join the SDA pins together.

With red and black wires connect the outer pins of the potentiometer to the upper power rails and with green wire connect the centre (wiper) pin to A5 on the Itsybitsy.

Connect one side of the button switch with a purple wire to pin 2 and with a black wire connect the other side to a GND rail.

Step 4: Loading the Font

Download the font file and drag it to the CIRCUITPY drive. (This is the Itsybitsy.)

Double click the lib folder and look at the list of drivers you have already loaded.

Step 5: Adding Extra Drivers

You will need the following in the lib folder:

  • simpleio.mpy
  • adafruit_bus_device
  • adafruit_framebuf.mpy
  • adafruit_ssd1306.mpy

If they are missing, drag them into the folder from the latest version available.

You are now ready to download the script.

Once loaded into the Mu editor you can save it to the Itsybitsy with the name

The program runs through a series of demonstrations of lines, circles, a dynamic bar graph and displaying defined characters. Just turn the pot slowly and press and hold the button to control the display.

The following pages give more information about how the program works.

Step 6: Setup the Devices

This first section loads all the libraries and sets up the SSD1306, potentiometer and button switch on the correct pins.

Step 7: Define Characters and Draw Horizontal and Vertical Lines

This section sets up the pre-defined characters. They are 5 dots wide and 8 dots high. Each dot in the definition draws 4 dots on the screen so that they show up better.

Horizontal and vertical lines are easy to draw with a loop. You just have to remember that you need the extra dot at the end. A line from (0,7) to (5,7) will need 6 dots: with x equal to 0,1,2,3,4 and 5 in turn.

The basic dot command is oled.pixel(x,y,colour) - 0 is black and 1 is white.

The origin (0,0) is at the top left of the screen, 0 - 127 pixels horizontally (left to right) and 0 - 63 vertically (top to bottom).

Step 8: Boxes, Blocks and Sloping Lines

Boxes are built from horizontal and vertical lines.

Blocks are built from multiple horizontal lines.

For sloping lines we first check co-ordinates are given left most first. If not we swap them over as the line will be drawn from left to right.

We then calculate the slope and use it to set the y value for each value of x.

The display(t) procedure makes the updated screen visible and waits for a short delay, t seconds.

Step 9: Degree Symbol, Anlgnment, Bar Graph and Circle

The degree symbol is created from 4 pixels.

The align() routine adds extra spaces in front of the number to right align short values in a fixed space.

The graph(v) routine draws a horizontal bar graph giving the percentage selected. The value is written at the right hand end using 'T' to represent 100 (Ton or Top).

Circles require some trigonometry so we need to import the math library at the beginning of the script. We use sin, cos and radians to calculate the x and y offsets from the centre as a radius is rotated through 90 degrees. Points are plotted in each of the four quadrants for each calculation of the offsets.

Step 10: Garbage Collection, Titles and Circles

These instructions demonstrate screen clearing to black and white, writing text to the screen and using the gc() 'garbage collection' routine to free up space. The value shows that there is plenty of space for a much larger script.

The program then draws circles with a common centre and with moving centres. Quite a quick routine considering the amount of calculation required.

The heading for the lines demo is written next.

Step 11: Lines Demo

This routine really gives the line() routine a workout. Radial lines are draw from each of the four corners of the display with different spacings forming patterns.

Step 12: The Main Loop: Bar Graph and Defined Characters

This is the main loop of the program. The values from the potentiometer change the values shown and alter the length of the bar graph.

If the button is held down the defined characters are swapped over as are 1/0 and True/False. This loop runs quite slowly because drawing the pre-defined characters is a slow process. You can speed things up by commenting some of them out.

There is no temperature sensor fitted, to keep this demo simple, so the '?' is displayed instead of a value in line 190.

Step 13: Screen Shots

1 Hour Challenge

Participated in the
1 Hour Challenge