Les ports ARDUINO: Gestion d'un afficheur 7 segments

publication: 8 juin 2019 / mis à jour 11 juin 2019

Read this page in english

 


Nous avions déjà traité un exemple de gestion simultanée des pins dans l'article intitulé Les ports ARDUINO: chenillard K2000.

Dans cet article, nous allons notamment dévoiler la méthode dite de développement: bottom-up , la soi-disant approche bottom-up. Cette méthode va dans les détails pour construire le des outils pour une gestion optimale des composants.

L'afficheur 7 segments

Voici les caractéristiques de l'afficheur 7 segments. Ce composant dispose de 10 bornes physiques, numérotées de 1 à 10:

L'afficheur 7 segments

Sur cette fiche technique, le point décimal est marqué DP. Ce point doit être situé en bas à droite pour que l'afficheur 7 segments soit correctement orienté. Les bornes 3 et 8 correspondent à la cathode commune. Placez l'afficheur sur la plaque d'essai et reliez la borne 8 à la masse via une résistance d'environ 300 Ohms. Schéma:

Installation afficheur 7 segments sur plaque d'essais

Insérez provisoiremet un fil de liaison au 5V de la carte ARDUINO (fil rouge sur le schéma). Avec l'autre extrémité de ce fil de liaison, testez les connecteurs 1, 2, 4, 5, 6, 7 9 et 10. Si tout se passe bien, chaque segment doit s'allumer selon les données techniques de l'afficheur 7 segments.

Nous venons de franchir avec succès la toute première étape de notre processus de déveoppement, dite bottom-up. Dans cette démarche, nous avons compris et maitrisé le fonctionnement d'un composant, ici l'afficheur 7 segments.

Le PORT B en détail

Toujours dans cette même démarche bottom-up, nous allons maintenant voir de manière détaillée la connexion physique du PORT B. Sur la carte ARDUINO MEGA 2560, C'est un port qui gère huit pins, numérotés 19 à 26. Pour la carte MEGA 2560, la numérotation de ces pins est décrite ici:
Carte des connecteurs sur ARDUINO MEGA 2560.

Voici le détail des pins 19 à 23 qui sont gérés dans la partie basse à gauche sur la carte MEGA 2560:

détail des pins 19 à 22

En jaune, le numéro du bit dans le port B: PB0 = Port B bit 0, PB1 = Port B bit 1, etc. La numérotation des bits commence toujours à zéro. En gris, en face du numéro de bit pdans le port, le numéro du pin: PB0 -> pin 19, PB1 -> pin 20. Pour chaque pin 19 à 22, le numéro du connecteur physique sur la carte ARDUNO MEGA:
  PB0 -> pin 19 -> connecteur 53
  PB1 -> pin 20 -> connecteur 52
  PB2 -> pin 21 -> connecteur 51
  PB3 -> pin 22 -> connecteur 50
...Ah! Mais où sont les bits 4 à 7 du port B?

Les bits 4 à 7 du port B se retrouvent sur la partie haute, à droite de la carte MEGA 2560:

détail des pins 23 à 26

Pour chaque pin 23 à 26, le numéro du connecteur physique sur la carte ARDUNO:
  PB4 -> pin 23 -> connecteur 10
  PB5 -> pin 24 -> connecteur 11
  PB6 -> pin 25 -> connecteur 12
  PB7 -> pin 26 -> connecteur 13
...Ah oui! Donc les bits du PORT B sont en deux endroits différents!

Attention: ne pas confondre numéros de connecteurs physiques et numéros de pins

Sur les cartes ARDUINO, les bornes sont marquées, certaines par numéros, d'autres par leur fonction, exemple: GND, TX, RX, 5V, etc...

La correspondance pour associer les numéros de pins aux bornes physiques se trouve dans ce document:
 Carte des connecteurs sur ARDUINO DUE
 Carte des connecteurs sur ARDUINO MEGA 2560
 Carte des connecteurs sur ARDUINO MICRO
 Carte des connecteurs sur ARDUINO NANO
 Carte des connecteurs sur ARDUINO UNO
 Carte des connecteurs sur ARDUINO YUN

A titre d'exemple, la led '13' qui est reliée sur la carte ARDUINO MEGA avec la borne physique 13 est en rapport avec le PIN 26. Dans tous nos textes, le terme "pin" désignera systématiquement le code PIN XX tel que référencé dans les documents techniques des cartes ARDUINO. La mention d'une borne physique se fera avec le terme 'borne'. Exemple:

  PIN 19 (borne 53) (avant dernière borne, tout en bas, à gauche sur une carte ARDUINO MEGA 2560)

Pour en savoir plus sur la manière de programmer les connecteurs des différentes cartes ARDUINO:
Comprendre les connecteurs des cartes ARDUINO

En FORTH, nous allons créer les mots nécessaires et suffisants pour gérer ce port B:

37 constant PORTB 
36 constant DDRB 
\ 35 constant PINB 

Le mot PORTB correspond à l'adresse du registre PORTB. C'est dans ce registre que nous allons injecter la valeur binaire permettant d'allumer les segments de l'afficheur 7 segments.

Le mot DDRB correspond à l'adresse du registre DDR du port B. Dans ce registre, nous allons indiquer le sens des données gérées par le PORT B:

: initDDRB ( ---) 
    %11111111 DDRB c!   \ positionne tous bits PORTB en sortie 
    ; 

Câblage de l'afficheur 7 segments

Ceci est la partie la plus délicate de la gestion de l'afficheur 7 segments. On va initialiser le registre DDRB et activer les bits du port B:

initDDRB 
%11111111 PORTB c! 

Il faut connecter physiquement notre afficheur comme suit. Au fur et à mesure que l'on procède au raccordement physique des connecteurs de la carte ARDUINO avec ceux de l'afficheur 7 segments, chaque segment d'oit s'allumer si vous respectez scrupuleusement ces connexions:
  PB0 -> pin 19 -> connecteur 53 -> borne 1 -> segment E
  PB1 -> pin 20 -> connecteur 52 -> borne 2 -> segment D
  PB2 -> pin 21 -> connecteur 51 -> borne 4 -> segment C
  PB3 -> pin 22 -> connecteur 50 -> borne 6 -> segment B
  PB4 -> pin 23 -> connecteur 10 -> borne 7 -> segment A
  PB5 -> pin 24 -> connecteur 11 -> borne 9 -> segment F
  PB6 -> pin 25 -> connecteur 12 -> borne 10 -> segment G
  PB7 -> pin 26 -> connecteur 13 -> borne 5 -> segment DP

Chaque segment doit s'allumer au fur et à mesure que vous montez les connexions physiques entre la carte ARDUINO et l'afficheur 7 segments:

câblage complet de l'afficheur 7 segments

Affichage des chiffres 0 à 9

Nos segments de l'afficheur 7 segments sont tous câblés à la carte ARDUINO. Voyons maintenant comment afficher des chiffres. Pour celà, on va définir ce tableau:

chiffre PB7
DP
PB6
G
PB5
F
PB4
A
PB3
B
PB2
C
PB1
D
PB0
E
0 00111111
1 00001100
2 01011011
3 01011110
4 01101100
5 01110110
6 01110111
7 00011100
8 01111111
9 01111110

En début de ligne, le chiffre à afficher. Ensuite, les valeurs 0 ou 1 pour chaque segment à activer. Sur la première ligne du chiffre 0 à afficher, les huit bits PB0 à PB7 à activer. On peut tester immédiatement ces bits en les regroupant en une seule valeur binaire:

%00111111 PORTB c!

L'afficheur 7 segments doit afficher le chiffre 0. On éteint l'afficheur:

$00 PORTB c! 

Pour afficher les chiffres de 0 à 9:

: testDigits  ( ---) 
    %00111111 PORTB c! 500 ms   \ affiche 0 
    %00001100 PORTB c! 500 ms   \ affiche 1 
    %01011011 PORTB c! 500 ms   \ affiche 2 
    %01011110 PORTB c! 500 ms   \ affiche 3 
    %01101100 PORTB c! 500 ms   \ affiche 4 
    %01110110 PORTB c! 500 ms   \ affiche 5 
    %01110111 PORTB c! 500 ms   \ affiche 6 
    %00011100 PORTB c! 500 ms   \ affiche 7 
    %01111111 PORTB c! 500 ms   \ affiche 8 
    %01111110 PORTB c! 500 ms   \ affiche 9 
    $00 PORTB c! ;              \ éteint afficheur 

Là, c'est juste un test d'affichage qui permet surtout de vérifier que nos chiffres s'affichent correctement sur notre afficheur 7 segments. L'idéal serait maintenant de disposer d'un mot qui stocke ces 10 valeurs binaires dans une table:

flash 
create digits  ( --- addr) 
    %00111111 c,    \ chiffre 0 
    %00001100 c,    \ chiffre 1 
    %01011011 c,    \ chiffre 2 
    %01011110 c,    \ chiffre 3 
    %01101100 c,    \ chiffre 4 
    %01110110 c,    \ chiffre 5 
    %01110111 c,    \ chiffre 6 
    %00011100 c,    \ chiffre 7 
    %01111111 c,    \ chiffre 8 
    %01111110 c,    \ chiffre 9 
    %00000000 c,    \ éteint afficheur 

Le mot create est un mot de création FORTH. Il est suivi du mot à créer, ici digits.

Ensuite, chaque ligne compile chaque octet permettant d'afficher un chiffre sur l'afficheur 7 segments.

L'exécution du mot digitdépose l'adresse mémoire du premier chiffre destiné à l'afficheur 7 segments:

digits c@ PORTB c!    \ affiche le chiffre 0 

Pour afficher un autre chiffre, il suffit d'incrémente l'adresse délivrée par digits du nombre d'octets souhaité avant d'extraire la valeur à injecter à l'afficheur 7 segments. Exemple, pour afficher le chiffre 4 sur l'afficheur 7 segments:

digits 4 + c@ PORTB c!    \ affiche le chiffre 0 

Définissons un mot qui va factoriser ceci:

: >7seg ( n ---)   
    digits +        \ incrémente adresse valeur n 
    c@              \ récupère c à envoyer à afficheur 7 segments 
    PORTB c! ;      \ envoie valeur à l'afficheur 

La séquence 3 >7seg fait afficher 3 sur l'afficheur 7 segments.

Le mot >7seg ne peut être précédé que d'une valeur comprise entre 0 et 9. Toute autre valeur provoquera un effet aléatoire...

Si vous souhaitez afficher les chiffres A à F pour du codage hexadécimal, nous vous laissons le soin d'étendre le code pour ces chiffres supplémentaires.... Hé oui! En codage hexadécimal, A à F sont des chiffres...

Un chenillard ARDUINO

Le logo ARDUINO est le symbole infini, un 8 couché. Nous allons générer un chenillard qui dessine ce "8" sur notre afficheur 7 segments:

flash 
create chenille   ( --- addr) 
%00000110 c, 
%01000100 c, 
%01100000 c, 
%00110000 c, 
%00011000 c, 
%01001000 c, 
%01000001 c, 
%00000011 c, 
: boucle-chenille ( ---) 
    begin 
        8 for 
          8 r@ - 1-     \ calcul index qui doit aller de 0 à 7 
          chenille + c@ \ récupère octet à envoyer à afficheur 7 segments 
          PORTB c!      \ envoi octet vers afficheur 7 segments 
          100 ms        \ attente 0,1 sec 
        next 
    key?                \ ai ppui touche, sort de la boucle begin..until 
    until ; 

Les segments sont allumés deux à deux, en suivant un trajet en "8"...

Jeu de tirage de dés

En reprenant juste les quelques éléments déja développés, on va créer un jeu de tirage de dés. On définit une fonction aléatoire rand qui sort un nombre aléatoire:

\ *** jeu de dés *********** 
variable rnd \ holds some entropy 
\ get a random number 
: random ( -- n ) 
    rnd @  31421 *  6927 +  dup rnd !  
; 
\ get a random number between 0 and u 
: rand ( u -- 0..u-1) 
    random um* nip 
; 
\ rand sort un nombre aléatoire enre 0 et u-1 

Ce mot rand est utilisé ensuite pour effectuer un tirage de dé dans le mot sortDe:

: sortDe ( --- n) 
 6 rand 1+ ;        \ tirage aléatoire entre 1 et 6 

Et pour que ce soit plus sexy, on crée le mot tirageDe:

: tirageDe ( ---) 
    4 for 
        8 for 
          8 r@ - 1-     \ calcul index qui doit aller de 0 à 7 
          chenille + c@ \ récupère octet à envoyer à afficheur 7 segments 
          PORTB c!      \ envoi octet vers afficheur 7 segments 
          100 ms        \ attente 0,1 sec 
        next 
    next 
    sortDe >7seg  
    ; 

Le mot tirageDe lance un chenillard Arduino (voir plus haut), puis extrait une valeur aléatoire et l'envie à l'afficheur 7 segments.

Conclusion

Nous arrivons ici à la dernière étape du processus de développement bottom-up, car la finalité a été atteinte: un jeu de dé pour illustrer la gestion d'un afficheur 7 segments.

Nous espérons que vous avez compris la démarche de ce processus de développement:

FORTH n'a pas la prétention d'être meilleur que tel ou tel autre langage de développement. FORTH est simplement une alternative. Au travers de cet exemple, vous avez pu constater qu'il est aisé de maitriser un processus de développement bottom-up.