Electronics Software Development

Interfacing A 7-Segment Display To An Arduino Uno

Arduino 7-Segment Graphic
Written by John Woolsey

Skill Level: Intermediate

Introduction

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

If you are new to the Arduino platform or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On An Arduino Uno 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 system consists of the Arduino Uno WiFi Rev2 development board connected to a macOS based computer with the desktop Arduino IDE. If you are using a different Arduino model or computer setup, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.

In this tutorial, I will be connecting a common anode 7-segment display to an Arduino through 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 Arduino 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 Arduino board, disconnect the Arduino from power and your computer. 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 Arduino.

Arduino Uno BCD 7-Segment Display Schematic

Note, you may come across other 7-segment display circuits using only one resistor at the common terminal(s), but 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.

Arduino Uno BCD 7-Segment Display Circuit

Once the circuit is built, you can connect your Arduino to your computer with the USB cable.

Writing The Software

Open the Arduino IDE and create a new sketch named BCD7SegmentDisplay with the code shown below.

// BCD7SegmentDisplay - BCD7SegmentDisplay.ino
//
// 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 pin D2.
// Common anode 7-segment display connected through 74LS47 IC to pins D3-D6.
//
// Created by John Woolsey on 01/30/2019.
// Copyright © 2019 Woolsey Workshop.  All rights reserved.


// Pin Mapping
const byte button = 2;  // momentary push button, fires interrupt service routine
const byte bcdA   = 3;  // binary coded decimal (BCD) least significant bit (LSB) for 74LS47 A input pin
const byte bcdB   = 4;
const byte bcdC   = 5;
const byte bcdD   = 6;  // binary coded decimal (BCD) most significant bit (MSB) for 74LS47 D input pin


// Global Variables
unsigned long lastTimeButtonPressed = 0;  // used for debouncing button
byte count = 0;                           // display counter

void setup() {
   // Pin configuration
   pinMode(button, INPUT_PULLUP);  // utilize microprocessor's internal pull-up resistor
   pinMode(bcdA, OUTPUT);
   pinMode(bcdB, OUTPUT);
   pinMode(bcdC, OUTPUT);
   pinMode(bcdD, OUTPUT);

   // Initialize interrupt service routine
   // Calls resetCount() function when button is pressed,
   // i.e., the button pin value falls from high to low.
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
   attachInterrupt(button, resetCount, FALLING);
#else
   attachInterrupt(digitalPinToInterrupt(button), resetCount, FALLING);
#endif
}


void loop() {
   displayWrite(count);         // update display
   count++;                     // increase counter
   if (count == 10) count = 0;  // reset to 0 if count exceeds 9
   delay(1000);                 // wait one second
}


// Resets counter and display to 0
void resetCount() {
   unsigned long currentTimeButtonPressed = millis();  // get current time
   if (currentTimeButtonPressed - lastTimeButtonPressed > 250) {  // allow for button debounce time of 250 ms
      lastTimeButtonPressed = currentTimeButtonPressed;
      count = 0;        // reset counter
      displayWrite(0);  // reset display
   }
}


// Writes value to display using binary coded decimal
void displayWrite(byte value) {
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
   digitalWrite(bcdA, PinStatus(bitRead(value, 0)));  // BCD LSB
   digitalWrite(bcdB, PinStatus(bitRead(value, 1)));
   digitalWrite(bcdC, PinStatus(bitRead(value, 2)));
   digitalWrite(bcdD, PinStatus(bitRead(value, 3)));  // BCD MSB
#else
   digitalWrite(bcdA, bitRead(value, 0));  // BCD LSB
   digitalWrite(bcdB, bitRead(value, 1));
   digitalWrite(bcdC, bitRead(value, 2));
   digitalWrite(bcdD, bitRead(value, 3));  // BCD MSB
#endif
}

The code should be fairly straightforward to understand, 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 itself subsequently drives the a through g segment inputs of the 7-segment display.

The pin mode of the button is specified as INPUT_PULLUP, which uses the internal pull-up resistor for the pin within the microprocessor on the Arduino board, instead of just INPUT since we did not use an external pull-up resistor in the circuit.

Since I am using the new Arduino Uno WiFi Rev2 board, I came across a few differences in how it works versus the standard Uno board. For this reason, I am using preprocessor directives to check if I am on the ARDUINO_AVR_UNO_WIFI_REV2 board or another one.

The first instance is on line 40 where I am setting up the interrupt service routine that triggers a call to the resetCount() function when the button is pressed. Typically we would use the digitalPinToInterrupt() function to translate the pin number to the interrupt number. However, that function does not work as expected for the WiFi Rev2 board. Luckily, no translation is required for the WiFi Rev2, so we can just simply use button.

The second usage is on line 69 and deals with a change made to the argument types of the digitalWrite() function. For the WiFi Rev2, we need to add a PinStatus cast since the underlying type is no longer an integer as is returned by the bitRead() function.

Speaking of bitRead(), this function just 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.

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 within the resetCount() function and I have conservatively set a debounce 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.

Upload (Sketch > Upload) the sketch to the board and 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.

Summary

In this tutorial, we learned how to interface a common anode 7-segment display to an Arduino Uno using a 74LS47 BCD To 7-Segment Decoder/Driver integrated circuit. We also learned how to take into account some of the subtle differences between the new Arduino Uno WiFi Rev2 board and the standard Arduino Uno Rev3.

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