Multiplexing 7 segment LED displays with Arduino

Here’s an example on multiplexing three seven-segment LED displays from an Arduino using a single 4511 IC and a handful of transistors. This builds on my last post about interfacing to a single display

Multiplexed displays in action

What you need

  • Arduino board
  • 4511 LED decoder/driver IC
  • 3x common cathode 7 segment LED displays
  • 3x BC327 or similar transistors
  • 3x 1k resistors
  • 7x 390 Ohm resistors
  • 1x 150k resistor
  • 1x 10uF capacitor
  • Breadboard or other prototyping platform
  • Wire

Making it

This one was a fraction too big to fit comfortably on a Protoshield so I used a small breadboard.

Multiplex LED schematic

Note that C1 and R8 are optional; these cause the 4511 to blank the display for a second or two at switch on. This is to prevent the displays producing garbage while the Arduino loads its bootloader. If you omit them, connect pin 4 to 5v.

It doesn’t really matter what output pins you connect the Arduino to on the 4511 amd transistors as long as you configure it correctly in the code.

Remember to connect pins 8 and 16 on the 4511 to 0v and 5v respectively.

Code

Here’s some example source code to drive it which simply counts up in an endless loop. This code assumes the use of PNP transistors as these are what I had at the time. If you wish to use NPN transistors, swap the collector and emitter pins and swap all the HIGH and LOW states for Led1 – 3 in the code.

Code example for PNP transistors:

display(output);
digitalWrite(Led1, LOW);
delay(2);
digitalWrite(Led1, HIGH);

Code example for NPN transistors:

display(output);
digitalWrite(Led1,HIGH);
delay(2);
digitalWrite(Led1, LOW);

The trickiest part with multiplexing is getting the order of instructions correct so that there is no ‘bleeding’ on the display. The code example below sends an output to the 4511 while all of the segment driver transistors are switched off. Once it has sent this, the correct segment is switched on for 2ms then switched off again. The digit sent to the 4511 never changes unless all segments are switched off.

A delay of 2 seems to give the best results; less than this causes it to appear dim and increasing it too much slows execution and can produce visible flicker in the display.

The display() function can be reused for other projects.

// Arduino pins connected to the 4511
const int LedA = 5;
const int LedB = 8;
const int LedC = 7;
const int LedD = 6;

// Arduino pins connected to the segment driver transistors
const int Led1 = 4;
const int Led2 = 3;
const int Led3 = 2;

long count = 0;
int output = 0;
int remain = 0;

void setup()
{
 // Let the Arduino know which pins go where
 pinMode(LedA, OUTPUT);
 pinMode(LedB, OUTPUT);
 pinMode(LedC, OUTPUT);
 pinMode(LedD, OUTPUT);
 pinMode(Led1, OUTPUT);
 pinMode(Led2, OUTPUT);
 pinMode(Led3, OUTPUT);
 digitalWrite(Led1, HIGH);
 digitalWrite(Led2, HIGH);
 digitalWrite(Led3, HIGH);
}

void loop()
{
 // The counter runs from 0-9999 so divide this by 10 as
 // we only have three display segments
 output = count / 10;

 // Display the first digit
 // The order of these steps is important to prevent
 // visible 'bleeding' on the display
 Display(output / 100); // Send first digit to the 4511
 output = output % 100; // Calculate next digit
 digitalWrite(Led1, LOW); // Illuminate first segment
 delay(2); // Wait
 digitalWrite(Led1, HIGH); // Extinguish first segment

 // Display the second digit
 Display(output / 10);
 output = output % 10;
 digitalWrite(Led2, LOW);
 delay(2);
 digitalWrite(Led2, HIGH);

 // Display the third digit
 Display(output);
 digitalWrite(Led3, LOW);
 delay(2);
 digitalWrite(Led3, HIGH);

 // Count to 9999 then reset
 count = count + 1;
 if (count > 9999)
 {
   count = 0;
 }
}

// Function to display the digit 'n'
void Display(int n)
{
 if ( n > 9 )
 {
  n = 9;
 }

 if ( n < 0 )
 {
   n = 0;
 }

 if ( n / 8 == 1 )
 {
  digitalWrite(LedD, HIGH);
 }
 else
 {
   digitalWrite(LedD, LOW);
 }

 n = n % 8;

 if ( n / 4 == 1 )
 {
  digitalWrite(LedC, HIGH);
 }
 else
 {
   digitalWrite(LedC, LOW);
 }
 n = n % 4;

 if ( n / 2 == 1 )
 {
  digitalWrite(LedB, HIGH);
 }
 else
 {
   digitalWrite(LedB, LOW);
 }
 n = n % 2;

 if ( n == 1 )
 {
  digitalWrite(LedA, HIGH);
 }
 else
 {
   digitalWrite(LedA, LOW);
 }

}

3 thoughts on “Multiplexing 7 segment LED displays with Arduino

  1. Jussi 16 July 2010 / 21:46

    Why to multiplex when you can use the latch in 4511? Are you trying to save power or something, or did you do it this way just for the practice? 🙂

  2. Cristi 11 December 2010 / 04:56

    Hello, great work. For what do you use the function to display the digit ‘n’. Can you give me an example?

  3. Sky 2 March 2015 / 10:02

    It worked and thank you so much for both the schema and code.

Leave a Reply to Sky Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s