Electronics Software Development

Interfacing A 7-Segment Display To A Raspberry Pi

Raspberry Pi 7-Segment Graphic
Written by John Woolsey

Skill Level: Intermediate

Introduction

This tutorial will teach you how to interface a 7-segment display to a Raspberry Pi. A basic understanding of electronics and programming is expected along with some familiarity with the Raspberry Pi platform.

If you are new to the Raspberry Pi platform or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On A Raspberry Pi tutorial before proceeding with this one. In addition, this tutorial will use a solderless breadboard to build a circuit from a schematic (circuit) diagram. The How to Use Breadboards, How to Use a Breadboard, and How to Read a Schematic are some good guides for learning how to translate a schematic to a breadboard.

The resources created for this tutorial are available on GitHub for your reference.

What Is Needed

Background Information

My development board is the Raspberry Pi 3 Model B running the Raspbian (November 2018 release) operating system. If you are using a different model or a different OS that is similar to Raspbian, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.

In this tutorial, I will connect a common anode 7-segment display to a Raspberry Pi using a 74LS47 BCD To 7-Segment Decoder/Driver integrated circuit (IC). This chip decodes binary coded decimal (BCD), which is just basic binary numbers for the 0-9 decimal digits, into the individual LED segments of a 7-segment display. The 4 BCD inputs of the chip are denoted as A through D, while the individual LED segment outputs are denoted as a through g. See the 74LS47 datasheet for more information. While usage of the IC is not strictly necessary, it does allow us to use fewer Raspberry Pi GPIO pins and write a simpler program. If you prefer to use a common cathode display instead, replace the 74LS47 decoder IC with a 74LS48 chip and make sure to connect the common terminals of the display to ground instead of power.

If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.

Building The Circuit

Before connecting any circuitry to your Raspberry Pi, shutdown and disconnect the Raspberry Pi from power. This avoids accidental damage during wiring.

Place the components and wire up the circuit on a breadboard according to the schematic diagram shown below and then connect it to your Raspberry Pi.

Raspberry Pi BCD 7-Segment Display Schematic

Note, you may come across other 7-segment display circuits using only one resistor at the common terminal(s). Using resistors across all the segments, as done here, ensures a constant level of brightness regardless of how many segments are lit.

The circuit should look similar to the one shown below once completed. Note, I used a two digit display (that I had available) in my circuit, but I only connected one digit. I am also using a GPIO to breadboard interface board to make wiring simpler, but this is not strictly necessary.

Raspberry Pi BCD 7-Segment Display Circuit

Once the circuit is built, you can connect power to your Raspberry Pi and boot it up.

Writing The Software

Open your favorite text editor on the Raspberry Pi and create a new Python program named BCD7SegmentDisplay.py with the code shown below.

# BCD7SegmentDisplay.py
#
# Description:
# Implements a counter that is displayed on a common anode 7-segment display
# driven through a BCD To 7-Segment Decoder/Driver (74LS47) IC.  The count is
# reset to 0 when a button is pressed.
#
# Circuit:
# Momentary push button connected to BCM pin 5, physical pin 29.
# Common anode 7-segment display connected through 74LS47 IC to BCM pins 22-25,
# physical pins 15, 16, 18, 22.
#
# Created by John Woolsey on 02/16/2019.
# Copyright (c) 2019 Woolsey Workshop.  All rights reserved.


# Imports
import RPi.GPIO as GPIO
from time import sleep


# Pin Definitions
button =  5  # momentary push button, fires interrupt service routine
bcdA   = 22  # binary coded decimal (BCD) least significant bit (LSB) for 74LS47 A input pin
bcdB   = 23
bcdC   = 24
bcdD   = 25  # binary coded decimal (BCD) most significant bit (MSB) for 74LS47 D input pin


# Global Variables
count = 0  # display counter


# Functions

# Reads a bit of a number
def bitRead(value, bit):
   return value & (1 << bit)  # shift mask to bit position and AND to value

# Resets counter and display to 0
def resetCount(button):
   global count     # declare count as global variable
   count = 0        # reset counter
   displayWrite(0)  # reset display

# Writes value to display using binary coded decimal
def displayWrite(value):
   GPIO.output(bcdA, bitRead(value, 0))  # BCD LSB
   GPIO.output(bcdB, bitRead(value, 1))
   GPIO.output(bcdC, bitRead(value, 2))
   GPIO.output(bcdD, bitRead(value, 3))  # BCD MSB


# Main

# Pin configuration
GPIO.setmode(GPIO.BCM)                                 # use BCM pin numbering
GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # utilize microprocessor's internal pull-up resistor
GPIO.setup(bcdA, GPIO.OUT)
GPIO.setup(bcdB, GPIO.OUT)
GPIO.setup(bcdC, GPIO.OUT)
GPIO.setup(bcdD, GPIO.OUT)

# Initialize interrupt service routine
# Calls resetCount() function when button is pressed,
# i.e., the button pin value falls from high to low.
GPIO.add_event_detect(button, GPIO.FALLING, callback=resetCount, bouncetime=250)

# Display count on 7-segment display
print("Press CTRL-C to exit.")
try:
   while True:
      displayWrite(count)        # update display
      count += 1                 # increment counter
      if count == 10: count = 0  # reset to 0 if count exceeds 9
      sleep(1)                   # wait one second

# Cleanup
finally:           # exit cleanly when CTRL+C is pressed
   GPIO.cleanup()  # release all GPIO resources
   print("\nCompleted cleanup of GPIO resources.")

The code should be fairly straightforward, but I would like to mention a few items of interest.

The bcdA through bcdD pins represent the A through D BCD inputs of the 74LS47 chip, which subsequently drives the a through g segment inputs of the 7-segment display.

The bitRead() function translates a number into its individual binary bits. For example bitRead(5, 0) will return 1 since the least significant bit in the number 5, 00000101 in binary, is 1. Likewise, bitRead(5, 1) will return 0. This is how we are sending our values to the BCD decoder chip.

The Raspberry Pi’s microcontroller is capable of using internal pull-up resistors. I chose to take advantage of this capability instead of attaching an extra external pull-up resistor to the button. This is accomplished by adding the extra pull_up_down=GPIO.PUD_UP argument within the pin setup of the button. If we only used GPIO.IN, then we would be required to add the external resistor.

Buttons used within circuits are notoriously noisy, meaning once pressed they can take a little while for their contacts to settle down to a known state. For instance, the interrupt service routine we are using can actually get called multiple times for a single button press. For this reason, a technique called debouncing is usually applied to register a button’s state. In software we can handle this by waiting a short amount of time, usually around 100 ms or so. In our program this is handled by adding an extra bouncetime argument to the add_event_detect() function which I have conservatively set to a wait time of 250 ms.

If there is something you don’t quite understand or needs further explanation, please let me know in the comment section and I will try to answer your question.

Running And Testing The System

Now that our circuit is built and our software is written, it is time to run and test our creation.

Within a terminal window, run the following command to run the Python program.

% python BCD7SegmentDisplay.py

You should see the 7-segment display counting up from 0. When it reaches 9, it should reset back to 0. Press the pushbutton on the breadboard at anytime and the display should reset back to 0.

Press CTRL-C to exit the program when you are done.

Summary

In this tutorial, we learned how to interface a common anode 7-segment display to a Raspberry Pi using a 74LS47 BCD To 7-Segment Decoder/Driver integrated circuit.

The final source code and schematic used for this tutorial is located on GitHub.

Thank you for joining me in this journey and I hope you enjoyed the experience. Please feel free to share your thoughts in the comments section below.

About the author

John Woolsey

John is an electrical engineer who loves science, math, and technology and teaching it to others even more.
 
He knew he wanted to work with technology from an early age, building his first robot when he was in 8th grade. His first computer was a Timex/Sinclair 2068 followed by the Tandy 1000 TL (aka really old stuff).
 
He put himself through college (University of Texas at Austin) by working at Motorola where he worked for many years after that in Research and Development.
 
John started developing mobile app software in 2010 for himself and for other companies. He has also taught programming to kids for summer school and enjoyed years of judging kids science projects at the Austin Energy Regional Science Festival.
 
Electronics, software, and teaching all culminate in his new venture to learn, make, and teach others via the Woolsey Workshop website.

Leave a Comment