msgbartop
Blog di Dino Ciuffetti (Bernardino in realtà)
msgbarbottom

02 Apr 14 Adafruit 4-Digit 7-Segment Display Backpack on raspberry pi in C

In my previous blog post I published a TSL2561 light sensor driver in C for Raspberry PI. In this article I will publish a user space C driver for Adafruit 4-digit 7-segment display.

This is based on a HT16K33 led driver IC, that it’s a I2C driven RAM mapping 16*8 LED controller driver.

The driver I’m posting it’s valid for the adafruit circuit only, since it’s completely based on the electronic schematic they realized.
Don’t use the driver with other circuits, since the display could not function properly.
Basically the adafruit 7-segment backpack (http://www.adafruit.com/products/879) uses 8 (rows) * 5 (columns) HT16K33 lines to drive its leds. The column number 1 is dedicated to the first digit, the second column is dedicated to the second digit, the third column is attached to the colon sign in the middle of the 4 digits, the fourth column is attached to the third digit, and the fifth colum to the fourth display digit.

adafruit_7seg_schematic

While each row drives a single led of the given column.

The display columns 0, 1, 3, 4 can show numbers and some letters (A-F, n, o, i, l, L, etc…) plus a decimal point, while the column 2 can only show a colon sign (:).
A number or a letter for each digit is composed by 7 led segments, so the possibilities are few… but not so few after all (check 7seg.txt file attachment for more details on letter composition).

So, now comes the fun. How can I access the led driver memory to light display digits in C? Adafruit releases proof of concept libraries in C and python, but they don’t seem to run on my raspberry pi.
Since I am too lazy to port their code with external dependencies, I decided to write my own library in C.

#include "7seg_bp_ada.h"

/* prepare the backpack driver
(the first parameter is the raspberry pi i2c master controller attached to the HT16K33, the second is the i2c selection jumper)
The i2c selection address can be one of HT16K33_ADDR_01 to HT16K33_ADDR_08
*/
HT16K33 led_backpack1 = HT16K33_INIT(1, HT16K33_ADDR_01);

/* initialize the backpack */
rc = HT16K33_OPEN(&led_backpack1);

/* power on the ht16k33 */
HT16K33_ON(&led_backpack1);

/* make it shining bright */
HT16K33_BRIGHTNESS(&led_backpack1, 0x0F);

/* make it not blinking */
HT16K33_BLINK(&led_backpack1, HT16K33_BLINK_OFF);

/* power on the display */
HT16K33_DISPLAY(&led_backpack1, HT16K33_DISPLAY_ON);

/* Say hello */
HT16K33_UPDATE_DIGIT(&led_backpack1, 0, 'H', 0); // first digit
HT16K33_UPDATE_DIGIT(&led_backpack1, 1, 'E', 0); // second digit
// turn off the colon sign in the middle of the 4 digits
HT16K33_UPDATE_DIGIT(&led_backpack1, 2, HT16K33_COLON_OFF, 0);
HT16K33_UPDATE_DIGIT(&led_backpack1, 3, '#', 0); // third digit
HT16K33_UPDATE_DIGIT(&led_backpack1, 4, 'o', 0); // fourth digit
HT16K33_COMMIT(&led_backpack1); // commit to the display memory

// call this if you want to shut down the device (power saving mode)
// HT16K33_OFF(&led_backpack1);

/* close things (the display remains in the conditions left) */
HT16K33_CLOSE(&led_backpack1);

I decided to release the software with the liberal apache 2 license, so feel free to use this software inside your commercial, non free software / firmware.

Below you will find the files .c and .h that you can embed into your project.
It’s helpful for me, and I hope it will be helpful for you.

Ciao, Dino.

Note: on Raspberry PI OS (and debian) you need libi2c-dev (apt install libi2c-dev) before compiling.

gcc -Wall -O2 -o 7seg_bp_ada.o -c 7seg_bp_ada.c
gcc -Wall -O2 -o 7seg_bp_ada_test.o -c 7seg_bp_ada_test.c
gcc -Wall -O2 -o 7seg_bp_ada_test 7seg_bp_ada.o -li2c 7seg_bp_ada_test.o

7seg_bp_ada.c
7seg_bp_ada.h
7seg_bp_ada_test.c

Reader's Comments

  1.    

    Sadly, I am getting an error when compiling:

    pi@raspberrypi:/media/Data/Code/rasp/ht16k33_7seg $ sudo gcc -Wall -O2 -o 7seg_bp_ada.o -c 7seg_bp_ada.c
    7seg_bp_ada.c: In function ‘HT16K33_COMMIT’:
    7seg_bp_ada.c:356:6: warning: implicit declaration of function ‘i2c_smbus_write_i2c_block_data’ [-Wimplicit-function-declaration]
    356 | i = i2c_smbus_write_i2c_block_data(backpack->adapter_fd, 0x00, 16, buf);
    | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    pi@raspberrypi:/media/Data/Code/rasp/ht16k33_7seg $ sudo gcc -Wall -O2 -o 7seg_bp_ada_test.o -c 7seg_bp_ada_test.c
    pi@raspberrypi:/media/Data/Code/rasp/ht16k33_7seg $ sudo gcc -Wall -O2 -o 7seg_bp_ada_test 7seg_bp_ada.o 7seg_bp_ada_test.o
    /usr/bin/ld: 7seg_bp_ada.o: in function `HT16K33_COMMIT’:
    7seg_bp_ada.c:(.text+0x430): undefined reference to `i2c_smbus_write_i2c_block_data’
    collect2: error: ld returned 1 exit status

    Reply to this comment
    •    

      Hi!
      Please, install this package:
      apt install libi2c-dev

      Then try with this one:
      # gcc -Wall -O2 -o 7seg_bp_ada.o -c 7seg_bp_ada.c
      # gcc -Wall -O2 -o 7seg_bp_ada_test.o -c 7seg_bp_ada_test.c
      # gcc -Wall -O2 -o 7seg_bp_ada_test 7seg_bp_ada.o -li2c 7seg_bp_ada_test.o

      Reply to this comment
  2.    

    Hi Dino, I know this blog post is old but just wanted to drop a line and say thanks for posting this driver. Lightweight and easy to understand, it gets the job done!

    Reply to this comment
  3.    

    That works, thanks!

    Reply to this comment
  4.    

    Hello Dino,

    Many thanks, I was looking for something like this!

    Unforunately, when I try compiling, I get the following error (in my own programs and the test from this site):

    7seg_bp_ada_test.c: In function ‘int main()’:
    7seg_bp_ada_test.c:10:26: error: expected primary-expression before ‘.’ token

    7seg_bp_ada_test.c:10:26: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]

    Would you have an idea what could’ve gone wrong?

    Thanks

    Alexander

    Reply to this comment
    •    

      Hi there!
      If I try with the following, I don’t have any error:

      dino@dam2knb:/tmp$ gcc -Wall -O2 -o 7seg_bp_ada.o -c 7seg_bp_ada.c
      dino@dam2knb:/tmp$ gcc -Wall -O2 -o 7seg_bp_ada_test.o -c 7seg_bp_ada_test.c
      dino@dam2knb:/tmp$ gcc -Wall -O2 -o 7seg_bp_ada_test 7seg_bp_ada.o 7seg_bp_ada_test.o

      May be you are having CPP problems like class instance declaration or the like. Not a proble in 7seg_bp_ada.c.

      Reply to this comment
  5. convinced-centennial

Lascia un commento

*