Afficheurs 7 segments

Vous connaissez les afficheurs 7 segments ? Ou alors vous ne savez pas que ça s’appelle comme ça ? Il s’agit des petites lumières qui forment le chiffre 8 et qui sont de couleur rouge ou verte, la plupart du temps, mais peuvent aussi être bleus, blancs, etc. On en trouve beaucoup dans les radio-réveils, car ils servent principalement à afficher l’heure. Autre particularité, non seulement de pouvoir afficher des chiffres (0 à 9), ils peuvent également afficher certaines lettres de l’alphabet.

Matériel

Pour ce chapitre, vous aurez besoin de :

  • Un (et plus) afficheur 7 segments (évidemment)
  • 8 résistances de 330Ω330\Omega
  • Un (ou deux) décodeurs BCD 7 segments
  • Une carte Arduino ! Mais dans un premier temps on va d’abord bien saisir le truc avant de faire du code :)

Nous allons commencer par une découverte de l’afficheur, comment il fonctionne et comment le branche-t-on. Ensuite nous verrons comment l’utiliser avec la carte Arduino. Enfin, le chapitre suivant amènera un TP résumant les différentes parties vues.

Première approche : côté électronique

Un peu (beaucoup) d’électronique

Comme son nom l’indique, l’afficheur 7 segments possède… 7 segments. Mais un segment c’est quoi au juste ? Et bien c’est une portion de l’afficheur, qui est allumée ou éteinte pour réaliser l’affichage. Cette portion n’est en fait rien d’autre qu’une LED qui au lieu d’être ronde comme d’habitude est plate et encastré dans un boiter. On dénombre donc 8 portions en comptant le point de l’afficheur (mais il ne compte pas en tant que segment à part entière car il n’est pas toujours présent). Regardez à quoi ça ressemble :

Un afficheur 7 segments
Un afficheur 7 segments - (CC-BY-SA, Pengo)
Des LED, encore des LED

Et des LED, il y en a ! Entre 7 et 8 selon les modèles (c’est ce que je viens d’expliquer), voir beaucoup plus, mais on ne s’y attardera pas dessus. Voici un schéma vous présentant un modèle d’afficheur sans le point (qui au final est juste une LED supplémentaire rappelez-vous) :

Schéma de l'afficheur 7segments
Schéma de l’afficheur 7segments

Les interrupteurs a,b,c,d,e,f,g représentent les signaux pilotant chaque segments

Comme vous le voyez sur ce schéma, toutes les LED possèdent une broche commune, reliée entre elle. Selon que cette broche est la cathode ou l’anode on parlera d’afficheur à cathode commune ou… anode commune (vous suivez ?). Dans l’absolu, ils fonctionnent de la même façon, seule la manière de les brancher diffère (actif sur état bas ou sur état haut).

Cathode commune ou Anode commune

Dans le cas d’un afficheur à cathode commune, toutes les cathodes sont reliées entre elles en un seul point lui-même connecté à la masse. Ensuite, chaque anode de chaque segment sera reliée à une broche de signal. Pour allumer chaque segment, le signal devra être une tension positive. En effet, si le signal est à 0, il n’y a pas de différence de potentiel entre les deux broches de la LED et donc elle ne s’allumera pas ! Si nous sommes dans le cas d’une anode commune, les anodes de toutes les LED sont reliées entre elles en un seul point qui sera connecté à l’alimentation. Les cathodes elles seront reliées une par une aux broches de signal. En mettant une broche de signal à 0, le courant passera et le segment en question s’allumera. Si la broche de signal est à l’état haut, le potentiel est le même de chaque côté de la LED, donc elle est bloquée et ne s’allume pas ! Que l’afficheur soit à anode ou à cathode commune, on doit toujours prendre en compte qu’il faut ajouter une résistance de limitation de courant entre la broche isolée et la broche de signal. Traditionnellement, on prendra une résistance de 330Ω330\Omega pour une tension de +5V, mais cela se calcul (cf. chapitre 1, partie 2).

  • Si vous voulez augmenter la luminosité, il suffit de diminuer cette valeur.
  • Si au contraire vous voulez diminuer la luminosité, augmenter la résistance.
Choix de l’afficheur

Pour la rédaction j’ai fait le choix d’utiliser des afficheurs à anode commune et ce n’est pas anodin. En effet et on l’a vu jusqu’à maintenant, on branche les LED du +5V vers la broche de la carte Arduino. Ainsi, dans le cas d’un afficheur à anode commune, les LED seront branchés d’un côté au +5V, et de l’autre côté aux broches de signaux. Ainsi, pour allumer un segment on mettra la broche de signal à 0 et on l’éteindra en mettant le signal à 1. On a toujours fait comme ça depuis le début, ça ne vous posera donc aucun problème. ;)

Branchement "complet" de l’afficheur

Nous allons maintenant voir comment brancher l’afficheur à anode commune.

Présentation du boîtier

Les afficheurs 7 segments se présentent sur un boîtier de type DIP 10.* Le format DIP régit l’espacement entre les différentes broches du circuit intégré ainsi que d’autres contraintes (présence d’échangeur thermique etc…). Le chiffre 10 signifie qu’il possède 10 broches (5 de part et d’autre du boitier). Voici une représentation de ce dernier (à gauche) :

Boîtier du 7 segments
Boîtier du 7 segments - (source: datasheet)
7 segments
Dénomination des segments - (CC-BY-SA, h2g2bob)

Voici la signification des différentes broches :

  1. LED de la cathode E
  2. LED de la cathode D
  3. Anode commune des LED
  4. LED de la cathode C
  5. (facultatif) le point décimal.
  6. LED de la cathode B
  7. LED de la cathode A
  8. Anode commune des LED
  9. LED de la cathode F
  10. LED de la cathode G

Pour allumer un segment c’est très simple, il suffit de le relier à la masse !

Nous cherchons à allumer les LED de l’afficheur, il est donc impératif de ne pas oubliez les résistances de limitations de courant !

Exemple

Pour commencer, vous allez tout d’abord mettre l’afficheur à cheval sur la plaque d’essai (breadboard). Ensuite, trouvez la broche représentant l’anode commune et reliez la à la future colonne du +5V. Prochaine étape, mettre une résistance sur chaque broche de signal. Enfin, reliez quelques une de ces résistances à la masse. Si tous se passe bien, les segments reliés à la masse via leur résistance doivent s’allumer lorsque vous alimentez le circuit. Voici un exemple de branchement :

7 segments schéma
7 segments schéma
7 segments breadboard
7 segments breadboard

Dans cet exemple de montage, vous verrez que tous les segment de l’afficheur s’allument ! Vous pouvez modifier le montage en déconnectant quelques unes des résistance de la masse et afficher de nombreux caractères.

Pensez à couper l’alimentation lorsque vous changer des fils de place.

Les composants n’aiment pas forcément être (dé)branchés lorsqu’ils sont alimentés. Vous pourriez éventuellement leur causer des dommages.

Seulement 7 segments mais plein de caractère(s) !

Vous l’avez peut-être remarqué avec "l’exercice" précédent, un afficheurs 7 segments ne se limite pas à afficher juste des chiffres. Voici un tableau illustrant les caractères possibles et quels segments allumés. Attention, il est possible qu’il manque certains caractères !

Caractère

seg. A

seg. B

seg. C

seg. D

seg. E

seg. F

seg. G

0

x

x

x

x

x

x

1

x

x

2

x

x

x

x

x

3

x

x

x

x

x

4

x

x

x

x

5

x

x

x

x

x

6

x

x

x

x

x

x

7

x

x

x

8

x

x

x

x

x

x

x

9

x

x

x

x

x

x

A

x

x

x

x

x

x

b

x

x

x

x

x

C

x

x

x

x

d

x

x

x

x

x

E

x

x

x

x

x

F

x

x

x

x

H

x

x

x

x

x

I

x

x

J

x

x

x

x

L

x

x

x

o

x

x

x

x

P

x

x

x

x

x

S

x

x

x

x

x

t

x

x

x

U

x

x

x

x

x

u

x

x

x

x

x

°

x

x

x

x

Table: Caractères affichage avec un afficheur 7 segments

Aidez-vous de ce tableau lorsque vous aurez à coder l’affichage de caractères ! ;)

Afficher son premier chiffre !

Pour commencer, nous allons prendre en main un afficheur et lui faire s’afficher notre premier chiffre ! C’est assez simple et ne requiert qu’un programme très simple, mais un peu rébarbatif.

Schéma de connexion

Je vais reprendre le schéma précédent, mais je vais connecter chaque broche de l’afficheur à une sortie de la carte Arduino. Comme ceci :

7 segments schéma
7 segments schéma
Afficheur 7 segments montage
Afficheur 7 segments montage

Vous voyez donc que chaque LED de l’afficheur va être commandée séparément les unes des autres. Il n’y a rien de plus à faire, si ce n’est qu’à programmer…

Le programme

L’objectif du programme va être d’afficher un chiffre. Eh bien… c’est partit ! Quoi ?! Vous voulez de l’aide ? o_O Ben je vous ai déjà tout dit y’a plus qu’à faire. En plus vous avez un tableau avec lequel vous pouvez vous aider pour afficher votre chiffre. Cherchez, je vous donnerais la solution ensuite.

/* On assigne chaque LED à une broche de l'arduino */
const int A = 2;
const int B = 3;
const int C = 4;
const int D = 5;
const int E = 6;
const int F = 7;
const int G = 8;
// notez que l'on ne gère pas l'affichage du point,
// mais vous pouvez le rajouter si cela vous chante

void setup()
{
    // définition des broches en sortie
    pinMode(A, OUTPUT);
    pinMode(B, OUTPUT);
    pinMode(C, OUTPUT);
    pinMode(D, OUTPUT);
    pinMode(E, OUTPUT);
    pinMode(F, OUTPUT);
    pinMode(G, OUTPUT);

    // mise à l'état HAUT de ces sorties pour éteindre les LED de l'afficheur
    digitalWrite(A, HIGH);
    digitalWrite(B, HIGH);
    digitalWrite(C, HIGH);
    digitalWrite(D, HIGH);
    digitalWrite(E, HIGH);
    digitalWrite(F, HIGH);
    digitalWrite(G, HIGH);
}

void loop()
{
    // affichage du chiffre 5, d'après le tableau précédent
    digitalWrite(A, LOW);
    digitalWrite(B, HIGH);
    digitalWrite(C, LOW);
    digitalWrite(D, LOW);
    digitalWrite(E, HIGH);
    digitalWrite(F, LOW);
    digitalWrite(G, LOW);
}
Solution

Vous le voyez par vous-même, c’est un code hyper simple. Essayez de le bidouiller pour afficher des messages, par exemple, en utilisant les fonctions introduisant le temps. Ou bien compléter ce code pour afficher tous les chiffres, en fonction d’une variable définie au départ (ex: var = 1, affiche le chiffre 1 ; etc.).

Voici le résultat dans le simulateur interactif. N’hésitez pas à essayer de changer le chiffre affiché pour vérifier vos connaissances.

!(https://www.tinkercad.com/embed/7ug9Mh0NNuS)

Techniques d’affichage

Vous vous en doutez peut-être, lorsque l’on veut utiliser plusieurs afficheur il va nous falloir beaucoup de broches. Imaginons, nous voulons afficher un nombre entre 0 et 99, il nous faudra utiliser deux afficheurs avec 27=142*7 = 14 broches connectées sur la carte Arduino. Rappel : une carte Arduino UNO possède… 14 broches entrées/sorties classiques. Si on ne fais rien d’autre que d’utiliser les afficheurs, cela ne nous gène pas, cependant, il est fort probable que vous serez amener à utiliser d’autres entrées avec votre carte Arduino. Mais si on ne libère pas de place vous serez embêté.

Nous allons donc voir deux techniques qui, une fois cumulées, vont nous permettre d’utiliser seulement 4 broches pour obtenir le même résultat qu’avec 14 broches !

Les décodeurs "4 bits -> 7 segments"

La première technique que nous allons utiliser met en œuvre un circuit intégré. Vous vous souvenez quand je vous ai parlé de ces bêtes là ? Oui, c’est le même type que le microcontrôleur de la carte Arduino. Cependant, le circuit que nous allons utiliser ne fait pas autant de choses que celui sur votre carte Arduino.

Décodeur BCD -> 7 segments

C’est le nom du circuit que nous allons utiliser. Son rôle est simple. Vous vous souvenez des conversions ? Pour passer du binaire au décimal ? Et bien c’est le moment de vous en servir, donc si vous ne vous rappelez plus de ça, allez revoir un peu le cours. Je disais donc que son rôle est simple. Et vous le constaterez par vous même, il va s’agir de convertir du binaire codé sur 4 bits vers un "code" utilisé pour afficher les chiffres. Ce code correspond en quelque sorte au tableau précédemment évoqué.

Principe du décodeur

Sur un afficheur 7 segments, on peut représenter aisément les chiffres de 0 à 9. En informatique, pour représenter ces chiffres, il nous faut au maximum 4 bits. Comme vous êtes des experts et que vous avez bien lu la partie sur le binaire, vous n’avez pas de mal à le comprendre. (0000)2(0000)_2 fera (0)10(0)_{10} et (1111)2(1111)_2 fera (15)10(15)_{10} ou (F)16(F)_{16}. Pour faire 9 par exemple on utilisera les bits 1001. En partant de se constat, des ingénieurs ont inventé un composant au doux nom de "décodeur" ou "driver" 7 segments. Il reçoit sur 4 broches les 4 bits de la valeur à afficher, et sur 7 autres broches ils pilotent les segments pour afficher ladite valeur. Ajouter à cela une broche d’alimentation et une broche de masse on obtient 13 broches ! Et ce n’est pas fini. La plupart des circuits intégrés de type décodeur possède aussi une broche d’activation et une broche pour tester si tous les segments fonctionnent.

Choix du décodeur

Nous allons utiliser le composant nommé MC14543B comme exemple (un equivalent utilisable et trouvable facilement est le CD4543BE). Tout d’abord, ouvrez ce lien dans un nouvel onglet, il vous menera directement vers le pdf du décodeur :

Les datasheets se composent souvent de la même manière. On trouve tout d’abord un résumé des fonctions du produit puis un schéma de son boîtier. Dans notre cas, on voit qu’il est monté sur un DIP 16 (DIP : Dual Inline Package, en gros "boîtier avec deux lignes de broches"). Si l’on continue, on voit la table de vérité faisant le lien entre les signaux d’entrées (INPUT) et les sorties (OUTPUT). On voit ainsi plusieurs choses :

  • Si l’on met la broche Bl (Blank, n°7) à un, toutes les sorties passent à zéro. En effet, comme son nom l’indique cette broche sert à effacer l’afficheur. Si vous ne voulez pas l’utiliser il faut donc la connecter à la masse pour la désactiver ;
  • Les entrées A, B, C et D (broches 5,3,2 et 4 respectivement) sont actives à l’état HAUT. Les sorties elles sont actives à l’état BAS (pour piloter un afficheur à anode commune) OU HAUT selon l’état de la broche PH (6). C’est là un gros avantage de ce composant, il peut inverser la logique de la sortie, le rendant alors compatible avec des afficheurs à anode commune (broche PH à l’état 1) ou cathode commune (Ph = 0) ;
  • La broche BI (Blank Input, n°7) sert à inhiber les entrées. On ne s’en servira pas et donc on la mettra à l’état HAUT (+5V) ;
  • LD (n°1) sert à faire une mémoire de l’état des sorties, on ne s’en servira pas ici. Elle signifie "Latch Disable". En la mettant à 1 on désactive donc le "latch" (verrou) et nos entrées sont alors bien prises en considération ;
  • Enfin, les deux broches d’alimentation sont la 8 (GND/VSS, masse) et la 16 (VCC, +5V).

N’oubliez pas de mettre des résistances de limitations de courant entre chaque segment et la broche de signal du circuit!

Fonctionnement

C’est bien beau tout ça mais comment je lui dis au décodeur d’afficher le chiffre 5 par exemple ?

Il suffit de regarder le datasheet et sa table de vérité (c’est le tableau avec les entrées et les sorties). Ce que reçoit le décodeur sur ses entrées (A, B, C et D) définit les états de ses broches de sortie (a,b,c,d,e,f et g). C’est tout ! Donc, on va donner un code binaire sur 4 bits à notre décodeur et en fonction de ce code, le décodeur affichera le caractère voulu. En plus le fabricant est sympa, il met à disposition des notes d’applications à la page 6 pour bien brancher le composant :

Branchement du MC14543B
Branchement du MC14543B - (source: datasheet)

On voit alors qu’il suffit simplement de brancher la résistance entre le CI et les segments et s’assurer que PH à la bonne valeur et c’est tout ! En titre d’exercice afin de vous permettre de mieux comprendre, je vous propose de changer les états des entrées A, B, C et D du décodeur pour observer ce qu’il affiche. Après avoir réalisé votre schéma, regarder s’il correspond avec celui présent dans cette balise secrète. Cela vous évitera peut-être un mauvais branchement, qui sait ?

Montage 7 segments - Schéma
Montage 7 segments - Schéma
Montage 7 segments - Montage
Montage 7 segments - Montage

Voici le montage sur simulateur. Attention, ici le décodeur utilisé est un CD4511. Le fonctionnement reste similaire mais n’est compatible qu’avec un afficheur à anode commune.

!(https://www.tinkercad.com/embed/0tFVUjyMNHB)

L’affichage par alternance

La seconde technique est utilisée dans le cas où l’on veut faire un affichage avec plusieurs afficheurs. Elle utilise le phénomène de persistance rétinienne. Pour faire simple, c’est grâce à cela que le cinéma vous parait fluide. On change une image toutes les 40 ms et votre œil n’a pas le temps de le voir, donc les images semble s’enchainer sans transition. Bref… Ici, la même stratégie sera utilisée. On va allumer un afficheur un certain temps, puis nous allumerons l’autre en éteignant le premier. Cette action est assez simple à réaliser, mais nécessite l’emploi de deux broche supplémentaires, de quatre autres composants et d’un peu de code. Nous l’étudierons un petit peu plus tard, lorsque nous saurons géré un afficheur seul.

Utilisation du décodeur BCD

Nous y sommes, nous allons (enfin) utiliser la carte Arduino pour faire un affichage plus poussé qu’un unique afficheur. Pour cela, nous allons très simplement utiliser le montage précédent composé du décodeur BCD, de l’afficheur 7 segments et bien entendu des résistances de limitations de courant pour les LED de l’afficheur. Je vais vous montrer deux techniques qui peuvent être employées pour faire le programme.

Initialisation

Vous avez l’habitude maintenant, nous allons commencer par définir les différentes broches d’entrées/sorties. Pour débuter (et conformément au schéma), nous utiliserons seulement 4 broches, en sorties, correspondantes aux entrées du décodeur 7 segments. Voici le code pouvant traduire cette explication :

const int bit_A = 2;
const int bit_B = 3;
const int bit_C = 4;
const int bit_D = 5;

void setup()
{
    // on met les broches en sorties
    pinMode(bit_A, OUTPUT);
    pinMode(bit_B, OUTPUT);
    pinMode(bit_C, OUTPUT);
    pinMode(bit_D, OUTPUT);

    // on commence par écrire le chiffre 0, donc toutes les sorites à l'état bas
    digitalWrite(bit_A, LOW);
    digitalWrite(bit_B, LOW);
    digitalWrite(bit_C, LOW);
    digitalWrite(bit_D, LOW);
}
Initialisation des broches

Ce code permet juste de déclarer les quatre broches à utiliser, puis les affectes en sorties. On les met ensuite toutes les quatre à zéro. Maintenant que l’afficheur est prêt, nous allons pouvoir commencer à afficher un chiffre !

Programme principal

Si tout se passe bien, en ayant la boucle vide pour l’instant vous devriez voir un superbe 0 sur votre afficheur. Nous allons maintenant mettre en place un petit programme pour afficher les nombres de 0 à 9 en les incrémentant (à partir de 0) toutes les secondes. C’est donc un compteur. Pour cela, on va utiliser une boucle, qui comptera de 0 à 9. Dans cette boucle, on exécutera appellera la fonction afficher() qui s’occupera donc de l’affichage (belle démonstration de ce qui est une évidence :P ^^ ).

void loop()
{
    char i=0; // variable "compteur"
    for(i=0; i<10; i++)
    {
        afficher(i); // on appel la fonction d'affichage
        delay(1000); // on attend 1 seconde
    }
}
Le compteur
Fonction d’affichage

Nous touchons maintenant au but ! Il ne nous reste plus qu’à réaliser la fonction d’affichage pour pouvoir convertir notre variable en chiffre sur l’afficheur. Pour cela, il existe différentes solutions. Nous allons en voir ici une qui est assez simple à mettre en œuvre mais qui nécessite de bien être comprise. Dans cette méthode, on va faire des opérations mathématiques (tout de suite c’est moins drôle :lol: ) successives pour déterminer quels bits mettre à l’état haut. Rappelez-vous, nous avons quatre broches à notre disposition, avec chacune un poids différent (8, 4, 2 et 1). En combinant ces différentes broches ont peu obtenir n’importe quel nombre de 0 à 15. Voici une démarche mathématique envisageable :

Organigramme décodeur 7 segments
Organigramme décodeur 7 segments

On peut coder cette méthode de manière assez simple et directe, en suivant cet organigramme :

// fonction écrivant sur un seul afficheur
void afficher(char chiffre)
{
    // on met à zéro tout les bits du décodeur
    digitalWrite(bit_A, LOW);
    digitalWrite(bit_B, LOW);
    digitalWrite(bit_C, LOW);
    digitalWrite(bit_D, LOW);

    // On allume les bits nécessaires
    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;
    }
}
Implémentation de l’affichage

Quelques explications s’imposent… Le code gérant l’affichage réside sur les valeurs binaires des chiffres. Rappelons les valeurs binaires des chiffres :

Chiffre

DCBA

0

(0000)2(0000)_2

1

(0001)2(0001)_2

2

(0010)2(0010)_2

3

(0011)2(0011)_2

4

(0100)2(0100)_2

5

(0101)2(0101)_2

6

(0110)2(0110)_2

7

(0111)2(0111)_2

8

(1000)2(1000)_2

9

(1001)2(1001)_2

Table: La représentation binaires des chiffres

D’après ce tableau, si on veut le chiffre 8, on doit allumer le segment D, car 8 s’écrit (1000)2(1000)_2 ayant pour segment respectif DCBA. Soit D=1, C=0, B=0 et A=0. En suivant cette logique, on arrive à déterminer les entrées du décodeur qui sont à mettre à l’état HAUT ou BAS. D’une manière plus lourde, on aurait pu écrire un code ressemblant à ça :

// fonction écrivant sur un seul afficheur
void afficher(char chiffre)
{
    switch(chiffre)
    {
    case 0 :
        digitalWrite(bit_A, LOW);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, LOW);
        break;
    case 1 :
        digitalWrite(bit_A, HIGH);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, LOW);
        break;
    case 2 :
        digitalWrite(bit_A, LOW);
        digitalWrite(bit_B, HIGH);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, LOW);
        break;
    case 3 :
        digitalWrite(bit_A, HIGH);
        digitalWrite(bit_B, HIGH);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, LOW);
        break;
    case 4 :
        digitalWrite(bit_A, LOW);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, HIGH);
        digitalWrite(bit_D, LOW);
        break;
    case 5 :
        digitalWrite(bit_A, HIGH);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, HIGH);
        digitalWrite(bit_D, LOW);
        break;
    case 6 :
        digitalWrite(bit_A, LOW);
        digitalWrite(bit_B, HIGH);
        digitalWrite(bit_C, HIGH);
        digitalWrite(bit_D, LOW);
        break;
    case 7 :
        digitalWrite(bit_A, HIGH);
        digitalWrite(bit_B, HIGH);
        digitalWrite(bit_C, HIGH);
        digitalWrite(bit_D, LOW);
        break;
    case 8 :
        digitalWrite(bit_A, LOW);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, HIGH);
        break;
    case 9 :
        digitalWrite(bit_A, HIGH);
        digitalWrite(bit_B, LOW);
        digitalWrite(bit_C, LOW);
        digitalWrite(bit_D, HIGH);
        break;
    }
}
L’affichage DCBA version longue

Mais, c’est bien trop lourd à écrire. Enfin c’est vous qui voyez. ;)

Utiliser plusieurs afficheurs

Maintenant que nous avons affiché un chiffre sur un seul afficheur, nous allons pouvoir apprendre à en utiliser plusieurs (avec un minimum de composants en plus !). Comme expliqué précédemment, la méthode employée ici va reposer sur le principe de la persistance rétinienne, qui donnera l’impression que les deux afficheurs fonctionnent en même temps.

Problématique

Nous souhaiterions utiliser deux afficheurs, mais nous ne disposons que de seulement 6 broches sur notre Arduino, le reste des broches étant utilisé pour une autre application. Pour réduire le nombre de broches, on peut d’ores et déjà utiliser un décodeur BCD, ce qui nous ferait 4 broches par afficheurs, soit 8 broches au total. Bon, ce n’est toujours pas ce que l’on veut. Et si on connectait les deux afficheurs ensemble, en parallèle, sur les sorties du décodeur ? Oui mais dans ce cas, on ne pourrait pas afficher des chiffres différents sur chaque afficheur. Tout à l’heure, je vous ai parlé de commutation. Oui, la seule solution qui soit envisageable est d’allumer un afficheur et d’éteindre l’autre tout en les connectant ensemble sur le même décodeur. Ainsi un afficheur s’allume, il affiche le chiffre voulu, puis il s’éteint pour que l’autre puisse s’allumer à son tour. Cette opération est en fait un clignotement de chaque afficheur par alternance.

Un peu d’électronique…

Pour faire commuter nos deux afficheurs, vous allez avoir besoin d’un nouveau composant, j’ai nommé : le transistor !

Transistor ? J’ai entendu dire qu’il y en avait plusieurs milliards dans nos ordinateurs ?

Et c’est tout à fait vrai. Des transistors, il en existe de différents types et pour différentes applications : amplification de courant/tension, commutation, etc. répartis dans plusieurs familles.

Le transistor bipolaire : présentation

Je le disais, je ne vais pas faire de détails. On va voir comment fonctionne un transistor bipolaire selon les besoins de notre application, à savoir, faire commuter les afficheurs. Un transistor, cela ressemble à ça :

Photo d'un transistor
Photo d’un transistor - (CC-BY-SA, Marvelshine)

Pour notre application, nous allons utiliser des transistors bipolaires. Je vais vous expliquer comment cela fonctionne. Déjà, vous pouvez observer qu’un transistor possède trois pattes. Cela n’est pas de la moindre importance, au contraire il s’agit là d’une chose essentielle ! En fait, le transistor bipolaire à une broche d’entrée (collecteur), une broche de sortie (émetteur) et une broche de commande (base). Son symbole est le suivant :

Symbole du transistor bipôlaire
Symbole du transistor bipôlaire

Ce symbole est celui d’un transistor bipolaire de type NPN.

Il en existe qui sont de type PNP, mais ils sont beaucoup moins utilisés que les NPN. Quoi qu’il en soit, nous n’utiliserons que des transistors NPN dans ce chapitre.

Fonctionnement en commutation du transistor bipolaire

Pour faire simple, le transistor bipolaire NPN (c’est la dernière fois que je précise ce point) est un interrupteur commandé en courant.

Ceci est une présentation très vulgarisée et simplifiée sur le transistor pour l’utilisation que nous en ferons ici. Les usages et possibilités des transistors sont très nombreux et ils mériteraient un grand livre à eux seuls ! Si vous voulez plus d’informations, rendez-vous sur le cours sur l’électronique ou approfondissez en cherchant des tutoriels sur le web. ;)

C’est tout ce qu’il faut savoir, pour ce qui est du fonctionnement. Après, on va voir ensemble comment l’utiliser et sans le faire griller ! ^^

Utilisation générale

On peut utiliser notre transistor de deux manières différentes (pour notre application toujours, mais on peut bien évidemment utiliser le transistor avec beaucoup plus de flexibilités). A commencer par le câblage :

Câblage du transistor en commutation
Câblage du transistor en commutation

Dans le cas présent, le collecteur (qui est l’entrée du transistor) se trouve être après l’ampoule, elle-même connectée à l’alimentation. L’émetteur (broche où il y a la flèche) est relié à la masse du montage. Cette disposition est "universelle", on ne peut pas inverser le sens de ces broches et mettre le collecteur à la place de l’émetteur et vice versa. Sans quoi, le montage ne fonctionnerait pas. Pour le moment, l’ampoule est éteinte car le transistor ne conduit pas. On dit qu’il est bloqué et empêche donc le courant ICI_C de circuler à travers l’ampoule. Soit IC=0I_C = 0 car IB=0I_B = 0. A présent, appuyons sur l’interrupteur :

Allumage de la lampe
Allumage de la lampe

Que se passe-t-il ? Eh bien la base du transistor, qui était jusqu’à présent "en l’air", est parcourue par un courant électrique. Cette cause à pour conséquence de rendre le transistor passant ou saturé et permet au courant de s’établir à travers l’ampoule. Soit IC0I_C \ne 0 car IB0I_B \ne 0.

La résistance sur la base du transistor permet de le protéger des courants trop forts. Plus la résistance est de faible valeur, plus l’ampoule sera lumineuse. A l’inverse, une résistance trop forte sur la base du transistor pourra l’empêcher de conduire et de faire s’allumer l’ampoule. Rassurez_vous, je vous donnerais les valeurs de résistances à utiliser. ;)

Utilisation avec nos afficheurs

Voyons un peu comment on va pouvoir utiliser ce transistor avec notre Arduino. La carte Arduino est en fait le générateur de tension (schéma précédent) du montage. Elle va définir si sa sortie est de 0V (transistor bloqué) ou de 5V (transistor saturé). Ainsi, on va pouvoir allumer ou éteindre les afficheurs. Voilà le modèle équivalent de la carte Arduino et de la commande de l’afficheur :

Montage de la commande
Montage de la commande

La carte Arduino va soit mettre à la masse la base du transistor, soit la mettre à +5V. Dans le premier cas, il sera bloqué et l’afficheur sera éteint, dans le second il sera saturé et l’afficheur allumé. Il en est de même pour chaque broche de l’afficheur. Elles seront au +5V ou à la masse selon la configuration que l’on aura définie dans le programme.

Schéma final

Et comme vous l’attendez surement depuis tout à l’heure, voici le schéma tant attendu (nous verrons juste après comment programmer ce nouveau montage) !

2*7 segments - Schéma
2*7 segments - Schéma
2*7 segments - Montage
2*7 segments - Montage
Quelques détails techniques
  • Dans notre cas (et je vous passe les détails vraiment techniques et calculatoires), la résistance sur la base du transistor sera de 2.2kΩ2.2k\Omega (si vous n’avez pas cette valeur, elle pourra être de 3.3kΩ3.3k\Omega, ou encore de 3.9kΩ3.9k\Omega, voir même de 4.7kΩ4.7k\Omega).
  • Les transistors seront des transistors bipolaires NPN de référence 2N2222, ou bien un équivalent qui est le BC547. Il en faudra deux donc.
  • Le décodeur BCD est le même que précédemment (ou équivalent).

Et avec tout ça, on est prêt pour programmer ! :)

…et de programmation

Nous utilisons deux nouvelles broches servant à piloter chacun des interrupteurs (transistors). Chacune de ces broches doivent donc être déclarées en global (pour son numéro) puis régler comme sortie. Ensuite, il ne vous restera plus qu’à alimenter chacun des transistors au bon moment pour allumer l’afficheur souhaité. En synchronisant l’allumage avec la valeur envoyé au décodeur, vous afficherez les nombres souhaités comme bon vous semble. Voici un exemple de code complet, de la fonction setup() jusqu’à la fonction d’affichage. Ce code est commenté et vous ne devriez donc avoir aucun mal à le comprendre ! Ce programme est un compteur sur 2 segments, il compte donc de 0 à 99 et recommence au début dès qu’il a atteint 99. La vidéo se trouve juste après ce code.

// définition des broches du décodeur 7 segments
// (vous pouvez changer les numéros si vous voulez)
const int bit_A = 2;
const int bit_B = 3;
const int bit_C = 4;
const int bit_D = 5;

// définitions des broches des transistors pour chaque afficheur
const int alim_dizaine = 6; // les dizaines
const int alim_unite = 7;   // les unites

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(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(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
}

void loop() // fonction principale
{
    // boucle qui permet de compter de 0 à 99 (= 100 valeurs)
    for(char i = 0; i<100; i++)
    {
        // appel de la fonction affichage avec envoi du nombre à afficher
        afficher_nombre(i);
    }
}

// fonction permettant d'afficher un nombre sur deux afficheurs
void afficher_nombre(char nombre)
{
    long temps; // variable utilisée pour savoir le temps écoulé...
    char unite = 0, dizaine = 0; // variable pour chaque afficheur

    if(nombre > 9) // si le nombre reçu dépasse 9
    {
        dizaine = nombre / 10; // on récupère les dizaines
    }

    unite = nombre - (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 millisecondes
    // permet donc de pouvoir lire le nombre affiché
    while((millis()-temps) < 500)
    {
        // on affiche le nombre

        // d'abord les dizaines pendant 10 ms

        // le transistor de l'afficheur des dizaines est saturé,
        // donc l'afficheur est allumé
        digitalWrite(alim_dizaine, HIGH);
        // on appel la fonction qui permet d'afficher le chiffre dizaine
        afficher(dizaine);
        // l'autre transistor est bloqué et l'afficheur éteint
        digitalWrite(alim_unite, LOW);
        delay(10);

        // puis les unités pendant 10 ms

        // on éteint le transistor allumé
        digitalWrite(alim_dizaine, LOW);
        // on appel la fonction qui permet d'afficher le chiffre unité
        afficher(unite);
        // et on allume l'autre
        digitalWrite(alim_unite, HIGH);
        delay(10);
    }
}

// fonction écrivant sur un seul afficheur
// on utilise le même principe que vu plus haut
void afficher(char 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;
    }
}
Le compteur de 0 à 99

Voilà donc la vidéo présentant le résultat final :

Et la même chose sur simulateur interactif. Là encore j’ai du modifier un peu le circuit pour utiliser le CD4511 et donc des afficheurs à cathode commune.

!(https://www.tinkercad.com/embed/6hNGcB1uLcF)

Contraintes des évènements

Comme vous l’avez vu juste avant, afficher de manière alternative n’est pas trop difficile. Cependant, vous avez surement remarqué, nous avons utilisé des fonctions bloquantes (delay). Si jamais un évènement devait arriver pendant ce temps, nous aurions beaucoup de chance de le rater car il pourrait arriver "pendant" un délai d’attente pour l’affichage. Pour parer à cela, je vais maintenant vous expliquer une autre méthode, préférable, pour faire de l’affichage. Elle s’appuiera sur l’utilisation de la fonction millis(), qui nous permettra de générer une boucle de rafraîchissement de l’affichage. Voici un organigramme qui explique le principe :

organigramme de rafraichissement
organigramme de rafraichissement

Comme vous pouvez le voir, il n’y a plus de fonction qui "attend". Tout se passe de manière continue, sans qu’il n’y ai jamais de pause. Ainsi, aucun évènement ne sera raté (en théorie, un évènement trèèèèèès rapide pourra toujours passer inaperçu). Voici un exemple de programmation de la boucle principal (suivi de ses fonctions annexes) :

// définition des broches du décodeur 7 segments
// (vous pouvez changer les numéros si vous voulez)
const int bit_A = 2;
const int bit_B = 3;
const int bit_C = 4;
const int bit_D = 5;

// définitions des broches des transistors pour chaque afficheur
const int alim_dizaine = 6; // les dizaines
const int alim_unite = 7;   // les unites

// variable pour l'affichage
bool afficheur = false;
long tempsaffichage = 0;
long tempscomptage = 0;
int valeur = 0;

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(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(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
}

void loop()
{
    // gestion du rafraichissement
    // si ça fait plus de 10 ms qu'on affiche,
    // on change de 7 segments (alternance unité <-> dizaine)
    if((millis() - tempsaffichage) > 250)
    {
        // on inverse la valeur de "afficheur"
        // pour changer d'afficheur (unité ou dizaine)
        afficheur = !afficheur;
        // on affiche la valeur sur l'afficheur
        // afficheur : true->dizaines, false->unités
        afficher_nombre(valeur, afficheur);
        tempsaffichage = millis(); // on met à jour le temps
    }

    // ici, on peut traiter les évènements (bouton...)
    // Par exemple on incrément le compteur toutes les secondes
    if((millis() - tempscomptage) > 1000)
    {
    	valeur++;
        tempscomptage = millis(); // on met à jour le temps
    }
}

// fonction permettant d'afficher un nombre
// elle affiche soit les dizaines soit les unités
void afficher_nombre(char nombre, bool afficheur)
{
    char unite = 0, dizaine = 0;
    if(nombre > 9)
        dizaine = nombre / 10; // on recupere les dizaines
    unite = nombre - (dizaine*10); // on recupere les unités

    // si "
    if(afficheur)
    {
        // on affiche les dizaines
        digitalWrite(alim_unite, LOW);
        afficher(dizaine);
        digitalWrite(alim_dizaine, HIGH);
    }
    else // égal à : else if(!afficheur)
    {
        // on affiche les unités
        digitalWrite(alim_dizaine, LOW);
        afficher(unite);
        digitalWrite(alim_unite, HIGH);
    }
}

// fonction écrivant sur un seul afficheur
void afficher(char 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;
    }
}
L’affichage de deux chiffres en utilisant millis

Si vous voulez tester le phénomène de persistance rétinienne, vous pouvez changer le temps de la boucle de rafraichissement (ligne 9). Si vous l’augmenter, vous commencerez à vois les afficheurs clignoter. En mettant une valeur d’un peu moins de une seconde vous verrez les afficheurs s’illuminer l’un après l’autre.

Voici l’exemple avec le simulateur (volontairement lent pour voir l’affichage en alternance) :

!(https://www.tinkercad.com/embed/e96lqNLGXel)


Ce chapitre vous a appris à utiliser un nouveau moyen pour afficher des informations avec votre carte Arduino. L’afficheur peut sembler peu utilisé mais en fait de nombreuses applications existe ! (chronomètre, réveil, horloge, compteur de passage, afficheur de score, etc.). Par exemple, il pourra vous servir pour déboguer votre code et afficher la valeur des variables souhaitées…