A countdown counter with the MAX7221 and a seven-segment display
3, 2, 1 … Go!

© Lead Image © bluedarkat, 123RF.com
Build a countdown counter with a Raspberry Pi and some electronics, and you can count down the time to any event.
Days until Christmas, time until retirement: We count the days to many events in life. A countdown counter can help make the time to wait fly by and increase anticipation. In this article, I show you how to use the Raspberry Pi as a control unit to build a chic countdown counter based on an LED segment display.
To ensure that the countdown can be seen from a distance easily, a large seven-segment Kingbright SC08-11SRWA [1] display (20.32mm/0.8 inch high) is used to display the remaining days to an event. The LEDs use a common cathode, which makes the display compatible with a MAX7221 display driver.
The combination of parts used here requires the use of a soldering iron. Completely assembled modules that match the capabilities of the MAX7221 are available, but they have considerably smaller displays of (typically) eight digits. Four digits should be enough for a day countdown (i.e., 9,999 days or more than 27 years). If you really want to count down for a longer period of time, simply add an additional segment to the setup.
MAX7221 Display Driver
In the MAX7221 display driver, an external resistor controls the current for the LEDs. I'll shoot for 33kohm, which results in a current of just under 20mA for one segment of the display. Otherwise, the MAX7221 does not require external wiring. Internally, the display stores the information to be displayed in 8x8-bit RAM.
Table 1 is an overview of the MAX7221 registers and their functions; a data sheet [2] provides further information. The MAX7221 is addressed through the SPI interface. Many microcontrollers are suitable for this purpose – I concentrate on the Raspberry Pi.
Table 1
MAX7221: Register Assignment
Register | Function | Description |
---|---|---|
0x00 |
No-op |
Functionless. In the case of several SPI blocks on one bus, it is used to address only one block. All others receive a no-op. |
0x01 |
Digit0 |
Digit 0 of the display. |
0x02 |
Digit1 |
Digit 1 of the display. |
0x03 |
Digit2 |
Digit 2 of the display. |
0x04 |
Digit3 |
Digit 3 of the display. |
0x05 |
Digit4 |
Digit 4 of the display. |
0x06 |
Digit5 |
Digit 5 of the display. |
0x07 |
Digit6 |
Digit 6 of the display. |
0x08 |
Digit7 |
Digit 7 of the display. |
0x09 |
Decode mode |
Each bit corresponds to one digit of the display (bit 0 = digit 0, etc.). If it is set, the digit works as a segment display; the lower 4 bits of the digit registers are then interpreted as a BCD number. If it is deleted, each segment of the digit can be controlled as a single LED. |
0x0A |
Intensity |
The lower 4 bits of the register control the brightness of the LEDs. |
0x0B |
Scan limit |
The lower 3 bits of the register control which digits of the display are used (0x00 = only digit 0; 0x01 = digits 0 and 1; etc.). |
0x0C |
Shutdown |
Bit 0 = 1: Normal mode, all displays and functions active. Bit 0 = 0: Shutdown mode, all displays off, no response to commands. |
0x0F |
Display test |
Lights all LEDs. |
Circuit Diagram
In the countdown counter circuit diagram (Figure 1), the MAX7221 is the central component. Connected to the four seven-segment displays, it only requires one external component: resistor R1. The complete circuit operates at 3.3V, which is supplied by a type LD1117v33 voltage regulator by STMicroelectronics (input voltage range = 4.3-15V).
The setup is thus quite independent of the voltage source (e.g., a USB power supply, car battery, etc.). Two capacitors buffer fluctuations in the input voltage and counteract the oscillation of the voltage regulator. A header plug joins the connectors of the SPI interface to the Raspberry Pi. Figure 2 shows the complete setup; all components are listed in Table 2.
Table 2
Components
No. | Name | Source | Price/Unit (EUR) |
---|---|---|---|
4 |
SC08-11SRWA 7-segment display |
reichelt.de |
1.15 |
1 |
MAX7221CNG 8-digit LED display driver |
reichelt.de |
5.99 |
1 |
PCB prototype 8x12 |
aliexpress.com |
~1 |
Various small parts |
Craft kit |
2 |
|
Total cost ~EUR20 |
Program
The experimental setup is based on a Raspberry Pi 1 with a current Raspbian image, but the steps described here also work with any other Raspberry Pi model.
First, activate the SPI interface with raspi-config
in 5 Interfacing Options | P4 SPI. After the next reboot, the /dev/spidev0.0
Raspberry Pi device directory contains the SPI device, which can be used as a character-oriented device under Unix.
Listing 1 shows the counter.c
example program, which loads all the libraries used and defines the necessary variables. The write_register()
function (lines 14-17) encapsulates the write()
C function and arranges the parameters accordingly. The main()
function (line 19 to end of code) establishes the connection to the SPI device and sets the speed of the SPI interface. It then initializes the MAX7221 to use digits 0 to 3 in decoder mode and sets the brightness to the maximum.
Listing 1
counter.c
01 #include <fcntl.h> 02 #include <sys/ioctl.h> 03 #include <linux/spi/spidev.h> 04 #include <inttypes.h> 05 #include <stdio.h> 06 #include <time.h> 07 08 static const char *device = "/dev/spidev0.0"; 09 static uint32_t speed = 500000; 10 int handle, diff; 11 time_t ts_now, ts_target; 12 struct tm target; 13 14 void write_register(int handle, uint8_t regi, uint8_t value) { 15 uint8_t tx[] = { regi, value }; 16 write(handle,tx,2); 17 } 18 19 int main() { 20 if ((handle = open(device, O_RDWR)) < 0) { 21 perror("SPI Device Error"); 22 return 1; 23 } 24 if (ioctl(handle, SPI_IOC_RD_MAX_SPEED_HZ, &speed)<0) { 25 perror("SPI Speed Error"); 26 return 1; 27 } 28 // MAX7221-Setup 29 write_register(handle,0x0C,0x01); 30 write_register(handle,0x09,0xFF); 31 write_register(handle,0x0F,0x00); 32 write_register(handle,0x0B,0x03); 33 write_register(handle,0x0A,0x0F); 34 ts_now = time(NULL); 35 target.tm_mday=1; 36 target.tm_mon=4; // Month 1 (Jan = 0) 37 target.tm_year=119; // Year - 1900 38 target.tm_sec=59; 39 target.tm_min=59; 40 target.tm_hour=23; 41 ts_target=mktime(&target); 42 diff=(ts_target-ts_now)/(60*60*24); 43 write_register(handle,0x04,(diff%10000)/1000); 44 write_register(handle,0x03,(diff%1000)/100); 45 write_register(handle,0x02,(diff%100)/10); 46 write_register(handle,0x01,(diff%10)); 47 }
The target
date structure (line 12) generates the timestamp of the target date. This structure has some peculiar characteristics that can cause a great deal of trouble: Days count from 1 and months from 0, and 1900 must be deducted from the year. The values for time of day can be written one to one into the structure.
The remaining lines of the program calculate the difference between the current and target dates and write it to the corresponding memory locations of the MAX7221. By transferring the start of the program to a cronjob (see the "Cron" box), you can start the program once a day, calculate the current display value, and transfer it to the display driver. Save the program and compile it with gcc
(GNU C compiler):
$ gcc counter.c -o counter $ ./counter
The last line runs the program.
Cron
The Unix cron service allows commands and scripts to be executed automatically at certain times. The crontab
command-line tool is used for configuration. Use crontab -l
to see the current settings for the logged in user. The -e
switch puts Crontab in edit mode. An entry contains, separated by white space, the specifications for minute, hour, day of the month, month, and weekday, as well as the command to be executed at the specified time.
The first five parameters control execution time. Numbers stand for times or dates and an asterisk for any given minute, hour, or day. If necessary, you can also use a backslash to define multiple values (e.g., */2
for every second minute). As far as timing is concerned, it is important to ensure that one call can be processed before the next initiates; otherwise, the system will become overloaded over time.
The following are some typical cron examples:
* * * * * /home/user/script # every minute 0 */2 * * * /home/user/script # at the start of every other hour 0 0 * * * /home/user/script # every day at midnight 30 18 * * * /home/user/script # every day at 6:30pm * * 1 * * /home/user/script # every minute on the first day of the month
Further detailed information can be found on the cron man page. Useful pages on the web, such as at Corntab [3], can help you to compose cron lines. You need to make sure that cron executes scripts with the rights of its own user account but does not use environment variables. To do this, specify all paths in full and do not use aliases.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Direct Download
Read full article as PDF:
Price $2.95
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
News
-
An All-Snap Version of Ubuntu is In The Works
Along with the standard deb version of the open-source operating system, Canonical will release an-all snap version.
-
Mageia 9 Beta 2 Ready for Testing
The latest beta of the popular Mageia distribution now includes the latest kernel and plenty of updated applications.
-
KDE Plasma 6 Looks to Bring Basic HDR Support
The KWin piece of KDE Plasma now has HDR support and color management geared for the 6.0 release.
-
Bodhi Linux 7.0 Beta Ready for Testing
The latest iteration of the Bohdi Linux distribution is now available for those who want to experience what's in store and for testing purposes.
-
Changes Coming to Ubuntu PPA Usage
The way you manage Personal Package Archives will be changing with the release of Ubuntu 23.10.
-
AlmaLinux 9.2 Now Available for Download
AlmaLinux has been released and provides a free alternative to upstream Red Hat Enterprise Linux.
-
An Immutable Version of Fedora Is Under Consideration
For anyone who's a fan of using immutable versions of Linux, the Fedora team is currently considering adding a new spin called Fedora Onyx.
-
New Release of Br OS Includes ChatGPT Integration
Br OS 23.04 is now available and is geared specifically toward web content creation.
-
Command-Line Only Peropesis 2.1 Available Now
The latest iteration of Peropesis has been released with plenty of updates and introduces new software development tools.
-
TUXEDO Computers Announces InfinityBook Pro 14
With the new generation of their popular InfinityBook Pro 14, TUXEDO upgrades its ultra-mobile, powerful business laptop with some impressive specs.