L'affichage

De Wiki L.A.B
Aller à : navigation, rechercher

L'afficheur 7 segments

Matériel
  • Arduino Uno
  • Plaque d'essai (breadboard)
  • 1 Afficheur 7 segments
  • 8 Résistances 1/4W 220Ω (270Ω ou 330Ω peuvent également convenir)
  • Straps ou fils de liaison
Principe

Un afficheur 7 segments est le plus simple des afficheurs. On le retrouve très fréquemment lorsqu'il s'agit d'afficher une information numérique. Il est constitué de 7 LED (+1 pour le point) reliées ensemble par leur anode (il en existe aussi reliés par la cathode). On peut commander individuellement.

Classiquement les différentes LED (aussi appelées segments) sont nommées conformément au schéma ci-dessous :

7 segment display labeled.png

Le composant que nous utiliserons met en correspondance les segments avec les broches physiques (pin) de la manière suivante :

Schema principe.gif

Pin du composant Nom du segment
1 E
2 D
3 Anode commune
4 C
5 DP
6 B
7 A
8 Anode commune
9 F
10 G
Montage

Montage Afficheur 7 Segments

Montage Afficheur 7 Segments


Pin du composant Nom du segment Pin sur l'Arduino
1 E D9
2 D D8
3 Anode commune 5V
4 C D4
5 DP D5
6 B D3
7 A D2
8 Anode commune
9 F D6
10 G D7
Programme

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino :

/*
  Ce programme met en oeuvre l'utilisation d'un afficheur 7 segments allumant séquentiellement chacune des LED
*/

const int led_A = 2; // le segment A est branché sur la pin 2
const int led_B = 3;
const int led_C = 4;
const int led_D = 8;
const int led_E = 9;
const int led_F = 6;
const int led_G = 7;
const int led_DP = 5;

inline void allumer(int led){
    digitalWrite(led, LOW);
}

inline void eteindre(int led){
    digitalWrite(led, HIGH);
}

inline void eteindreToutesLesLED(){
    eteindre(led_A); // eteint la LED
    eteindre(led_B);
    eteindre(led_C);
    eteindre(led_D);
    eteindre(led_E);
    eteindre(led_F);
    eteindre(led_G);
    eteindre(led_DP);
}

inline void allumerEtEteindreLED(int led){
  allumer(led);
  delay(500);               // attente de 1/2 seconde
  eteindre(led);
}


void setup() // setup est exécuté une seule fois après la remise à zéro
{                
  pinMode(led_A, OUTPUT); // la broche led_A (2) est initialisée en sortie
  pinMode(led_B, OUTPUT); 
  pinMode(led_C, OUTPUT); 
  pinMode(led_D, OUTPUT);
  pinMode(led_E, OUTPUT);
  pinMode(led_F, OUTPUT);
  pinMode(led_G, OUTPUT);
  pinMode(led_DP, OUTPUT);
  eteindreToutesLesLED();
}

void loop() // loop est exécuté indéfiniment
{
  allumerEtEteindreLED(led_A);
  allumerEtEteindreLED(led_B);
  allumerEtEteindreLED(led_C);
  allumerEtEteindreLED(led_D);
  allumerEtEteindreLED(led_E);
  allumerEtEteindreLED(led_F);
  //allumerEtEteindreLED(led_G);
  //allumerEtEteindreLED(led_DP);
}

Pour enlever la redondance du code précédent on peut utiliser un tableau. Le tableau permet d'indexer les différentes pin pour pouvoir les utiliser séquentiellement sans dupliquer le code. Les tableaux s'utilisent généralement de pair avec les boucle for.

/*
  Ce programme met en oeuvre l'utilisation d'un afficheur 7 segments allumant séquentiellement chacune des LED
*/


//Déclaration des constantes 
const int led_A = 2; // le segment A est branché sur la pin 2
const int led_B = 3;
const int led_C = 4;
const int led_D = 8;
const int led_E = 9;
const int led_F = 6;
const int led_G = 7;
const int led_DP = 5;

const int tableauSegment [] = {led_A, led_B, led_C, led_D, led_E, led_F, led_G, led_DP};
const int nbSegment = 8;


// Déclaration des variables globales
int indiceSegmentCourant = 0;

inline void allumer(int led){
    digitalWrite(led, LOW);
}

inline void eteindre(int led){
    digitalWrite(led, HIGH);
}

inline void eteindreToutesLesLED(){ 
    for(int i=0; i < nbSegment; i++){
        int ledAEteindre = tableauSegment[i];  
        eteindre(ledAEteindre); // eteint la LED
    }
}

inline void allumerEtEteindreLED(int led){
    allumer(led);
    delay(500);               // attente de 1/2 seconde
    eteindre(led);
}

void setup() // setup est exécuté une seule fois après la remise à zéro
{                
    pinMode(led_A, OUTPUT); // la broche led_A (2) est initialisée en sortie
    pinMode(led_B, OUTPUT); 
    pinMode(led_C, OUTPUT); 
    pinMode(led_D, OUTPUT);
    pinMode(led_E, OUTPUT);
    pinMode(led_F, OUTPUT);
    pinMode(led_G, OUTPUT);
    pinMode(led_DP, OUTPUT);
    eteindreToutesLesLED();
}

void loop() // loop est exécuté indéfiniment
{   
    int ledAFaireClignoter = tableauSegment[indiceSegmentCourant];
    allumerEtEteindreLED(ledAFaireClignoter);
  
    // Passer à la led suivante
    ++indiceSegmentCourant;
  
    //Lorsque l'on dépasse le dernier indice possible, on retourne à 0
    if(indiceSegmentCourant >= nbSegment){
        indiceSegmentCourant = 0;
    }
}

Pour afficher des chiffres, il faut connaitre (ou retrouver) la table des configurations valides pour l'afficheur :

Programmation
Chiffre Segment DP Segment G Segment F Segment E Segment D Segment C Segment B Segment A
0 0 0 1 1 1 1 1 1
1 0 0 0 0 0 1 1 0
2 0 1 0 1 1 0 1 1
3 0 1 0 0 1 1 1 1
4 0 1 1 0 0 1 1 0
5 0 1 1 0 1 1 0 1
6 0 1 1 1 1 1 0 1
7 0 0 0 0 0 1 1 1
8 0 1 1 1 1 1 1 1
9 0 1 1 0 1 1 1 1
A 0 1 1 1 0 1 1 1
B 0 1 1 1 1 1 0 0
C 0 0 1 1 1 0 0 1
D 0 1 0 1 1 1 1 0
E 0 1 1 1 1 0 0 1
F 0 1 1 1 0 0 0 1
/*
  Ce programme met en oeuvre l'utilisation d'un afficheur 7 segments en affichant la lettre A
*/


//Déclaration des constantes 
const int led_A = 2; // le segment A est branché sur la pin 2
const int led_B = 3;
const int led_C = 4;
const int led_D = 8;
const int led_E = 9;
const int led_F = 6;
const int led_G = 7;
const int led_DP = 5;

const int tableauSegment [] = {led_A, led_B, led_C, led_D, led_E, led_F, led_G, led_DP};
const int nbSegment = 8;


// Déclaration des variables globales
int indiceSegmentCourant = 0;

inline void allumer(int led){
    digitalWrite(led, LOW);
}

inline void eteindre(int led){
    digitalWrite(led, HIGH);
}

inline void eteindreToutesLesLED(){ 
    for(int i=0; i < nbSegment; i++){
        int ledAEteindre = tableauSegment[i];  
        eteindre(ledAEteindre); // eteint la LED
    }
}

inline void allumerEtEteindreLED(int led){
  allumer(led);
  delay(500);               // attente de 1/2 seconde
  eteindre(led);
}


void setup() // setup est exécuté une seule fois après la remise à zéro
{                
  pinMode(led_A, OUTPUT); // la broche led_A (2) est initialisée en sortie
  pinMode(led_B, OUTPUT); 
  pinMode(led_C, OUTPUT); 
  pinMode(led_D, OUTPUT);
  pinMode(led_E, OUTPUT);
  pinMode(led_F, OUTPUT);
  pinMode(led_G, OUTPUT);
  pinMode(led_DP, OUTPUT);
  eteindreToutesLesLED();
}

void loop() // loop est exécuté indéfiniment
{   
    //D'après le tableau, la lettre A correspond à : 0	 1	 1	 1	 0	 1	 1	 1    
    allumer(led_A);
    allumer(led_B);
    allumer(led_C);
    eteindre(led_D);
    allumer(led_E);
    allumer(led_F);
    allumer(led_G);
    eteindre(led_DP);   
}

Le programme suivant affiche tous les chiffres de 0 à 9 :

/*
  Ce programme met en oeuvre l'utilisation d'un afficheur 7 segments en affichant les chiffres les uns après les autres
*/

//Déclaration des constantes 
const int led_A = 2; // le segment A est branché sur la pin 2
const int led_B = 3;
const int led_C = 4;
const int led_D = 8;
const int led_E = 9;
const int led_F = 6;
const int led_G = 7;
const int led_DP = 5;

const int tableauSegment [] = {led_A, led_B, led_C, led_D, led_E, led_F, led_G, led_DP};
const int nbSegment = 8;

inline void allumer(int led){
    digitalWrite(led, LOW);
}

inline void eteindre(int led){
    digitalWrite(led, HIGH);
}

inline void eteindreToutesLesLED(){ 
    for(int i=0; i < nbSegment; i++){
        int ledAEteindre = tableauSegment[i];  
        eteindre(ledAEteindre); // eteint la LED
    }
}

inline void allumerEtEteindreLED(int led){
  allumer(led);
  delay(500);               // attente de 1/2 seconde
  eteindre(led);
}

void afficher(char chiffre){
    eteindreToutesLesLED();
    switch(chiffre)
    {
    case 0 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_C);
        allumer(led_D);
        allumer(led_E);
        allumer(led_F);  
        break;
    case 1 :
        allumer(led_B);
        allumer(led_C); 
        break;
    case 2 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_D);
        allumer(led_E);
        allumer(led_G);
        break;
    case 3 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_C);
        allumer(led_D);
        allumer(led_G);
        break;
    case 4 :
        allumer(led_B);
        allumer(led_C);
        allumer(led_F);
        allumer(led_G);
        break;
    case 5 :
        allumer(led_A);
        allumer(led_C);
        allumer(led_D);
        allumer(led_F);
        allumer(led_G); 
        break;
    case 6 :
        allumer(led_A);
        allumer(led_C);
        allumer(led_D);
        allumer(led_E);
        allumer(led_F);
        allumer(led_G);
        break;
    case 7 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_C); 
        break;
    case 8 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_C);
        allumer(led_D);
        allumer(led_E);
        allumer(led_F);
        allumer(led_G); 
        break;
    case 9 :
        allumer(led_A);
        allumer(led_B);
        allumer(led_C);
        allumer(led_D);
        allumer(led_F);
        allumer(led_G);
        break;
    }
}

void setup() // setup est exécuté une seule fois après la remise à zéro
{                
    pinMode(led_A, OUTPUT); // la broche led_A (2) est initialisée en sortie
    pinMode(led_B, OUTPUT); 
    pinMode(led_C, OUTPUT); 
    pinMode(led_D, OUTPUT);
    pinMode(led_E, OUTPUT);
    pinMode(led_F, OUTPUT);
    pinMode(led_G, OUTPUT);
    pinMode(led_DP, OUTPUT);
    eteindreToutesLesLED();
}

void loop() // loop est exécuté indéfiniment
{   
    for(char i=0; i <=9; ++i){
        afficher(i);
        delay(500);
    }  
}

Ce programme peut être simplifié en stockant la matrice des configurations directement dans la mémoire flash de l'arduino :

/*
  Ce programme met en oeuvre l'utilisation d'un afficheur 7 segments en affichant les chiffres les uns après les autres
*/


//Déclaration des constantes 
const int led_A = 2; // le segment A est branché sur la pin 2
const int led_B = 3;
const int led_C = 4;
const int led_D = 8;
const int led_E = 9;
const int led_F = 6;
const int led_G = 7;
const int led_DP = 5;

const int tableauSegment [] = {led_A, led_B, led_C, led_D, led_E, led_F, led_G, led_DP};
const int nbSegment = 8;

const int tableauChiffre[][nbSegment] = {
    {1, 1, 1, 1, 1, 1, 0, 0}, 
    {0, 1, 1, 0, 0, 0, 0, 0}, 
    {1, 1, 0, 1, 1, 0, 1, 0}, 
    {1, 1, 1, 1, 0, 0, 1, 0}, 
    {0, 1, 1, 0, 0, 1, 1, 0}, 
    {1, 0, 1, 1, 0, 1, 1, 0}, 
    {1, 0, 1, 1, 1, 1, 1, 0}, 
    {1, 1, 1, 0, 0, 0, 0, 0}, 
    {1, 1, 1, 1, 1, 1, 1, 0}, 
    {1, 1, 1, 1, 0, 1, 1, 0}, 
    {1, 1, 1, 0, 1, 1, 1, 0}, 
    {0, 0, 1, 1, 1, 1, 1, 0}, 
    {1, 0, 0, 1, 1, 1, 0, 0}, 
    {0, 1, 1, 1, 1, 0, 1, 0}, 
    {1, 0, 0, 1, 1, 1, 1, 0}, 
    {1, 0, 0, 0, 1, 1, 1, 0},  
};

// Déclaration des variables globales
int indiceSegmentCourant = 0;

inline void allumer(int led){
    digitalWrite(led, LOW);
}

inline void eteindre(int led){
    digitalWrite(led, HIGH);
}

inline void eteindreToutesLesLED(){ 
    for(int i=0; i < nbSegment; i++){
        int ledAEteindre = tableauSegment[i];  
        eteindre(ledAEteindre); // eteint la LED
    }
}

inline void allumerEtEteindreLED(int led){
  allumer(led);
  delay(500);               // attente de 1/2 seconde
  eteindre(led);
}


void afficher(char chiffre){
    eteindreToutesLesLED();
    for(int i = 0; i < nbSegment; ++i){
        if(tableauChiffre[chiffre][i] == 1)
        {
            allumer(tableauSegment[i]);
        }
    }
}

void setup() // setup est exécuté une seule fois après la remise à zéro
{                
    pinMode(led_A, OUTPUT); // la broche led_A (2) est initialisée en sortie
    pinMode(led_B, OUTPUT); 
    pinMode(led_C, OUTPUT); 
    pinMode(led_D, OUTPUT);
    pinMode(led_E, OUTPUT);
    pinMode(led_F, OUTPUT);
    pinMode(led_G, OUTPUT);
    pinMode(led_DP, OUTPUT);
    eteindreToutesLesLED();
}

void loop() // loop est exécuté indéfiniment
{   
    for(char i=0; i <=9; ++i){
        afficher(i);
        delay(500);
    }  
}

Matrice de LED

Matériel
Principe

Comme on l'a vu avec l'afficheur 7 segments, les LED sont un moyen commode pour afficher une information simple. Le principal problème des montages que nous avons vus jusqu'à présent est que le nombre de broches utilisées est égal au nombre de LED.

La matrice de LED est un arrangement particulier d'un ensemble de LED pour constituer un tableau où l'on peut éclairer chaque LED indépendamment. Les LED sont rangées en lignes et colonnes. Comme pour l'afficheur 7 segments, il existe deux types de matrice :

  1. Matrice à anode commune.
  2. Matrice à cathode commune.

Les exemples ci-dessous sont écrits pour être compatible avec le Lumex LDM-24488NI Matrix (http://sigma.octopart.com/140413/datasheet/Lumex-LDM-24488NI.pdf). C'est une matrice 8x8 à cathode commune assez standard. Ils devraient être assez facile de les adapter pour d'autres modèles de matrices.

3mmred8x8.jpg

Une matrice 8x8 (64 LED) utilise au total 16 entrées (8 pour les lignes et 8 pour les colonnes). Pour éviter de passer trop de temps à câbler une matrice, nous avons préféré utiliser un shield (une carte fille de l'arduino) qui relie chaque broche de la matrice à une broche de l'Arduino.

Shield.JPG

Le brochage de la matrice sur le shield est le suivant :

Pin conceptuelle Pin Arduino Pin physique
Colonne 1 6 13
Colonne 2 11 3
Colonne 3 10 4
Colonne 4 3 10
Colonne 5 17 6
Colonne 6 4 11
Colonne 7 8 15
Colonne 8 9 16
Ligne 1 2 9
Ligne 2 7 14
Ligne 3 19 8
Ligne 4 5 12
Ligne 5 13 1
Ligne 6 18 7
Ligne 7 12 2
Ligne 8 16 5

Les broches 16, 17, 18, 19 correspondent au pin A2 ,A3 ,A4, A5 de l'Arduino quand elles sont utilisées comme des sorties numériques.

Pour éclairer une LED de coordonnée (x,y), il faut relier la broche de la colonne x à la masse et celle de la ligne y au 5v. On peut alimenter plusieurs LED d'une même colonne mais les colonnes doivent être mises à la masse une seule à la fois sinon on obtient deux fois la même colonne.

Programme

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino.

/*
 Ce programme met en oeuvre l'utilisation d'une matrice de LED. L'objectif est d'éclairer 
les LED paires de la première colonne.
*/
 
const int nbLignes = 8;
const int lignes[nbLignes] = {2, 7, 19, 5, 13, 18, 12, 16};

const int nbColonnes = 8;
const int colonnes[nbColonnes] = {6, 11, 10, 3, 17, 4, 8, 9};
 
// représentation de l'image à dessiner
int pixels[8][8];           
void setup() {
      for (int i = 0; i < nbColonnes; i++) {
          pinMode(colonnes[i], OUTPUT);  
          // Mettre les pins des colonnes à l'état haut pour éteindre toutes les led
          digitalWrite(colonnes[i], HIGH);    
      }
      
      for (int i = 0; i < nbLignes; i++) { 
          pinMode(lignes[i], OUTPUT);
      } 
     
      // initialisation de la matrice image
      for (int x = 0; x < nbColonnes; x++) {
          for (int y = 0; y < nbLignes; y++) {
              pixels[x][y] = 1;
          }
      }
}
 
void loop() {
    digitalWrite(colonnes[0], LOW);
    
    digitalWrite(lignes[0], HIGH);
    digitalWrite(lignes[2], HIGH);
    digitalWrite(lignes[4], HIGH);
    digitalWrite(lignes[6], HIGH);
    digitalWrite(lignes[8], HIGH);   
}


On peut aussi animer le programme précédent en allumant et éteignant les LED de la diagonale les unes après les autres.

/*
 Ce programme met en oeuvre l'utilisation d'une matrice de LED. L'objectif est de découvrir le principe du balaiement en éclairant une après l'autre les LED de la diagonale
*/
 
const int nbLignes = 8;
const int lignes[nbLignes] = {2, 7, 19, 5, 13, 18, 12, 16};

const int nbColonnes = 8;
const int colonnes[nbColonnes] = {6, 11, 10, 3, 17, 4, 8, 9};

// Variables globales
int indiceColonneCourante = 0;

// représentation de l'image à dessiner
int pixels[8][8];


void setup() {
      for (int i = 0; i < nbColonnes; i++) {
          pinMode(colonnes[i], OUTPUT);  
          // Mettre les pins des colonnes à l'état haut pour éteindre toutes les led
          digitalWrite(colonnes[i], HIGH);    
      }
      
      for (int i = 0; i < nbLignes; i++) { 
          pinMode(lignes[i], OUTPUT);
      } 
     
      // initialisation de la matrice image
      for (int x = 0; x < nbColonnes; x++) {
          for (int y = 0; y < nbLignes; y++) {
              pixels[x][y] = 1;
          }
      }
}
 
void loop() {
    digitalWrite(colonnes[indiceColonneCourante], LOW);
    digitalWrite(lignes[indiceColonneCourante], HIGH);
    
    delay(200); 
    
    digitalWrite(lignes[indiceColonneCourante], LOW);
    digitalWrite(colonnes[indiceColonneCourante], HIGH);
    
    // Passer à la led suivante
    ++indiceColonneCourante;
  
    //Lorsque l'on dépasse le dernier indice possible, on retourne à 0
    if(indiceColonneCourante >= nbColonnes){
        indiceColonneCourante = 0;
    }
}
/*
 Ce programme met en oeuvre l'utilisation d'une matrice de LED. L'objectif est de découvrir le principe du balaiement en affichant une image colonne après colonne
*/

#define SPACE { \
    {0, 0, 0, 0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0} \
}

#define H { \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}  \
}

#define E  { \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define L { \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define O { \
    {0, 0, 0, 1, 1, 0, 0, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 0, 0, 1, 1, 0, 0, 0}  \
}

#define SMILEY { \
    {0, 0, 1, 1, 1, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {1, 0, 1, 0, 0, 1, 0, 1}, \
    {1, 0, 0, 0, 0, 0, 0, 1}, \
    {1, 0, 1, 1, 1, 1, 0, 1}, \
    {1, 0, 0, 1, 1, 0, 0, 1}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 1, 1, 1, 0, 0}  \
}



const int nbLignes = 8;
const int lignes[nbLignes] = {2, 7, 19, 5, 13, 18, 12, 16};

const int nbColonnes = 8;
const int colonnes[nbColonnes] = {6, 11, 10, 3, 17, 4, 8, 9};

// Variables globales
int indiceColonneCourante = 0;

// représentation de l'image à dessiner
int pixels[8][8] = SMILEY;

void afficherColonne(int indiceColonne, int delai){
    
    digitalWrite(colonnes[indiceColonne], LOW);//Activation de la colonne à afficher
    
    for (int i = 0; i < nbLignes; ++i) {
        digitalWrite(lignes[i], pixels[i][indiceColonne]);
    }

    delay(delai);

    for (int i = 0; i < nbLignes; ++i) {
        digitalWrite(lignes[i], LOW);
    }
    
    digitalWrite(colonnes[indiceColonne], HIGH); //Désactivation de la colonne à afficher
    
}


void setup() {
      for (int i = 0; i < nbColonnes; ++i) {
          pinMode(colonnes[i], OUTPUT);  
          // Mettre les pins des colonnes à l'état haut pour éteindre toutes les led
          digitalWrite(colonnes[i], HIGH);    
      }
      
      for (int i = 0; i < nbLignes; ++i) { 
          pinMode(lignes[i], OUTPUT);
      } 
}
 
void loop() {
    afficherColonne(indiceColonneCourante, 2);
    
    // Passer à la led suivante
    ++indiceColonneCourante;
  
    //Lorsque l'on dépasse le dernier indice possible, on retourne à 0
    if(indiceColonneCourante >= nbColonnes){
        indiceColonneCourante = 0;
    }
}
/*
 Ce programme met en oeuvre l'utilisation d'une matrice de LED. L'objectif est de découvrir le principe du balaiement en éclairant une après l'autre les LED de la diagonale
*/

#define SPACE { \
    {0, 0, 0, 0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0} \
}

#define H { \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}  \
}

#define E  { \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define L { \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define O { \
    {0, 0, 0, 1, 1, 0, 0, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 0, 0, 1, 1, 0, 0, 0}  \
}

#define SMILEY { \
    {0, 0, 1, 1, 1, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {1, 0, 1, 0, 0, 1, 0, 1}, \
    {1, 0, 0, 0, 0, 0, 0, 1}, \
    {1, 0, 1, 1, 1, 1, 0, 1}, \
    {1, 0, 0, 1, 1, 0, 0, 1}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 1, 1, 1, 0, 0}  \
}



const int nbLignes = 8;
const int lignes[nbLignes] = {2, 7, 19, 5, 13, 18, 12, 16};

const int nbColonnes = 8;
const int colonnes[nbColonnes] = {6, 11, 10, 3, 17, 4, 8, 9};

// Variables globales
int indiceColonneCourante = 0;

const int nbPatterns = 8;
int patterns[nbPatterns][8][8] = {
  H,E,L,L,O,SPACE, SMILEY, SPACE
};

int pattern = 0;
int debutPattern;


void afficherColonne(int indiceColonne, int delai){
    
    digitalWrite(colonnes[indiceColonne], LOW);//Activation de la colonne à afficher
    
    for (int i = 0; i < nbLignes; ++i) {
        digitalWrite(lignes[i], patterns[pattern][i][indiceColonne]);
    }

    delay(delai);

    for (int i = 0; i < nbLignes; ++i) {
        digitalWrite(lignes[i], LOW);
    }
    
    digitalWrite(colonnes[indiceColonne], HIGH); //Désactivation de la colonne à afficher
    
}


void setup() {
      for (int i = 0; i < nbColonnes; ++i) {
          pinMode(colonnes[i], OUTPUT);  
          // Mettre les pins des colonnes à l'état haut pour éteindre toutes les led
          digitalWrite(colonnes[i], HIGH);    
      }
      
      for (int i = 0; i < nbLignes; ++i) { 
          pinMode(lignes[i], OUTPUT);
      } 
      
      debutPattern = millis();
}
 
void loop() {
    afficherColonne(indiceColonneCourante, 2);
    
    // Passer à la led suivante
    ++indiceColonneCourante;
  
    //Lorsque l'on dépasse le dernier indice possible, on retourne à 0
    if(indiceColonneCourante >= nbColonnes){
        indiceColonneCourante = 0;
        int finPattern = millis();
        if(finPattern - debutPattern > 1000 || debutPattern > finPattern){
            pattern = (pattern + 1)% nbPatterns;
            debutPattern = finPattern;
        }
    }
}

Ecran LCD

Matériel
Principe

La dernière famille d'afficheurs que nous allons explorer est celle des afficheurs LCD (ou afficheurs à cristaux liquides en bon français). On retrouve ces écrans partout dans notre quotidien. Il en existe 3 principaux types : Dans la grande famille afficheur LCD, on distingue plusieurs catégories :

  • Les afficheurs alphanumériques
  • Les afficheurs graphiques monochromes
  • Les afficheurs graphiques couleurs

Les premiers sont ceux que nous allons utiliser. Ils permettent d'afficher facilement des chaines de caractères. Les caractères sont prédéfinis, on n'a donc pas besoin de gérer chaque pixel de l’écran. Les seconds laissent une liberté totale des graphismes affichés. Ils sont donc bien plus complexes à mettre en oeuvre. On a accès à chacun des pixels et on peut donc produire des dessins beaucoup plus évolués. Les derniers sont l’évolution des précédents, la couleur en plus (soit 3 fois plus de pixels à gérer : un sous-pixel pour le rouge, un autre pour le bleu et un dernier pour le vert).

Encore une fois, pour gagner en modularité et surtout éviter de perdre trop de temps à câbler, nous avons choisi d'utiliser un shield. En plus du LCD, ce shield ajoute quelques boutons permettant d’interagir avec l'écran. Il est particulièrement important de noter que l'accès à l'écran LCD est grandement facilité par l'utilisation de la bibliothèque LiquidCrystal qui masque tout le protocole bas niveau.

Shield lcd.jpg


Pin Arduino Fonction
7 RS - Register select
6 E - Enable
5 D4 - High 4-bit data
4 D5 - High 4-bit data
3 D6 - High 4-bit data
2 D7 - High 4-bit data
A0 Boutons poussoirs

Pour éviter d'utiliser 5 entrées pour les boutons poussoirs, les concepteurs de la carte ont préféré multiplexer les interrupteurs grâce à un pont diviseur de tension :

Analog buttons.jpg

Il faut noter que les résistances utilisées ont une précision de l'ordre de 10%. La tension associée à chaque bouton pourra donc légèrement varier.

Bouton poussoir Voltage sur A0
1 0V ±10%
2 1V ±10%
3 2V ±10%
4 3V ±10%
5 4V ±10%
none 5V ±10%
Montage

Le montage est très simple, il suffit d'assembler le shield et l'arduino de manière similaire à la photo ci-dessous :

Shield lcd avec arduino.jpg

Programme

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino.

/*
 Ce programme met en oeuvre l'utilisation d'un écran LCD. L'objectif est d'afficher un texte et de réagir à l'appui sur un bouton
*/

// inclusion de la bibliothèque
#include <LiquidCrystal.h>

// Initialisation de la bibliothèque par rapport au cablage du shield
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);


// Définition des constantes
const int inputPin = A0; 

// Définition des variables
int inputValue = 0;   // valeur lue sur l'entrée A0


// Initialization
void setup() 
{
  lcd.begin(16, 2);              // réglage du nombre de ligne et de colonne
  lcd.print("@nedseb is cool!"); // Affiche un message
  lcd.setCursor(0, 1);           // Déplace le curseur sur le caractère 0 de la ligne 1
  lcd.print("-- plop  plop --");
}

// main loop
void loop() 
{
  // vérifie l'état des boutons (Avec prise en charge de la variabilité du voltage)
  inputValue = analogRead(inputPin);
  if(inputValue < 100 && inputValue >= 0) inputValue = 1;
  else if(inputValue < 250 && inputValue > 150) inputValue = 2;
  else if(inputValue < 470 && inputValue > 370) inputValue = 3;
  else if(inputValue < 670 && inputValue > 570) inputValue = 4;
  else if(inputValue < 870 && inputValue > 770) inputValue = 5;
  else if(inputValue <= 1023 && inputValue > 950) inputValue = 0;

  // afficher l'événement
  if(inputValue == 1 || inputValue == 2 || inputValue == 3 || inputValue == 4 || inputValue == 5)
  {
    lcd.setCursor(0, 1);
    lcd.print("Boutton : ");
    lcd.print(inputValue);
    lcd.print("     ");
    delay(200);
  }
  else
  {
    lcd.setCursor(0, 1);
    lcd.print("-- plop  plop --");
  }
}
/*
 Ce programme met en oeuvre l'utilisation d'un écran LCD. L'objectif est d'afficher un texte et de réagir à l'appui sur un bouton
*/


// inclusion de la bibliothèque
#include <LiquidCrystal.h>

// Initialisation de la bibliothèque par rapport au cablage du shield
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

void setup(){
  lcd.begin(16, 2);
  // initialisation de la communication série
  Serial.begin(9600);
}

void loop()
{
  // Lorsqu'un caractère arrive sur le port série
  if (Serial.available()) {
    // attendre un peu pour laisser le temps au message d'arriver complètement
    delay(100);
    // effacer l'écran
    lcd.clear();
    // lire tous les caractères disponibles
    while (Serial.available() > 0) {
      // afficher chacun des caractères un par un
      lcd.write(Serial.read());
    }
  }
}
/*
 Ce programme met en oeuvre l'utilisation d'un écran LCD. L'objectif est d'afficher un texte et de réagir à l'appui sur un bouton
*/


// inclusion de la bibliothèque
#include <LiquidCrystal.h>

// Initialisation de la bibliothèque par rapport au cablage du shield
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};

void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);  
  lcd.write(byte(0));
}

void loop() {}