Accueil > La technologie > Arduino > Manœuvre des aiguilles avec des servo-moteurs > Témoins de positions : le Charlieplexing

Manœuvre des aiguilles en analogique avec des servo-moteurs

Témoins de positions : le Charlieplexing

lundi 2 décembre 2013, par Jean-Luc

La dernière fonction à mettre en œuvre est la gestion des témoins de position. 16 LED sont nécessaires et il nous reste 6 broches. La broche numérique 13 ayant déjà une LED soudée sur la carte de l’Arduino n’est pas très commode à utiliser. Il nous reste donc en réalité 5 broches.

Comment faire ?

Il existe une technique connue sous le nom de Charliplexing [1] qui permet de multiplexer des LED sur des entrées/sorties numériques. Examinons tout d’abord le cas de deux LED connectées à 2 broches avec 2 résistances de 150Ω.

Charlieplexing avec 2 broches
dont l’intérêt est plus que discutable.

Si la broche 0 est en sortie à 5V et la broche 1 en sortie à 0V, la LED rouge est allumée. Si la broche 0 est en sortie à 0V et la broche 1 en sortie à 5V, la LED verte est allumée. Toute autre configuration, une des broches ou les deux en entrée ou les deux en sortie au même potentiel, éteint les deux LED.

Ça ne nous avance pas beaucoup me direz vous.

Rajoutons donc une broche 2 et une résistance et ajoutons une paire de LED entre la broche 2 et la broche 1 mais aussi entre la broche 2 et la broche 0, soit 6 LED au total.

Charlieplexing avec 3 broches

Pour allumer la LED D5 par exemple, il faut mettre la broche 0 en sortie à 5V, la broche 2 en sortie à 0V et pour que ni D1, ni D3 ne s’allument, mettre la broche 1 en entrée (donc en haute impédance). On peut remarquer que D1 et D3 sont également alimentées mais comme elle sont en série, elles présentent une tension de seuil 2 fois supérieure [2] et le courant empruntera le chemin de plus faible tension de seuil.

Pour la suite on va noter le fait de mettre une sortie à 5V : 1, à 0V, 0 et en entrée : Z.

La table correspondant à l’allumage de chaque LED est la suivante.

  broche 0 broche 1 broche 2
D0 0 1 Z
D1 1 0 Z
D2 Z 0 1
D3 Z 1 0
D4 0 Z 1
D5 1 Z 0

De manière générale, avec N broches, on peut piloter N × N-1 LED. Avec nos 5 broches disponible, on pourra donc piloter 5 × 4 = 20 LED.

Programme de démonstration

Évidemment, seule une LED peut être allumée à un instant. C’est donc l’Arduino qui va s’occuper de balayer les LED et, pour chacune les allumer ou non à une vitesse suffisamment grande pour que l’œil ait l’impression que l’allumage de chaque LED est permanent grâce à la persistance rétinienne. Avant de nous lancer dans l’allumage de 16 LED, voyons comment fonctionne le programme pour 3 broches et 6 LED. Dans un premier temps, nous allons balayer et allumer les 6 LED pour juger de l’effet rendu.

Il faut tout d’abord transposer le table d’états en C dont les lignes correspondront aux LED et les colonnes aux sortie. Les états eux même sont définis par un enum, une manière de donner un nom symbolique à une constante numérique :

enum { OUT0, OUT1, INZ };
 
const byte etatSortiePourLED[6][3] = {
    { OUT0, OUT1, INZ }, /* D0 */
    { OUT1, OUT0, INZ }, /* D1 */
    { INZ, OUT0, OUT1 }, /* D2 */
    { INZ, OUT1, OUT0 }, /* D3 */
    { OUT0, INZ, OUT1 }, /* D4 */
    { OUT1, INZ, OUT0 }  /* D5 */
};

OUT0 signifie que le broche est en sortie et à 0, OUT1 qu’elle est en sortie et à 1 et INZ en entrée et à haute impédance, c’est à dire sans résistance de pull-up.

Ajoutons une fonction pour programmer une broche en fonction de ce code :

void programmeBroche(int numBroche, byte etat)
{
    switch (etat) {
        case OUT0:
          digitalWrite(numBroche,LOW);
          pinMode(numBroche,OUTPUT);
          break;
        case OUT1:
          digitalWrite(numBroche,HIGH);
          pinMode(numBroche,OUTPUT);
          break;
        case INZ:
          pinMode(numBroche,INPUT);
          digitalWrite(numBroche,LOW); /* pas de pullup */
          break;
    }
}

Pour que l’on puisse tour à tour allumer une LED ou non, il nous faut un tableau qui, pour chaque LED, va indiquer son état, ALLUME ou ETEINT. De nouveau nous allons utiliser un enum.

enum { ALLUME, ETEINT };
 
byte etatLED[6] = {
    ETEINT, ETEINT, ETEINT, ETEINT, ETEINT, ETEINT
};

Enfin, il nous faut une fonction qui, pour un numéro de LED, va chercher son état et, si elle elle allumée, appelle, pour chaque broche, programmeBroche avec les états de broche correspondant à l’allumage de cet LED. Si elle est éteinte, toutes les sorties sont mises dans l’état INZ.

void gereLED(int num)
{
    if (etatLED[num] == ALLUME) {
        programmeBroche(10,etatSortiePourLED[num][0]);
        programmeBroche(11,etatSortiePourLED[num][1]);
        programmeBroche(12,etatSortiePourLED[num][2]);
    }
    else {
        programmeBroche(10,INZ);
        programmeBroche(11,INZ);
        programmeBroche(12,INZ);
    }
}

Il suffit ensuite dans loop() de balayer les LED, de 0 à 5, en donnant leur état avec une période de 2ms.

int numLED = 0;
 
void loop()
{
    gereLED(numLed);
 
    numLED++;
    if (numLED > 5)
        numLED = 0;
 
    delay(2);
}

Par dessus on superpose une séquence d’allumage comme, par exemple, un chenillard.

int numLED = 0;

int LEDAllumee = 0;
int compteur1s = 0;
 
void setup()
{
    /* Au début la LED 0 est allumée */
    etatLED[LEDAllumee] = ALLUME;
}
 
void loop()
{
    compteur1s++;
    if (compteur1s == 500) {
        /* Au bout de 1s, on allume la LED suivante */
        compteur1s = 0;
        /* Éteint la LED qui était allumée */
        etatLED[LEDAllumee] = ETEINT;
        /* Passe à la LED suivante */
        LEDAllumee++;
        if (LEDAllumee > 5)
            LEDAllumee = 0;
        /* Allume la nouvelle LED */
        etatLED[LEDAllumee] = ALLUME;
    }
 
    gereLED(numLed);
 
    numLED++;
    if (numLED > 5)
        numLED = 0;
 
    delay(2);
}

Voici le programme de chenillard en Charlieplexing sur 3 broches et 6 LED.

Sketch du chenillard en Charlieplexing

Ainsi que la vidéo de démonstration

Démonstration du sketch de chenillard

[1Le Charlieplexing est une technique proposée en 1995 par Charlie Allen, voir l’article sur Wikipedia

[2La tension de seuil dépend de la couleur de la LED mais même en mettant en série 2 LED rouge dont la tension de seuil est la plus faible, 1,6V, 2 × 1,6V = 3,2 V reste supérieure à la tension de seuil des LED violettes, 3,1V

Un message, un commentaire ?

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)