1

I'm trying to use an Arduino Mega 2560 to use 7-segment displays, 6 displays... I use 3 CD4543B to pilot the 6 displays.

It works very well for 4 displays as you can see in this video.

But when I want to use the same circuit for 5 or 6 displays, there is some bug as you can see on this video for 5 displays.

Here is the code that works fine for 4 displays:

//définition des broches du premier décodeur 
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//définition du brochage du deuxieme decodeur 
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//définition du brochage du 3ième décodeur
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;
//définition des broches des transistors

const int alim_millier=3;
const int alim_centaine=4;
const int alim_dizaine=5;
const int alim_unite=6;

void setup() {
  //les broches sont toutes des sorties
  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_millier,OUTPUT);
  pinMode(alim_centaine,OUTPUT);
  pinMode(alim_dizaine,OUTPUT);
  pinMode(alim_unite,OUTPUT);
  //les broches sont toutes mises à l'état bas
  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_millier,LOW);
  digitalWrite(alim_centaine,LOW);
  digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);
}

void loop() {
  //fonction principale
  for(int i=0; i<10000; i++) {
    //boucle qui permet de compter de0 à9999(=10000 valeurs)
    afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
  }
}

//fonction permettant d'afficherun nombre sur quatre afficheurs
void afficher_nombre(int nombre) {
  long temps;//variable utilisée poursavoir le temps écoulé
  int unite=0,dizaine=0,centaine=0, millier=0;//variable pour chaque afficheur
  millier=nombre/1000;//on récupère les milliers
  centaine=(nombre-1000*millier)/100;//on récupère les centaines
  dizaine=(nombre-(centaine*100)-(millier*1000))/10;//on récupère les dizaines
  unite=nombre-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités
  temps=millis();//on récupère le temps courant
  //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
  //permet donc de pouvoir lire le nombre affiché
  while((millis()-temps)<500) {
    //on affiche le nombre
    //d'abord les milliers pendant 5ms
    digitalWrite(alim_millier,HIGH);
    afficher_CD(millier);//on appelle la fonction qui permet d'afficher le chiffre millier
    digitalWrite(alim_centaine,LOW);
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor est bloqué
    delay(5);
    //d'abord les centaines pendant 5ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
    afficher_CM(centaine);//on appelle la fonction qui permet d'afficher le chiffre centaine  
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor est bloqué
    delay(5);
    //ensuite les dizaines pendant 5 ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);// transistor est bloqué
    digitalWrite(alim_dizaine,HIGH);//transistor saturé
    afficher_CM(dizaine);
    digitalWrite(alim_unite,LOW);//transistor bloqué
    delay(5);
    //on affiche les unités 5 ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,LOW);//transistor bloqué
    digitalWrite(alim_unite,HIGH);//transistor saturé
    afficher_UD(unite);
    delay(5);
  }
}

//fonction écrivant sur les premiers afficheurs
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;
  }
}

//fonction écrivant sur le second afficheur
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;
  }
}

And here the code for 5 displays with "bugs" :

//définition des broches du premier décodeur 
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//définition du brochage du deuxieme decodeur 
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//définition du brochage du 3ième décodeur
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;
//définition des broches des transistors
const int alim_dm= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;
void setup() {
  //les broches sont toutes des sorties
  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_dm,OUTPUT);
  pinMode(alim_millier,OUTPUT);
  pinMode(alim_centaine,OUTPUT);
  pinMode(alim_dizaine,OUTPUT);
  pinMode(alim_unite,OUTPUT);
  //les broches sont toutes mises à l'état bas
  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_dm,LOW);
  digitalWrite(alim_millier,LOW);
  digitalWrite(alim_centaine,LOW);
  digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);  
}

void loop() {
  //fonction principale
  for(int i=0;i<100000;i++)//boucle qui permet de compter de0 à 99999(=100000 valeurs) {
    afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
  }
}

//fonction permettant d'afficherun nombre sur quatre afficheurs
void afficher_nombre(int nombre) {
  long temps;//variable utilisée poursavoir le temps écoulé
  int unite=0,dizaine=0,centaine=0, millier=0, dm=0;//variable pour chaque afficheur
  dm=nombre/10000;//on récupère les dm
  millier=(nombre-(10000*dm))/1000;//on récupère les milliers
  centaine=(nombre-1000*millier)-(10000+dm)/100;//on récupère les centaines
  dizaine=(nombre-(centaine*100)-(millier*1000)-(dm*10000))/10;//on récupère les dizaines
  unite=nombre-(dm*10000)-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités

  temps=millis();//on récupère le temps courant
  //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
  //permet donc de pouvoir lire le nombre affiché
  while((millis()-temps)<500) {
    //on affiche le nombre
    //d'abord les dms pendant 5ms
    digitalWrite(alim_dm,HIGH);
    afficher_CD(dm);//on appelle la fonction qui permet d'afficher le chiffre dm
    digitalWrite(alim_millier,LOW);//le transistor bloqué
    digitalWrite(alim_centaine,LOW);//le transistor est bloqué
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor bloqué
    delay(10);
    //d'abord les millier pendant 5ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
    afficher_CM(millier);//on appelle la fonction qui permet d'afficher le chiffre centaine  
    digitalWrite(alim_centaine,LOW);//le transistor est bloqué
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor bloqué
    delay(10);
    //ensuite les centaine pendant 5 ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,HIGH);// transistor est bloqué
    afficher_CM(centaine);
    digitalWrite(alim_dizaine,LOW);//transistor saturé
    digitalWrite(alim_unite,LOW);//transistor bloqué
    delay(10);
    //on affiche les dizaines 5 ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,HIGH);//transistor bloqué
    afficher_UD(dizaine);
    digitalWrite(alim_unite,LOW);//transistor saturé
    delay(10);
    //on affiche les unités
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,LOW);//transistor bloqué
    digitalWrite(alim_unite,HIGH);//transistor saturé
    afficher_UD(unite);
    delay(10);
  }
}

//fonction écrivant sur les premiers afficheurs
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;
  }
}

//fonction écrivant sur le second afficheur
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;
  }
}
//Fin du programme

I've been trying for weeks to understand the problem. All displays work fine, and if I adapt the code for 4 displays and try to use any 4 of the 6 displays it works fine (I have tried a combination such as displays: 1, 2, 3, 4 or 2, 3, 4, 5 or 3, 4, 5, 6 or 1, 2, 5, 6, everything works).

Thanks to a conversation on the Arduino forum, I also tried this code for 5 displays but I still have the same problem:

//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);
}

Any clue is very welcome! Thanks!

2 Answers 2

1

I think it's because I use int and I should use long to avoid overflow... for the number I want to display:

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

should be :

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

And also a parentheses problem solved thanks to cattledog on this forum

2
  • on Arduino int is 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 while long is 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647
    – Martynas
    Commented May 15, 2017 at 18:17
  • exactly :) ! I'm use to code for 64bits or 32bits on computer, and forgot that arduino is 16bits....
    – Dadep
    Commented May 15, 2017 at 18:34
0

Here is the code that works fine for 4 displays:

both code pieces suffer from the use of "delay()".

here is what I used - https://dannyelectronics.wordpress.com/2017/06/30/a-more-flexible-driver-for-7-segment-leds/

it is written so the leds can be driven by individual pins so porting to arduino requires no change to the source code - just a few macros to remap the IO operations.

also running it from a timer isr is the (only) way to go.

edit: here is to show how the code above gets to work here. I expanded it to cover 8 digits but only the first 6 digits effective. three macros are all it takes to repurpose it for arduino.

displaying a fixed "123456".

enter image description here

all the user code does is to dump the content to be displayed into the display buffer and the display routine, led_display() takes care of the rest.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.