Skip to content
Arduino contents

Lesson 1.10: 7-segment display

Four digits add up to 32 segments, and the Uno doesn't have that many pins. This lesson solves it with two techniques you'll find in many devices: the shift register and multiplexing.

Parts

How it works

On a common-cathode display, the four digits share the segment pins —A to G and the point— and each one has its own cathode. A digit lights when its cathode is LOW, and shows whichever segments are HIGH.

Multiplexing means lighting one digit at a time, with its number, for a few milliseconds, then moving to the next. Above about 50 cycles per second the eye doesn't see the flicker and perceives all four lit.

The 74HC595 receives the eight segments serially on a single data pin, clocked by a clock pin, and presents them on its eight outputs when it gets a pulse on the latch. Three pins drive all eight segments.

Each digit is a byte: bit 0 is segment A and bit 6 is G. Zero, which lights everything except G, is 0b00111111, or 0x3F.

Wiring

ComponentConnects toNote
74HC595, VCC (16) and MR (10)5V
74HC595, GND (8) and OE (13)GND
74HC595, DS (14)Pin 8
74HC595, ST_CP (12)Pin 9
74HC595, SH_CP (11)Pin 10
74HC595, Q0–Q6 (15, 1–6)Display, segments A–G (pins 11, 7, 4, 2, 1, 10, 5)In order: Q0 to A, Q1 to B…
74HC595, Q7 (7)Display, point DP (pin 3)
Display, digits 1–4 (pins 12, 9, 8, 6)Pins 2, 3, 4 and 5Each through a 220 Ω resistor

Code

// Counter from 0000 to 9999 on a multiplexed display.
const int DATA_PIN = 8;   // DS
const int LATCH_PIN = 9;  // ST_CP
const int CLOCK_PIN = 10; // SH_CP
const int DIGIT_PINS[4] = {2, 3, 4, 5}; // cathodes of digits 1-4

// Bit 0 = segment A ... bit 6 = G, bit 7 = point.
const byte DIGITS[10] = {
  0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
};

int number = 0;
unsigned long lastTick = 0;

void setup() {
  pinMode(DATA_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);

  for (int i = 0; i < 4; i++) {
    pinMode(DIGIT_PINS[i], OUTPUT);
    digitalWrite(DIGIT_PINS[i], HIGH); // HIGH = digit off
  }
}

void writeSegments(byte segments) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, segments);
  digitalWrite(LATCH_PIN, HIGH); // outputs change here, all at once
}

void loop() {
  if (millis() - lastTick >= 1000) {
    lastTick = millis();
    number = (number + 1) % 10000;
  }

  // Right to left: units, tens, hundreds, thousands.
  int value = number;
  for (int digit = 3; digit >= 0; digit--) {
    writeSegments(DIGITS[value % 10]);
    digitalWrite(DIGIT_PINS[digit], LOW);  // light this digit
    delay(4);
    digitalWrite(DIGIT_PINS[digit], HIGH); // and turn it off before the next
    value /= 10;
  }
}

What the code does

  • DIGITS holds the segment pattern for each digit, 0 to 9.
  • writeSegments() lowers the latch, sends the byte bit by bit with shiftOut() and raises it again: all eight outputs change together, at the end.
  • value % 10 is the last digit and value /= 10 drops it, so the loop walks the digits from right to left.
  • Each digit is switched off before the segments change. Otherwise the new number would flash briefly on the previous digit.
  • The counter advances with millis(), not delay(): multiplexing can't stop, or only one digit would show.

Step by step

  1. Seat the 74HC595 and the display across the breadboard's centre channel. The chip's notch marks the side of pins 1 and 16.
  2. Wire the 74HC595's power and control, then its eight outputs to the display, and finally the four digits with their resistors.
  3. Upload the code.

Result

The display counts from 0000 to 9999, one number per second, with all four digits lit at once.

If it doesn't work

  • If the wrong segments light, one of the 74HC595 outputs goes to the wrong segment: go over Q0–Q7 in the table.
  • If nothing lights, check that MR is at 5V and OE at GND: with MR LOW the register is cleared, and with OE HIGH the outputs are off.
  • If your display is common-anode, the logic is inverted: digits are enabled with HIGH and segments with LOW. Send ~DIGITS[n] instead of DIGITS[n].
  • An 8 looking dimmer than a 1 is normal with the resistors on the digits: the current is shared among the lit segments.