7 segments led with arduino 2560

Hi,

I doing a small project with 6 display 7 segment (I will call A1, A2, A3, A4, A5, A6) and 3 cd4543B (I will call Da, Db, Dc) with an arduino mega 2560. I also use 3 transistor

Da is use for A1, A2
Db is use for A3, A4
Dc is use for A5, A6

The circuit is done, and work if I use only 4 display I have tried different combination (A1, A2, A3, A4, or A1, A2, A5, A6 or A2, A3, A4, A5, or A3, A4, A5, A6) and all work well.

but If I want to use five or six display, nothing work…
my code for 5 display,

I don’t understand why it’s not working.

Thanks a lot

Code :

//Da
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//Db
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//Dc
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;

// transistors
const int alim_dizainemillier= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;

void setup()
{

pinMode(bit_A,OUTPUT);
pinMode(bit_B,OUTPUT);
pinMode(bit_C,OUTPUT);
pinMode(bit_D,OUTPUT);
pinMode(bit_E,OUTPUT);
pinMode(bit_F,OUTPUT);
pinMode(bit_G,OUTPUT);
pinMode(bit_H,OUTPUT);
pinMode(bit_I,OUTPUT);
pinMode(bit_J,OUTPUT);
pinMode(bit_K,OUTPUT);
pinMode(bit_L,OUTPUT);
pinMode(alim_dizainemillier,OUTPUT);
pinMode(alim_millier,OUTPUT);
pinMode(alim_centaine,OUTPUT);
pinMode(alim_dizaine,OUTPUT);
pinMode(alim_unite,OUTPUT);

digitalWrite(bit_A,LOW);
digitalWrite(bit_B,LOW);
digitalWrite(bit_C,LOW);
digitalWrite(bit_D,LOW);
digitalWrite(bit_E,LOW);
digitalWrite(bit_F,LOW);
digitalWrite(bit_G,LOW);
digitalWrite(bit_H,LOW);
digitalWrite(bit_I,LOW);
digitalWrite(bit_J,LOW);
digitalWrite(bit_K,LOW);
digitalWrite(bit_L,LOW);
digitalWrite(alim_dizainemillier,LOW);
digitalWrite(alim_millier,LOW);
digitalWrite(alim_centaine,LOW);
digitalWrite(alim_dizaine,LOW);
digitalWrite(alim_unite,LOW);  
}

void loop() 
{
 for(int i=0;i<10000;i++)
 {
   afficher_nombre(i);
   
 }
}




void afficher_nombre(int nombre)

{
 long temps;
 int unite=0,dizaine=0,centaine=0, millier=0, dizainemillier=0;
 dizainemillier=nombre/10000;
 millier=(nombre-(10000*dizainemillier))/1000;
 centaine=(nombre-1000*millier)-(10000+dizainemillier)/100;
 dizaine=(nombre-(centaine*100)-(millier*1000)-(dizainemillier*10000))/10;
 unite=nombre-(dizainemillier*10000)-(millier*1000)-(centaine*100)-(dizaine*10);
 
 temps=millis();
 while((millis()-temps)<500){   
 
 

    digitalWrite(alim_dizainemillier,HIGH);
    afficher_CD(dizainemillier);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);
    digitalWrite(alim_dizaine,LOW);
    digitalWrite(alim_unite,LOW);
    delay(5);
 

 https://www.arduino.cc/   digitalWrite(alim_dizainemillier,LOW);
    digitalWrite(alim_millier,HIGH);
    afficher_CM(millier);
    digitalWrite(alim_centaine,LOW);
    digitalWrite(alim_dizaine,LOW);
    digitalWrite(alim_unite,LOW);
    delay(5);
 

   digitalWrite(alim_dizainemillier,LOW);
   digitalWrite(alim_millier,LOW);
   digitalWrite(alim_centaine,HIGH);
   afficher_CM(centaine);
   digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);
   delay(5);
   

   digitalWrite(alim_dizainemillier,LOW);
   digitalWrite(alim_millier,LOW);
   digitalWrite(alim_centaine,LOW);
   digitalWrite(alim_dizaine,HIGH);
   afficher_UD(dizaine);
   digitalWrite(alim_unite,LOW);

   digitalWrite(alim_dizainemillier,LOW);
   digitalWrite(alim_millier,LOW);
   digitalWrite(alim_centaine,LOW);
   digitalWrite(alim_dizaine,LOW);
   digitalWrite(alim_unite,HIGH);
   afficher_UD(unite);
   delay(5);
 }
}


void afficher_UD(int chiffre)
{
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);

      if(chiffre>=8)
         {
           digitalWrite(bit_D,HIGH);
           chiffre=chiffre-8;
         }
     if(chiffre>=4)
         {
           digitalWrite(bit_C,HIGH);
           chiffre=chiffre-4;
         }
    if(chiffre>=2)
         {
           digitalWrite(bit_B,HIGH);
           chiffre=chiffre-2;
         }
    if(chiffre>=1)
         {
           digitalWrite(bit_A,HIGH);
           chiffre=chiffre-1;
         }
}


void afficher_CM(int chiffre)
{
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);

      if(chiffre>=8)
         {
           digitalWrite(bit_H,HIGH);
           chiffre=chiffre-8;
         }
     if(chiffre>=4)
         {
           digitalWrite(bit_G,HIGH);
           chiffre=chiffre-4;
         }
    if(chiffre>=2)
         {
           digitalWrite(bit_F,HIGH);
           chiffre=chiffre-2;
         }
    if(chiffre>=1)
         {
           digitalWrite(bit_E,HIGH);
           chiffre=chiffre-1;
         }
}

void afficher_CD(int chiffre)
{
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);

      if(chiffre>=8)
         {
           digitalWrite(bit_L,HIGH);
           chiffre=chiffre-8;
         }
     if(chiffre>=4)
         {
           digitalWrite(bit_K,HIGH);
           chiffre=chiffre-4;
         }
    if(chiffre>=2)
         {
           digitalWrite(bit_J,HIGH);
           chiffre=chiffre-2;
         }
    if(chiffre>=1)
         {
           digitalWrite(bit_I,HIGH);
           chiffre=chiffre-1;
         }
}

The problem may be in the power supply. The Arduino can't power many LEDs.

Post a complete wiring diagram (hand drawn, not Fritizing).

But in this case each display work one after the other (fast enough to give the illusion it work at the same time), so for me it’s unclear why it could be a power supply problem ?

I try to augment the delay and see one display after the others but it does not work… I get strange number and it stop…

here in attached a diagram of my circuit, thanks for any help...

schem.gif|1058x794

Typically, one would use a single part on the bottom all displays in parallel, and cycle thru the 6 transistors one at a time quickly. No current limit resisters between the displays and the bottom part, could burn something out eventually. Why 6 segments and not all 7? Just curious.

Should also have a 0.1uF cap on each bottom part, from it's Vcc pin to Gnd, as near to the VCC pin as you can.

Those seem to be common cathode parts, could replace the bottom part and the transistors with a single MAX7219, cut out a lot of the wiring. MAX7219 will do all the multiplexing at 800 Hz so everything looks smooth, you send it two bytes to update the digit you want:

digitalWrite (ssPin, LOW);
shiftOut (latchPin, clockPin, MSBFIRST, address); // from 1 to 8
shiftOut (latchPin, clockPin, MSBFIRST, digitToDisplay); // from 0 to 9, and HELP, or define your own data
                                                              // I usually create a look up array, then call fontArray[digitToDisplay]
digitalWrite (ssPin, HIGH);

Oh yes sure there is resistance 220ohms for each segments of the 6 display, it didn't not appear on the diagram sorry.

This circuit is based on this one :

|500x347 |500x231

Done 3 times in parallel to have 6 displays.

I'm sorry I didn't understood what you mean by "Why 6 segments and not all 7? Just curious"...

Thanks for the reference of MAX7219 I will have look. But do you think it's possible to do it with 3 cd4543B ?

When you "Should also have a 0.1uF cap on each bottom part, from it's Vcc pin to Gnd, as near to the VCC pin as you can." you mean between the 5V going to transistors and GND ?

Thanks a lot for your help !

Eight 7-segment displays on a circuit board, including the MAX7219 driver, will cost you $2 shipped (ebay). Only three control pins from the Arduino (and supply/ground). Several of those boards can be daisy-chained, using the same three pins. Why bother with transistors, resistors and an old 40-series chip. Leo..

Yes you're right, there is cheaper and easier way... But it's just a project to understand and learn thing... I would like to make it work but the objective is learning more than having something working...

For personal satisfaction I would like to understand ...:

why my circuit work for 4 displays even used with three cd4543B (only 2 are necessary) and when I want to use with 5 or 6 displays (just modifying the program) nothing work at all ...?

Your code has some logic errors. Start with one digit, get that working and build upon that. One obvious error that I see is missing a delay for "alim_dizaine".

I don't think this part of your code is sequenced correctly, you should present the correct bcd code to the 4543 before you turn on the transistor. This sequence:

    digitalWrite(alim_dizainemillier, HIGH);
    afficher_CD(dizainemillier);
    digitalWrite(alim_millier, LOW);
    digitalWrite(alim_centaine, LOW);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
    delay(5);


    digitalWrite(alim_dizainemillier,LOW);
    digitalWrite(alim_millier, HIGH);
    afficher_CM(millier);
    digitalWrite(alim_centaine, LOW);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
    delay(5);


    digitalWrite(alim_dizainemillier, LOW);
    digitalWrite(alim_millier, LOW);
    digitalWrite(alim_centaine, HIGH);
    afficher_CM(centaine);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
    delay(5);


    digitalWrite(alim_dizainemillier, LOW);
    digitalWrite(alim_millier, LOW);
    digitalWrite(alim_centaine, LOW);
    digitalWrite(alim_dizaine, HIGH);
    afficher_UD(dizaine);
// MISSING DELAY HERE
    digitalWrite(alim_unite, LOW);

    digitalWrite(alim_dizainemillier, LOW);
    digitalWrite(alim_millier, LOW);
    digitalWrite(alim_centaine, LOW);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, HIGH);
    afficher_UD(unite);
    delay(5);

could and should look like this:

    afficher_CD(dizainemillier);
    digitalWrite(alim_dizainemillier, HIGH);
    delay(5);
    digitalWrite(alim_dizainemillier, LOW);

    afficher_CM(millier);
    digitalWrite(alim_millier, HIGH);
    delay(5);
    digitalWrite(alim_millier, LOW);

    afficher_CM(centaine);
    digitalWrite(alim_centaine, HIGH);
    delay(5);
    digitalWrite(alim_centaine, LOW);

    afficher_UD(dizaine);
    digitalWrite(alim_dizaine, HIGH);
    delay(5);
    digitalWrite(alim_dizaine, LOW);

    afficher_UD(unite);
    digitalWrite(alim_unite, HIGH);
    delay(5);
    digitalWrite(alim_unite, LOW);

And while this fragment appears to function:

void afficher_CD(int chiffre)
{
  digitalWrite(bit_I, LOW);
  digitalWrite(bit_J, LOW);
  digitalWrite(bit_K, LOW);
  digitalWrite(bit_L, LOW);

  if (chiffre >= 8)
  {
    digitalWrite(bit_L, HIGH);
    chiffre = chiffre - 8;
  }
  if (chiffre >= 4)
  {
    digitalWrite(bit_K, HIGH);
    chiffre = chiffre - 4;
  }
  if (chiffre >= 2)
  {
    digitalWrite(bit_J, HIGH);
    chiffre = chiffre - 2;
  }
  if (chiffre >= 1)
  {
    digitalWrite(bit_I, HIGH);
    chiffre = chiffre - 1;
  }
}

can be shortened to:

void afficher_UD(int chiffre)
{
  digitalWrite(bit_A,chiffre & 1);
  digitalWrite(bit_B,chiffre & 2);
  digitalWrite(bit_C,chiffre & 4);
  digitalWrite(bit_D,chiffre & 8);
}

thanks a lot, I tested this modification, it's better but I still have the 3 first displays that are giving strange things....

here the code with your corrections :

//Da
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//Db
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//Dc
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;

// transistors
const int alim_dizainemillier= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;

void setup()
{

pinMode(bit_A,OUTPUT);
pinMode(bit_B,OUTPUT);
pinMode(bit_C,OUTPUT);
pinMode(bit_D,OUTPUT);
pinMode(bit_E,OUTPUT);
pinMode(bit_F,OUTPUT);
pinMode(bit_G,OUTPUT);
pinMode(bit_H,OUTPUT);
pinMode(bit_I,OUTPUT);
pinMode(bit_J,OUTPUT);
pinMode(bit_K,OUTPUT);
pinMode(bit_L,OUTPUT);
pinMode(alim_dizainemillier,OUTPUT);
pinMode(alim_millier,OUTPUT);
pinMode(alim_centaine,OUTPUT);
pinMode(alim_dizaine,OUTPUT);
pinMode(alim_unite,OUTPUT);

digitalWrite(bit_A,LOW);
digitalWrite(bit_B,LOW);
digitalWrite(bit_C,LOW);
digitalWrite(bit_D,LOW);
digitalWrite(bit_E,LOW);
digitalWrite(bit_F,LOW);
digitalWrite(bit_G,LOW);
digitalWrite(bit_H,LOW);
digitalWrite(bit_I,LOW);
digitalWrite(bit_J,LOW);
digitalWrite(bit_K,LOW);
digitalWrite(bit_L,LOW);
digitalWrite(alim_dizainemillier,LOW);
digitalWrite(alim_millier,LOW);
digitalWrite(alim_centaine,LOW);
digitalWrite(alim_dizaine,LOW);
digitalWrite(alim_unite,LOW);  
}

void loop() 
{
 for(int i=0;i<100000;i++)
 {
   afficher_nombre(i);
   
 }
}


void afficher_nombre(int nombre)

{
 long temps;
 int unite=0,dizaine=0,centaine=0, millier=0, dizainemillier=0;
 dizainemillier=nombre/10000;
 millier=(nombre-(10000*dizainemillier))/1000;
 centaine=(nombre-1000*millier)-(10000+dizainemillier)/100;
 dizaine=(nombre-(centaine*100)-(millier*1000)-(dizainemillier*10000))/10;
 unite=nombre-(dizainemillier*10000)-(millier*1000)-(centaine*100)-(dizaine*10);

 temps=millis();
 while((millis()-temps)<500){   
   
    afficher_CD(dizainemillier);
    digitalWrite(alim_dizainemillier, HIGH);
    delay(5);
    digitalWrite(alim_dizainemillier, LOW);

    afficher_CM(millier);
    digitalWrite(alim_millier, HIGH);
    delay(5);
    digitalWrite(alim_millier, LOW);

    afficher_CM(centaine);
    digitalWrite(alim_centaine, HIGH);
    delay(5);
    digitalWrite(alim_centaine, LOW);

    afficher_UD(dizaine);
    digitalWrite(alim_dizaine, HIGH);
    delay(5);
    digitalWrite(alim_dizaine, LOW);

    afficher_UD(unite);
    digitalWrite(alim_unite, HIGH);
    delay(5);
    digitalWrite(alim_unite, LOW);
 }
}

void afficher_UD(int chiffre)
{
  digitalWrite(bit_A,chiffre & 1);
  digitalWrite(bit_B,chiffre & 2);
  digitalWrite(bit_C,chiffre & 4);
  digitalWrite(bit_D,chiffre & 8);
}

void afficher_CM(int chiffre)
{
  digitalWrite(bit_E,chiffre & 1);
  digitalWrite(bit_F,chiffre & 2);
  digitalWrite(bit_G,chiffre & 4);
  digitalWrite(bit_H,chiffre & 8);
}

void afficher_CD(int chiffre)
{
  digitalWrite(bit_I,chiffre & 1);
  digitalWrite(bit_J,chiffre & 2);
  digitalWrite(bit_K,chiffre & 4);
  digitalWrite(bit_L,chiffre & 8);
}

I think you need to slow down the display of each number, a delay(500) should fix it.

void loop() 
{
 for(int i=0;i<100000;i++)
 {
   afficher_nombre(i);
   delay(500);   
 }
}

I have tried but it still doing the same thing ....

I post some videos here : Working fine for 4 displays

With bugs for 5 displays

If anyone have some for clue ....

thanks to avr_fred I have modify the code for 5 displays that now look like :

//Da
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//Db
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//Dc
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;

// transistors
const int alim_dizainemillier= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;

void setup()
{

pinMode(bit_A,OUTPUT);
pinMode(bit_B,OUTPUT);
pinMode(bit_C,OUTPUT);
pinMode(bit_D,OUTPUT);
pinMode(bit_E,OUTPUT);
pinMode(bit_F,OUTPUT);
pinMode(bit_G,OUTPUT);
pinMode(bit_H,OUTPUT);
pinMode(bit_I,OUTPUT);
pinMode(bit_J,OUTPUT);
pinMode(bit_K,OUTPUT);
pinMode(bit_L,OUTPUT);
pinMode(alim_dizainemillier,OUTPUT);
pinMode(alim_millier,OUTPUT);
pinMode(alim_centaine,OUTPUT);
pinMode(alim_dizaine,OUTPUT);
pinMode(alim_unite,OUTPUT);

digitalWrite(bit_A,LOW);
digitalWrite(bit_B,LOW);
digitalWrite(bit_C,LOW);
digitalWrite(bit_D,LOW);
digitalWrite(bit_E,LOW);
digitalWrite(bit_F,LOW);
digitalWrite(bit_G,LOW);
digitalWrite(bit_H,LOW);
digitalWrite(bit_I,LOW);
digitalWrite(bit_J,LOW);
digitalWrite(bit_K,LOW);
digitalWrite(bit_L,LOW);
digitalWrite(alim_dizainemillier,LOW);
digitalWrite(alim_millier,LOW);
digitalWrite(alim_centaine,LOW);
digitalWrite(alim_dizaine,LOW);
digitalWrite(alim_unite,LOW);  
}

void loop() 
{
 for(int i=0;i<100000;i++)
 {
   afficher_nombre(i);
   delay(5);
 }
}


void afficher_nombre(int nombre)

{
 long temps;
 int unite=0,dizaine=0,centaine=0, millier=0, dizainemillier=0;
 dizainemillier=nombre/10000;
 millier=(nombre-(10000*dizainemillier))/1000;
 centaine=(nombre-1000*millier)-(10000+dizainemillier)/100;
 dizaine=(nombre-(centaine*100)-(millier*1000)-(dizainemillier*10000))/10;
 unite=nombre-(dizainemillier*10000)-(millier*1000)-(centaine*100)-(dizaine*10);

 temps=millis();
 while((millis()-temps)<500){   
   
    afficher_CD(dizainemillier);
    digitalWrite(alim_dizainemillier, HIGH);
    delay(5);
    digitalWrite(alim_dizainemillier, LOW);

    afficher_CM(millier);
    digitalWrite(alim_millier, HIGH);
    delay(5);
    digitalWrite(alim_millier, LOW);

    afficher_CM(centaine);
    digitalWrite(alim_centaine, HIGH);
    delay(5);
    digitalWrite(alim_centaine, LOW);

    afficher_UD(dizaine);
    digitalWrite(alim_dizaine, HIGH);
    delay(5);
    digitalWrite(alim_dizaine, LOW);

    afficher_UD(unite);
    digitalWrite(alim_unite, HIGH);
    delay(5);
    digitalWrite(alim_unite, LOW);
 }
}

void afficher_UD(int chiffre)
{
  digitalWrite(bit_A,chiffre & 1);
  digitalWrite(bit_B,chiffre & 2);
  digitalWrite(bit_C,chiffre & 4);
  digitalWrite(bit_D,chiffre & 8);
}

void afficher_CM(int chiffre)
{
  digitalWrite(bit_E,chiffre & 1);
  digitalWrite(bit_F,chiffre & 2);
  digitalWrite(bit_G,chiffre & 4);
  digitalWrite(bit_H,chiffre & 8);
}

void afficher_CD(int chiffre)
{
  digitalWrite(bit_I,chiffre & 1);
  digitalWrite(bit_J,chiffre & 2);
  digitalWrite(bit_K,chiffre & 4);
  digitalWrite(bit_L,chiffre & 8);
}

But I still ha some bug....

I also post on this forum

The code needs rewriting with arrays so that there is only one piece of code for each operation and only the array index varies. This means if one works, any number will work. The code will be smaller, more general, easier to read and easier to modify / extend / maintain.

An array for the transistor pins indexed by digit, an array of arrays for the pins for each digits...

I think it's because I have overflow... arduino use 16 bits so I can't use "int" I need to use "long"... I will try and tell you. EDIT : It still have a bug....

@MarkT I will have a look about array... I never use with arduino but it should be easy... thanks ! but I would like to understand where is the error

There is a typo and parenthesis error in the section where you break the number down into the digits

dizainemillier = nombre / 10000;
millier = (nombre - (10000 * dizainemillier)) / 1000;
//centaine = (nombre - 1000 * millier) - (10000 + dizainemillier) / 100;
centaine = ( nombre - (10000 * dizainemillier) - (1000 * millier)) / 100;
dizaine = (nombre - (centaine * 100) - (millier * 1000) - (dizainemillier * 10000)) / 10;
unite = nombre - (dizainemillier * 10000) - (millier * 1000) - (centaine * 100) - (dizaine * 10);

Thanks a lot !