Some links in this post may be affiliate links. We may get paid if you buy something or take an action after clicking one of these, but without addictional costs for you compared to direct buying.
RPI 4 digit 7 segment featured image

How to control a 4 digit 7 Segment Display from Raspberry PI with Python

Check my RPI articles in Best Raspberry PI projects article or peppe8o.com home page. Or subscribe my newsletter (top right in this page) to be notified when new projects are available! Also interested to start 3D printing with a cheap budget? Visit my cheap 3D printers list
0
(0)
4 digit 7 segment display picture

4 Digit 7 Segment Display is a simple electronic display, similar to Single 7 segment display, but composed of 4 digits than can show at the same time 4 chars. It also has dot leds, but in different confiurations (single for each digit, central colon, etc).

It is used within a wide number application, usually to diplay time.

Its operation is based on persistence of vision principle: you can drive one digit at time, so you must drive each digit at a speed so that human eye cannot perceive power off moments.

When using 4-digit 7-segment display, please notice that if it is common anode, the common anode pin connects to the power source; if it is common cathode, the common cathode pin connects to the GND. This guide is based on cathode one, nut anode works with the same code by inverting digit selection logic.

These devices have a simple internal wiring diagrams:

4 digit 7 segment display segments internal circuit

As shown in picture, once configured A…DP pins to 1 (HIGH) to diplay correct number, pins 12, 9, 8 and 6 drive in what digit position to display. For cathode elements, these four pins must all stay to 1 (HIGH) except for the digit you want to power on. For anode elements, these pins must all stay to 0 (LOW) except for the digit you want to power on.

Followin picture shows also the pinout for the cathodic 4 digit display I’m going to use:

4 digit 7 segment display pinout

In this article we’ll control our 4 Digit 7 segment display from a Raspberry PI Zero W. This article applies also to newer Raspberry PI boards.

What We Need

Raspberry PI Zero WH board

As usual, I suggest adding from now to your favourite ecommerce shopping chart all needed hardware, so that at the end you will be able to evaluate overall costs and decide if continuing with the project or removing them from shopping chart. So, hardware will be only:

Many of listed hardware (except from Raspberry PI Zero W and micro SD Card) can be bought alone or can be also found in the useful Elegoo starter kit.

Step-by-Step Procedure

Wiring Diagram

Prepare cabling according to following wiring diagram:

4 digit 7 segment display RPI wiring

This wiring produces the following mapping between Display and Raspberry PI:

Display SegmentDisplay PinRaspberry PI phisical pinRaspberry PI BCM GPIO
A111824
B72225
C4248
D2267
E1281
F103212
G53616
DP33820
DIGIT 112814
DIGIT 291015
DIGIT 381218
DIGIT 461623

Please find below the overall picture:

RPI 4 digit 7 segment Display picture

OS Preparation

Start with OS installation using Install Raspberry PI OS Lite guide. This guide can be also used with Raspberry PI OS Desktop installation.

Make your OS up-to-date:

sudo apt update
sudo apt upgrade

Python Scripting

Install GPIO

sudo apt install rpi.gpio

Get from my download area seg4DigitDisplay.py script:

wget https://peppe8o.com/download/python/seg4DigitDisplay.py

Script Usage

This script can be used by simply calling from terminal:

python3 seg4DigitDisplay.py

Value to be displayed must be set in “toDisplay” variable inside the script:

toDisplay="16.30" # numbers and digits to display

This variable can be set with four numbers and one dot or no dot after each number. A space will deploy a powered off digit corresponding to its position. Please find below some valid examples:

  • 12.34
  • 1.23.4
  • 1234.
  • 1 2.3 (there is a space between “1” and “2”)
  • 1.2 3. (there is a space between “2” and “3”)
  • 123. (there is a space before “1”)
  • 1.2.3.4.
  • 1234

To stop script, simply press CTRL+C. This will execute a GPIO clenaup closing all GPIOs.

Script explaination

This script starts with some variables setting:

toDisplay="16.30" # numbers and digits to display
delay = 0.005 # delay between digits refresh

toDisplay sets what you want to show in your display.

Delay is the time each single digit stays on. So, from it also depends the refresh rate for overall display. This is an important variable. A too low delay means that Raspberry PI could not be able to disable/enable GPIOs so fast, thus resulting with all segments in all digis appearing on. A too high delay means that refresh rate is affeted, resulting in a blinking effect for display digits (with persistence of vision resulting compromised). Also resistors affect these results. With 100ohm resistors I reached a good result on 0.005 seconds delay.

Following section defines what Raspberry PI pins we are going to use. We will use BCM naming convention. Please refer to Raspberry PI Pinout: collection of GPIO Schemas for phisical to BCM relations

selDigit = [14,15,18,23]
# Digits:   1, 2, 3, 4

display_list = [24,25,8,7,1,12,16] # define GPIO ports to use
#disp.List ref: A ,B ,C,D,E,F ,G

digitDP = 20
#DOT = GPIO 20

Then GPIOs are also all set as output:

GPIO.setwarnings(False)
for pin in display_list:
 GPIO.setup(pin,GPIO.OUT) # setting pins for segments
for pin in selDigit:
 GPIO.setup(pin,GPIO.OUT) # setting pins for digit selector
GPIO.setup(digitDP,GPIO.OUT) # setting dot pin
GPIO.setwarnings(True)

Warnings are disabled because this script will leave display active after execution.

An array is prepared to manage easily segments activation for each single number (so that arrSeg[0] shows 0, arrSeg[1] shows 1, etc):

arrSeg = [[1,1,1,1,1,1,0],\
 [0,1,1,0,0,0,0],\
 [1,1,0,1,1,0,1],\
 [1,1,1,1,0,0,1],\
 [0,1,1,0,0,1,1],\
 [1,0,1,1,0,1,1],\
 [1,0,1,1,1,1,1],\
 [1,1,1,0,0,0,0],\
 [1,1,1,1,1,1,1],\
 [1,1,1,1,0,1,1]]

Then the two main functions come. As you can remember, we defined what to display as a string in toDisplay variable. spliToDisplay function splits this string in an array of 4 elements, so that each element is a simple number (or space). Also dots are added to the element that the dot is following.

def splitToDisplay (toDisplay): # splits string to digits to display
 arrToDisplay=list(toDisplay)
 for i in range(len(arrToDisplay)):
  if arrToDisplay[i] == ".": arrToDisplay[(i-1)] = arrToDisplay[(i-1)] + arrToDisplay[i] # dots are concatenated to previous array element
 while "." in arrToDisplay: arrToDisplay.remove(".") # array items containing dot char alone are removed
 return arrToDisplay

With an array so composed, the showDsiplay function takes in charge to display all 4 digits. This uses a for cicle with 4 steps. Each step enables a digit by putting its selector to 0 (LOW). This is because we are using a cathode Display.

def showDisplay(digit):
 for i in range(0, 4): #loop on 4 digits selectors (from 0 to 3 included)
  sel = [1,1,1,1]
  sel[i] = 0
  GPIO.output(selDigit, sel) # activates selected digit
  if digit[i].replace(".", "") == " ": # space disables digit
   GPIO.output(display_list,0)
   continue
  numDisplay = int(digit[i].replace(".", ""))
  GPIO.output(display_list, arrSeg[numDisplay]) # segments are activated according to digit mapping
  if digit[i].count(".") == 1:
   GPIO.output(digitDP,1)
  else:
   GPIO.output(digitDP,0)
  time.sleep(delay)

With anode displays modify the two rows according to the following:

 sel = [0,0,0,0]
 sel[i] = 1

Finally, the main loop is an infinite number of recalls to previously defined functions in pipe.

try:
 while True:
  showDisplay(splitToDisplay(toDisplay))
except KeyboardInterrupt:
 print('interrupted!')
 GPIO.cleanup()
sys.exit()

The “except KeyboardInterrup” manages a Keyboard interrupt (CTRL+C) so that this trigger passes a GPIO clenanup before exiting, so powering off the whole circuit.

Enjoy!

How useful was this post?

Click on a star to rate it anonymously!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

3 thoughts on “How to control a 4 digit 7 Segment Display from Raspberry PI with Python”

  1. Hey,

    I modified your code a bit to get it worked for me, basically it is quite similar to what you have achieved so far, but there is some changes in the way of displaying numbers.
    I appreciate your efforts to make such nice tutorials.

    the code is below:

    import sys, os
    import RPi.GPIO as GPIO
    import time
    import random
    #fpid = os.fork()
    #if fpid!=0:

    to_display = ‘12,25’

    GPIO.setmode (GPIO.BCM)
    GPIO.setwarnings(False)
    display_list = [17,27,22,10,9,11,6] #
    # display list ref: A, B, C, D, E, F, G
    for pin in display_list:
    GPIO.setup(pin,GPIO.OUT) # set pins for each segement

    # digits 1, 2, 3,4
    set_digit = [26,8,19,7] #23=29
    for digit in set_digit:
    GPIO.setup(digit,GPIO.OUT) # set pins for digit selector

    digit_dot = 16
    # dot GPIO port
    GPIO.setup(digit_dot, GPIO.OUT)
    GPIO.setwarnings(True)

    # A, B, C, D,E,F,G
    arrSeg = [[0,0,0,0,0,0,1],\
    [1,0,0,1,1,1,1],\
    [0,0,1,0,0,1,0],\
    [0,0,0,0,1,1,0],\
    [1,0,0,1,1,0,0],\
    [0,1,0,0,1,0,0],\
    [0,1,0,0,0,0,0],\
    [0,0,0,1,1,1,1],\
    [0,0,0,0,0,0,0],\
    [0,0,0,0,1,0,0]]

    def split_num(to_display): # splits the given number string
    “”” Splits variable ‘to_display’ string to a list of elements,
    so that each element is a simple str number or space, and set strains to number
    of digits given
    “””
    arrToDisplay = list(to_display)
    if “,” in arrToDisplay:
    arrToDisplay[arrToDisplay.index(‘,’)] = ‘.’
    # index “,” inlist and replace with “.”
    if len(arrToDisplay) > 5:
    raise ValueError(‘Given Number is out of the range of display!’)
    # raise error if given number is more that for digits
    return arrToDisplay

    def show_display(num): # num represents any number that splitTodisplay cleans up
    “”” this function basically activates digits and the corresponding display
    segements according to the variable(num), and removes ‘.’ from the variable
    if it finds one
    “””
    # handling floating numbers
    if len(num) > 4:
    for i in range(0,4):
    new_num = [x for x in num if x!=’.’] # if ‘.’ in num, replaces ‘.’ with ”
    sel_digit = [[1, 0, 0, 0],\
    [0, 1, 0, 0],\
    [0, 0, 1, 0],\
    [0, 0, 0, 1]]

    GPIO.output(set_digit,sel_digit[i])
    GPIO.output(display_list,arrSeg[int(new_num[i])])
    # activate decimal digit
    if num[i+1] == ‘.’:
    GPIO.output(digit_dot,0)
    else:
    GPIO.output(digit_dot,1)
    time.sleep(.0001)
    # integer number
    else:
    for i in range(0,4):
    sel_digit = [[1, 0, 0, 0],\
    [0, 1, 0, 0],\
    [0, 0, 1, 0],\
    [0, 0, 0, 1]]
    GPIO.output(set_digit,sel_digit[i])
    GPIO.output(display_list,arrSeg[int(num[i])])
    time.sleep(.0001)

    try:
    time_end = time.time()+2 # time.time() time elapsed since 1970 in seconds

    # while loop runs only two minutes , not a infinite loop
    while time.time()<time_end: # while loop runs for 2 seconds
    show_display(split_num(to_display))

    except KeyboardInterrupt:
    print('interrupted!')

    finally:
    GPIO.cleanup()

    sys.exit()

    comments and feedback are always welcomed!

    Best wishes,

    aVral

  2. Pingback: Best Raspberry PI projects with Open Source software - peppe8o

Leave a Comment

Your email address will not be published. Required fields are marked *

I accept the Privacy Policy