HT16K33 four-digit display backpack

Four red digits and a colon on an HT16K33 I2C backpack at 0x70 to 0x77. Aliases: Adafruit 7-segment backpack, I2C 4-digit display.

The chip holds the picture in its own RAM and scans the LEDs itself, so the sketch writes a number once and gets on with its work. It dims in sixteen steps and blinks without the sketch doing anything, and it shares the two I2C wires with sensors, which is why clocks and monitors use it.

Pins

Pin What it does
VCC Supply, 4.5 V to 5.5 V.
GND Ground.
SDA I2C data. The backpack carries the pull-ups.
SCL I2C clock.

Properties

address is 0x70 (the default) to 0x77, set by the three solder jumpers A0 to A2 on the back. Up to eight backpacks can share one bus.

How it talks

The chip reads the high nibble of each byte as a command, as the HT16K33 datasheet lays out:

  • 0x00 to 0x0F sets the RAM pointer, and the bytes after it go into the sixteen bytes of display RAM, the pointer stepping on and wrapping. A read returns the RAM.
  • 0x21 starts the oscillator. At power on the chip is in standby and shows nothing.
  • 0x80 | blink << 1 | on: the display on or off, and a blink of 2 Hz, 1 Hz or 0.5 Hz.
  • 0xE0 | level: brightness, a duty of (level + 1) / 16.

On the backpack, RAM bytes 0, 2, 6 and 8 are the four digits, left to right, with segment A in bit 0 and the decimal point in bit 7. Byte 4 is the colon, on bit 1.

The library

Adafruit_LEDBackpack.h works as its tutorial uses it:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_7segment matrix = Adafruit_7segment();

void setup() {
  matrix.begin(0x70);
}

void loop() {
  for (int counter = 0; counter < 10000; counter++) {
    matrix.println(counter);
    matrix.writeDisplay();
    delay(10);
  }
}

print(n, DEC) or print(n, HEX) right-aligns a whole number, and one that does not fit shows ----. writeDigitNum(position, digit, dot) and writeDigitRaw(position, segments) write one digit, where positions 0, 1, 3 and 4 are the digits and 2 is the colon. drawColon(true), setBrightness(0 to 15), blinkRate(HT16K33_BLINK_1HZ) and clear() are there too. Nothing changes on the display until writeDisplay(). Printing a float needs floating point, which these boards do not have: write the digits with writeDigitNum() and a dot instead.

What the model gets right

The command set, standby at power on, the RAM pointer and its wrap, reading the RAM back, sixteen dimming steps and the three blink rates, all from the HT16K33 datasheet. The backpack's digit and colon wiring is Adafruit's.

What it does not model

The key scan and its interrupt pin, the LED currents, and the RAM's undefined contents at power on (it starts blank here). Only the four-digit seven-segment backpack is a part; the 8x8 matrix and alphanumeric backpacks are not.

Common mistakes

Forgetting writeDisplay(). Every call before it only changes the buffer in the sketch.

Writing the third digit to position 2. That is the colon; the digits are 0, 1, 3 and 4.

See it in action

Air quality monitor shows the CO2 reading on this display and blinks it when the air needs changing. Open it at /templates.