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
- Raspberry Pi Running Raspbian Or Similar Linux Based OS (available on Raspberry Pi Foundation and Adafruit)
- Optional Raspberry Pi GPIO Breakout Board (available on Adafruit and CanaKit)
- Solderless Breadboard (available on Adafruit and SparkFun)
- Preformed Breadboard Jumper Wire Kit (available on SparkFun and CanaKit)
- 7 x Male-Female Jumper Wires (available on Adafruit and Arrow)
- 74LS47 BCD To 7-Segment Decoder/Driver Integrated Circuit (available on Arrow and Digi-Key)
- 7-Segment Display (available on SparkFun and Digi-Key)
- Momentary Push Button (available on Adafruit and SparkFun)
- 7 x 330 Ω Resistors (available on SparkFun and Amazon)
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.
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.
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.
Leave a Comment