CircuitPython

Adafruit CircuitPython Module Install

To use the LED backpack with your Adafruit CircuitPython board you'll need to install the Adafruit_CircuitPython_HT16K33 module on your board. Remember this module is for Adafruit CircuitPython firmware and not MicroPython.org firmware!

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--read below and carefully follow the referenced steps to find and install these libraries from Adafruit's CircuitPython library bundle.

Bundle Install

For express boards that have extra flash storage, like the Feather/Metro M0 express and Circuit Playground express, you can easily install the necessary libraries with Adafruit's CircuitPython bundle.  This is an all-in-one package that includes the necessary libraries to use the LED backpack display with CircuitPython. For details on installing the bundle, read about CircuitPython Libraries.

Remember for non-express boards like the Trinket M0, Gemma M0, and Feather/Metro M0 basic you'll need to manually install the necessary libraries from the bundle:

  • adafruit_ht16k33
  • adafruit_bus_device
  • adafruit_register

If your board supports USB mass storage, like the M0-based boards, then simply drag the files to the board's file system. Note on boards without external SPI flash, like a Feather M0 or Trinket/Gemma M0, you might run into issues on Mac OSX with hidden files taking up too much space when drag and drop copying, see this page for a workaround.

If your board doesn't support USB mass storage, like the ESP8266, then use a tool like ampy to copy the file to the board. You can use the latest version of ampy and its new directory copy command to easily move module directories to the board.

Before continuing make sure your board's lib folder or root filesystem has at least the adafruit_ht16k33adafruit_bus_device, and adafruit_register folders/modules copied over.

Usage

The following section will show how to control the LED backpack from the board's Python prompt / REPL.  You'll walk through how to control the LED display and learn how to use the CircuitPython module built for the display.

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

I2C Initialization

First you'll need to initialize the I2C bus for your board.  First import the necessary modules:

import board
import busio as io

Note if you're using the ESP8266 or other boards which do not support hardware I2C you need to import from the bitbangio module instead of busio:

import board
import bitbangio as io

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 = io.I2C(board.SCL, board.SDA)

LED Matrix

To use a LED matrix you'll first need to import the adafruit_ht16k33.matrix module and create an instance of the appropriate Matrix class.  There are three classes currently available to use:

  • Matrix8x8 - This is for a simple 8x8 matrix (square or round pixels, they're both the same driver and code).
  • Matrix16x8 - This is for a 16x8 matrix (i.e. double the width of the 8x8 matrices).  For the LED Matrix FeatherWing you want to use this Matrix16x8 class.
  • Matrix8x8x2 - This is for a 8x8 bi-color matrix.

For example to use the Matrix16x8 class import the module and create an instance with:

import adafruit_ht16k33.matrix 
matrix = adafruit_ht16k33.matrix.Matrix16x8(i2c)

The above command will create the matrix class using the default I2C address of the display (0x70).  If you've changed the I2C address (like when using multiple backpacks or displays) you can override it in the initializer using an optional address keyword argument.

For example to create an instance of the Matrix8x8 class on address 0x74:

matrix = adafruit_ht16k33.matrix.Matrix8x8(i2c, address=0x74)

You might notice the matrix turns on to a 'jumbled' collection of random LEDs.  Don't worry!  The display isn't broken, right now the module that controls it doesn't clear the display state on startup so you might see noise from random memory values.

To clear the display and turn all the pixels off you can use the fill command with a color of 0 (off):

matrix.fill(0)

By default the display will update automatically. This way you do not need to call the show function every time you update the display buffer. However, this means it is being sent the contents of the display buffer with every change. This can slow things down if you're trying to do something fancy. If you think you're running into that issue, you can simply turn the auto write feature off. Then you will need to call show to update the display.

# auto write can be turned off
matrix.auto_write = False
# and fill is same as before
matrix.fill(0)
# but now you have to call show()
matrix.show()

To turn all the pixels on you can use fill with a color of 1 (on):

matrix.fill(1)

If you're using the bi-color matrix you can even use a fill color of 2 or 3 to change to different colors of red, green, and yellow (red + green).

Next you can set pixels on the display by accessing them using x,y coordinates and setting a color:

  • X position - X position of the pixel on the matrix.
  • Y position - Y position of the pixel on the matrix.
  • Color - 0 for off, 1 for on (or one of the LEDs for bi-color display), 2 or 3 for other bi-color display colors.

The general way to set a pixel is:

matrix[x,y] = color

For example to set the first pixel at position 0, 0 to on:

matrix[0, 0] = 1

Or to set the opposite corner pixel at position 7, 7 to on:

matrix[7, 7] = 1

That's all there is to controlling the pixels on a LED matrix!  Right now the matrix library is simple and only exposes basic pixel control.  In the future more advanced drawing commands might be avaialable.

Brightness and Blinking

You can change the brightness of the entire display with the brightness property.  This property has a value from 0 to 15 where 0 is the lowest brightness and 15 is the highest brightness.  Note that you don't need to call show after calling brightness, the change is instant.

For example to set the brightness to the minimum:

matrix.brightness = 0

Or to set it back to maximum:

matrix.brightness = 15

You can also make the entire display blink at 3 different rates using the blink_rate property, which has a value 0 to 3:

  • 0 = no blinking
  • 1 = fast blinking (~once a 1/2 second)
  • 2 = moderate blinking (~once a second)
  • 3 = slow blinking (~once every 2 seconds)

Again you don't need to call show after setting the blink rate, the change will immediately take effect.

For example to blink quickly:

matrix.blink_rate = 1

And to stop blinking:

matrix.blink_rate = 0

LED 7-segment Display

To use a 7-segment display you'll first need to import the adafruit_ht16k33.segments module and create an instance of the Seg7x4 class.

import adafruit_ht16k33.segments
display = adafruit_ht16k33.segments.Seg7x4(i2c)

The above command will create the 7-segment class using the default I2C address of the display (0x70).  If you've changed the I2C address (like when using multiple backpacks or displays) you can override it in the initializer using an optional address keyword argument.

For example to create an instance of the Seg7x4 class on address 0x74:

display = adafruit_ht16k33.Seg7x4(i2c, address=0x74)

You might notice the display turns on to a 'jumbled' collection of random LEDs.  Don't worry!  The display isn't broken, right now the module that controls it doesn't clear the display state on startup so you might see noise from random memory values.

To clear the display and turn all the LEDs off you can use the fill command with a color of 0 (off):

display.fill(0)

Setting Individual Digits

You can put a numeric value in any of the display's 4 positions by accessing it using the index of the position.  For example to set position 0 to the number 1 and position 1 to the number 2 call:

display[0] = '1'
display[1] = '2'
display.show()

Display Numbers and Hex Values

You can also use the print function to write to the entire display. Remember the display only has 4 digits so a best effort will be made to display the number--you might need to round the number or adjust it to fit!

display.print(1234)
display.show()
display.print(3.141)
display.show()

To display hex values, pass in a string to print. The hex characters A-F can be displayed.

display.print('FEED')
display.show()

If you want to work with actual integer values, then use the built in string formatting.

display.print('{:x}'.format(65261))
display.show()

You can pass some special characters to the display to control extra capabilities:

  • Colon - Use ':' to turn the colon on, you don't need to specify the position parameter.  Use ';' to turn the colon off.
  • Hex character - Use a character 'a' through 'f' to display a high hex character value at a specified position.

LED 14-segment Quad Alphanumeric Display

To use a 14-segment quad alphanumeric display it's almost exactly the same as the 7-segment display, but with a slightly different class name.  Import the adafruit_ht16k33.segments module again but this time create an instance of the Seg14x4 class.

import adafruit_ht16k33.segments
display = adafruit_ht16k33.segments.Seg14x4(i2c)

The above command will create the 14-segment class using the default I2C address of the display (0x70).  If you've changed the I2C address (like when using multiple backpacks or displays) you can override it in the initializer using an optional address keyword argument.

For example to create an instance of the Seg14x4 class on address 0x74:

display = adafruit_ht16k33.segments.Seg14x4(i2c, address=0x74)

You might notice the display turns on to a 'jumbled' collection of random LEDs.  Don't worry!  The display isn't broken, right now the module that controls it doesn't clear the display state on startup so you might see noise from random memory values.

To clear the display and turn all the LEDs off you can use the fill command with a color of 0 (off):

display.fill(0)
display.show()

To access the individual digits, it's the same as with the 7-segment display. However, the 14-segment display can take any alphanumeric character. For example:

display[0] = 'C'
display[1] = 'I'
display[2] = 'P'
display[3] = 'Y'
display.show() 

You can use the print function to write to the entire display.

display.print('CPY!')
display.show()
This guide was first published on May 20, 2016. It was last updated on Sep 20, 2018. This page (CircuitPython) was last updated on Aug 30, 2018.