Ht16k33Multi (ht16k33_multi v0.2.0)

View Source

Ht16k33Multi is a library for controlling one or more Ht16k33 microchips, which are commonly used to drive 7-segment displays, such as these shown below:

Image of Ht16k33 7-segment display

Features

The main features of Ht16k33Multi include:

  • Displaying numbers on a 7-segment display
  • Displaying words using a special 7-segment font
  • Supporting multiple displays (hence the "multi" in the library name). You can easily chain multiple Ht16k33 devices to display full sentences or other content across them.
  • Utilizing the built-in blinking and dimming features of the Ht16k33 microchip

Usage

A typical setup involves using the Ht16k33 with a 7-segment display and a Raspberry Pi — such as the Raspberry Pi Zero.

You can use the Nerves Project to build firmware for the Raspberry Pi and other embedded systems like the BeagleBone. See the list of supported targets (Nerves Project) for more information.

Installation

  1. Connect the Ht16k33 to your embedded system. See the Connect the device to the I²C bus and power section for details.

  2. Add the library to your dependencies

     # mix.exs
     defp deps do
       [
         {:ht16k33_multi, "~> 0.1"}
       ]
     end
  3. Fetch the dependencies

     mix deps.get
    
  4. Start the Ht16k33Multi GenServer

    You can start it manually in iex:

     iex> Ht16k33Multi.start_link()

    Or supervise it within your application:

     children = [
       # Single device with default I²C bus ("i2c-1") and address (0x70)
       Ht16k33Multi,
    
       # OR with explicit options
       {Ht16k33Multi, i2c_bus: "i2c-1", address: 0x70}
     ]

    If you're using multiple devices (all on the default I²C bus "i2c-1"), assign each a name and address:

     children = [
       {Ht16k33Multi, name: :red_leds, address: 0x70},
       {Ht16k33Multi, name: :blue_leds, address: 0x71},
       {Ht16k33Multi, name: :yellow_leds, address: 0x72}
     ]

    💡 See the Device Address section to learn how to detect your I²C bus and device address.

  5. Write to the display

    Display a message:

     iex> Ht16k33Multi.write("Hola")

    Enable blinking:

     iex> Ht16k33Multi.blinking_on()

    Dim the display:

     iex> Ht16k33Multi.dimming(6)

Connect the Device to the I2C Bus and Power

Using Qwiic with a Raspberry Pi Zero (rpi0)

You can easily chain multiple Ht16k33 devices using Qwiic cables. This allows you to have multiple displays showing full sentences or other content.

Wiring Overview:

Wire ColorFunctionRaspberry Pi Zero PinGPIO Pin
BlackGND6GND
Red3.3V45V
BlueSDA (Serial Data)3GPIO2
YellowSCL (Serial Clock)5GPIO3

HT16K33 7-segment display with I²C Qwiic connection to a Raspberry Pi Zero

Device Address

You can detect the I²C bus and device addresses using Circuits.I2C:

iex> Circuits.I2C.bus_names()
["i2c-1"]

iex> Circuits.I2C.detect_devices()
Devices on I2C bus "i2c-1":
* 112  (0x70)
1 devices detected on 1 I²C buses

The device address is configurable in hardware. You can set it by soldering the address pins (shown at the bottom right in the image below).

See the HT16K33 datasheet for more details.

HT16K33 7-segment backside with address pins and I²C Qwiic connection

Testing

This library has been tested with the Adafruit 7-Segment LED HT16K33 Backpack.

Summary

Functions

Sets blinking off for the 7-segment display.

Sets blinking off for all displays.

Turns blinking on for the 7-segment display.

Sets blinking on for all displays.

Returns a specification to start this module under a supervisor.

Sets colon off for the 7-segment display.

Sets colon off for all displays.

Sets colon on for the 7-segment display.

Sets colon on for all displays.

Sets the dimming level (brightness) of the display.

Dims all displays with the same value.

Starts the Ht16k33Multi GenServer.

Returns the current state of the Ht16k33Multi GenServer.

Writes a string or integer to the 7-segment display.

Writes a string of characters or an integer to multiple 7-segment displays.

Functions

blinking_off(name \\ __MODULE__)

(since 0.1.0)
@spec blinking_off(atom() | pid() | {atom(), any()} | {:via, atom(), any()}) :: :ok

Sets blinking off for the 7-segment display.

  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Examples

Ht16k33Multi.blinking_off(:red_leds)

blinking_off_all(devices_names)

(since 0.1.0)
@spec blinking_off_all(any()) :: list()

Sets blinking off for all displays.

  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].

This function calls blinking_off/1 for each device in the list, setting the blinking off for all of them.

Examples

Ht16k33Multi.blinking_off_all([:blue_leds, :red_leds])

blinking_on(name \\ __MODULE__, speed \\ 0)

(since 0.1.0)
@spec blinking_on(atom() | pid() | {atom(), any()} | {:via, atom(), any()}, any()) ::
  :ok

Turns blinking on for the 7-segment display.

The default blinking speed is 0.5 Hz.

  • speed – The blinking speed:
    • 0 – 0.5 Hz
    • 1 – 1 Hz
    • 2 – 2 Hz
  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Example

Ht16k33Multi.blinking_on(:red_leds, 1)

blinking_on_all(devices_names, speed \\ 0)

(since 0.1.0)
@spec blinking_on_all(any(), any()) :: list()

Sets blinking on for all displays.

  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].
  • speed – The blinking speed. Refer to blinking_on/2 for available speed values.

This function calls blinking_on/2 for each device in the list, setting the blinking on for all of them.

Examples

Ht16k33Multi.blinking_on_all([:blue_leds, :red_leds], 1)

child_spec(init_arg)

(since 0.1.0)

Returns a specification to start this module under a supervisor.

See Supervisor.

colon_off(name \\ __MODULE__)

(since 0.2.0)
@spec colon_off(atom() | pid() | {atom(), any()} | {:via, atom(), any()}) :: :ok

Sets colon off for the 7-segment display.

  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Examples

Ht16k33Multi.colon_off(:red_leds)

colon_off_all(devices_names)

(since 0.2.0)
@spec colon_off_all(any()) :: list()

Sets colon off for all displays.

  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].

This function calls colon_off/1 for each device in the list, setting the colon off for all of them.

Examples

Ht16k33Multi.colon_off_all([:blue_leds, :red_leds])

colon_on(name \\ __MODULE__)

(since 0.2.0)
@spec colon_on(atom() | pid() | {atom(), any()} | {:via, atom(), any()}) :: :ok

Sets colon on for the 7-segment display.

  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Examples

Ht16k33Multi.colon_on(:red_leds)

colon_on_all(devices_names)

(since 0.2.0)
@spec colon_on_all(any()) :: list()

Sets colon on for all displays.

  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].

This function calls colon_on/1 for each device in the list, setting the colon on for all of them.

Examples

Ht16k33Multi.colon_on_all([:blue_leds, :red_leds])

dimming(value, name \\ __MODULE__)

(since 0.1.0)
@spec dimming(any(), atom() | pid() | {atom(), any()} | {:via, atom(), any()}) :: :ok

Sets the dimming level (brightness) of the display.

The value should be an integer between 1 and 16.

  • value – The dimming level. Must be an integer between 1 and 16.
  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Examples

Ht16k33Multi.dimming(8, :red_leds)

dimming_all(value, devices_names)

(since 0.1.0)
@spec dimming_all(any(), any()) :: list()

Dims all displays with the same value.

The value should be an integer between 1 and 16.

  • value – The dimming level. Must be an integer between 1 and 16.
  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].

This function calls dimming/2 for each device in the list, setting the dimming level for all of them.

Examples

Ht16k33Multi.dimming_all(8, [:blue_leds, :red_leds])

start_link(options \\ [])

(since 0.1.0)
@spec start_link(keyword()) :: :ignore | {:error, any()} | {:ok, pid()}

Starts the Ht16k33Multi GenServer.

Options

  • :name – (optional) The GenServer name of the device. Use this to run multiple GenServers for different LED displays.

  • :i2c_bus – The name of the I²C bus (e.g., "i2c-1"). Defaults to "i2c-1".

  • :address – The I²C address of the device (e.g., 0x70). Defaults to 0x70.

Default values

name: Ht16k33Multi,
i2c_bus: "i2c-1",
address: 0x70

Examples

Start with defaults:

Ht16k33Multi.start_link()

Start with custom name and address:

Ht16k33Multi.start_link(name: :red_leds, address: 0x72)

status(name \\ __MODULE__)

(since 0.1.0)
@spec status(atom() | pid() | {atom(), any()} | {:via, atom(), any()}) ::
  %Ht16k33Multi{
    address: term(),
    i2c_ref: term(),
    last_command: term(),
    name: term()
  }

Returns the current state of the Ht16k33Multi GenServer.

  • name – The GenServer name, PID, or tuple identifying the process. This should match the name provided when starting the GenServer with Ht16k33Multi.start_link/1.

Examples

Ht16k33Multi.status()
Ht16k33Multi.status(:red_leds)

write(characters, name \\ __MODULE__)

(since 0.1.0)
@spec write(any(), atom() | pid() | {atom(), any()} | {:via, atom(), any()}) :: :ok

Writes a string or integer to the 7-segment display.

You can pass more than 4 characters or digits, but only the first 4 will be shown since the display has just 4 positions.

  • characters – A string or integer to display.
  • name – The GenServer name of the device. This should match the name provided to Ht16k33Multi.start_link/1, e.g., Ht16k33Multi.start_link(name: :red_leds).

Examples

Ht16k33Multi.write("Hola")
Ht16k33Multi.write(43, :red_leds)

write_to_all(characters, devices_names, option \\ [])

(since 0.1.0)
@spec write_to_all(binary(), list(), keyword()) :: list()

Writes a string of characters or an integer to multiple 7-segment displays.

  • characters – A binary (string) or integer to display.
  • devices_names – A list of GenServer names that identify the displays. These names should match those provided to Ht16k33Multi.start_link/1, e.g., [:blue_leds, :red_leds].
  • option – An optional keyword list of options. Use one_word_per_display: false if you want to display characters continuously across all displays.

By default, one word (up to 4 characters) is written per display. Words longer than 4 characters will be truncated.

If you want to display the characters continuously across displays, pass the option one_word_per_display: false.

Example

Ht16k33Multi.write_to_all("Hola que tal?", [:blue_leds, :red_leds, :yellow_leds])