4 digits, 7 segments LED display multiplexing with Arduino


Last time I showed You how to control 1 digit 7 segment LED display with Arduino. This time it’s not 1, but 4 digits. To connect 1 digit to Arduino we had to use 8 ports, so to connect 4 digits we need to have 4×8=32? Not necessary. Where is a way to use much less ports, it’s called multiplexing. Using multiplexing at one time only one digit is active(e.g. for 2ms). All digits is turned on is serial, but because human’s eye is inert we have illusion, that all digits are lighting at same time.

As You can see form schematic bellow with multiplexing implemented we required only 4 additional ports compared to 1 digit circuit, total – 12.

Because at the same time only one digit will be on All 4 digits segments inputs are connected together. By connecting digits common cathodes to ground we are controlling which digit shall be turned on. Atmega 1280 µCPU port can drain(receive) maximum 40 mA current. If all one digits segments are on, we are having 20×8= 160 mA that is to much, so we can’t to connect common cathodes directly to Arduino ports.  Therefore I have used BC547 NPN transistors as switches. Transistor is opened, when positive voltage is applied at the base.

Let’s see the code.

It’s modified version of earlier commented code, so I’m lazy to explain some of the code again.

Modified code have definition of ports that(with transistors) are controlling digits.

#define GND1 52
#define GND2 53
#define GND3 50
#define GND4 51

And they are outputs

pinMode(GND1, OUTPUT);
pinMode(GND2, OUTPUT);

pinMode(GND3, OUTPUT);
pinMode(GND4, OUTPUT);

There new function to display all 4 digits. You can see it have 4 parts, to display 4 digits.

void showdigits (int number)
{

// e.g. we have "1234"
showdigit(number/1000);  // segments are set to display "1"
digitalWrite(GND1, HIGH); // first digit on,
digitalWrite(GND2, LOW); // other off
digitalWrite(GND3, LOW);
digitalWrite(GND4, LOW);

delay (1);

number = number%1000;  // remainder of 1234/1000 is 234
digitalWrite(GND1, LOW); // first digit is off
 showdigit(number/100); //// segments are set to display "2"
digitalWrite(GND2, HIGH); // second digit is on
 delay (1); // and so on....

number =number%100;    
digitalWrite(GND2, LOW);
showdigit(number/10);
digitalWrite(GND3, HIGH);
delay (1);

number =number%10; 
digitalWrite(GND3, LOW);
showdigit(number); 
digitalWrite(GND4, HIGH);
 delay (1);

};

My new target is to make digital clock of these displays using timer for accuracy.

And full code goes here:

/*
7 LED segments demo counter program from electronicsblog.net.
If You share/use this code elsewhere on the internet please mention this code source.
*/

// segment | Arduino board PIN number 

#define G 22
#define F 23
#define A 24
#define B 25
#define E 26
#define D 27
#define C 28
#define DP 29

// Commonn cathodes control
#define GND1 52
#define GND2 53
#define GND3 50
#define GND4 51

int timer=0; 

int i=0;
// functions to display digits

void digit0 () {
// for 0 needed to turn ON F A B C D E segments, so:

digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);

//////////////////////// G segment should be turn OFF
digitalWrite(G, LOW);

};

void digit1 () {

digitalWrite(A,LOW);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, LOW);
};

void digit2 () {

digitalWrite(A,HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
};

void digit3 () {

digitalWrite(A,HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
};

void digit4 () {

digitalWrite(A,LOW);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
};

void digit5 () {

digitalWrite(A,HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
};

void digit6 () {

digitalWrite(A,HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
};

void digit7 () {

digitalWrite(A,HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, LOW);
};

void digit8 () {

digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);

};

void digit9 () {

digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);

};

//function to display digit from inputed int

void showdigit (int digit)

{

 switch (digit) {

 case 0:
 digit0 ();
 break;

 case 1:
 digit1 ();
 break;

 case 2:
 digit2 ();
 break;

 case 3:
 digit3 ();
 break;

 case 4:
 digit4 ();
 break;

 case 5:
 digit5 ();
 break;

 case 6:
 digit6 ();
 break;

 case 7:
 digit7 ();
 break;

 case 8:
 digit8 ();
 break;

 case 9:
 digit9 ();
 break;

 default:

 break;

 }; 

};

// showing 4 digits
void showdigits (int number)
{

// e.g. we have "1234"
showdigit(number/1000);  // segments are set to display "1"
digitalWrite(GND1, HIGH); // first digit on,
digitalWrite(GND2, LOW); // other off
digitalWrite(GND3, LOW);
digitalWrite(GND4, LOW);

delay (1);

number = number%1000;  // remainder of 1234/1000 is 234
digitalWrite(GND1, LOW); // first digit is off
 showdigit(number/100); //// segments are set to display "2"
digitalWrite(GND2, HIGH); // second digit is on
 delay (1); // and so on....

number =number%100;    
digitalWrite(GND2, LOW);
showdigit(number/10);
digitalWrite(GND3, HIGH);
delay (1);

number =number%10; 
digitalWrite(GND3, LOW);
showdigit(number); 
digitalWrite(GND4, HIGH);
 delay (1);

}; 

void setup()

{

pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(DP, OUTPUT);

pinMode(GND1, OUTPUT);
pinMode(GND2, OUTPUT);
pinMode(GND3, OUTPUT);
pinMode(GND4, OUTPUT);

};
void loop ()

{ 
  timer++;

 showdigits (i);

  if (timer==10) {

timer=0;

i++;

if (i>10000) {i=0;};

if (i%2) { digitalWrite(DP, HIGH); }

else  {digitalWrite(DP, LOW); };

  }; 

};
  • Avangard_85

    Hi, is it possible to drive six unit of 7segment, using ATMega128. On arduino we have 14 Digital and 6 analog input. I can substitute the analog pin into digital pin and control extra 2 unit of 7segment, right?

    • http://www.electronicsblog.net/ Darius

      If you are short of digital pins, you could use analog with “analogWrite(pin, value) ” where “off” is when value is 0, and “on” is when value is 255. It is easier to use analog pins to control output of common cathodes.

      • Lipuwwf

        I have test this is a very good project i have adapter program for use Arduino Uno (change digital and analog Pin) work all and also  Buzzer ok.
        I have used 1 resistor 470 ohm 1/4w common push button to gnd.
        Only 1 upgrade possible  push button for select count up or dawn and led indicator for up or down.
        But is OK 100%.
        I work for create PCB Shield for a stable hardware.
        Regard

        • Lipuwwf

          Possible it
          is previewed to transform the plan in order to realize a clock controlled
          radius module DCF77 or with IC Ds series rtc?
          Regard

  • Coolguy84007

    Hi, thanx for posting it was helpful… keep it up…

  • Lipuwwf

    Error load
    F was not declared for this scope

     digitalWrite(F, HIGH);
    ????
    Regards.
    Eu

    • http://www.electronicsblog.net/ Darius

       Use not “F” but example “S” it’s problem with Arduino 1.0 software. With 0022 code compiles without errors.

  • Lipuwwf

    Tanks Darius
    Incredible error in V.1
    I have changed F/ S
    Work OK 100%
    Is possible set Up or Down / Start Stop or preset time up down / Hardware buttom.
    I ask Big question….
    Regards

  • Wirral_guy

    Hi Darius. I have put this together on an Arduino Uno but the clock runs very slow, the digits countdown approx 1 every 2 seconds. I have tried to work out the timer functions (and map them against the Uno fnctions) but it is making little sense at the moment. Can you explain the timer process in a little more detail? Or, at least let me know how to adjust the it! :)

  • Jamal

    I appretiate you cooperation
    Thanks lot darius
    I have one quistion i hope to get answer from you
    Suppose i have database i mean stored data like file.cvs in sd card and there are date and time fields .
    How i can search for example if i search about date if it is found result it will put it upon digits
    Ex:
    12/2/2013 12:40
    22/3/2013 4:30
    5/4/2013 7:25
    During search by date 22/3/2013
    it will put time 4:30 upon 4 digits and so on

    I will appretiate your coopretion

    Best regard
    Jamal