Arduino 40
Le Charlieplexage ou les économies d'E/S
Sommaire
| Charlieplexage, quoi-t-est-ce ? |
Je ne connais pas Charlie, mais je pense que c'est le nom de l'inventeur ...
Le livre de TAVERNIER sur l'ARDUINO expose l'idée en s'appuyant sur un module shield composé de plus de 100 leds, et de sa bibliothèque associée. En ce qui me concerne, c'est la curiosité, et peut-être l'intérêt pour des applications moins étendues ... qui m'ont amenés à tester ce système.
 | | Pour piloter 2 leds on peut faire comme ca : C'est à priori le plus simple et efficace, basique A=High/Low led_a=éteinte/allumée B=High/Low led_b=éteinte/allumée |
 | | MAIS ! On peut faire aussi comme ça Le seul intérêt est d'avoir 2 fils au lieu de 3 Pour piloter, c'est plus compliqué 0 vaut dire 0 volt(LOW), 1 =5volts(HIGH): |
Ligne |
led Verte |
led Rouge |
sortie A |
sortie B |
0 |
éteinte |
éteinte |
0 |
0 |
1 |
allumée |
éteinte |
1 |
0 |
2 |
éteinte |
allumée |
0 |
1 |
3 |
éteinte |
éteinte |
1 |
1 |
4 |
éteinte |
éteinte |
e |
e |
Mais comment allumer les 2 leds en même temps ? On va "multiplexer", c'est à dire utiliser successivement dans le temps, très vite (plus de 50 fois par seconde pour bien faire), les lignes 1 et 2 du tableau, et notre oeil ne verra rien d'autre que les 2 leds allumées, grâce à la "persistence rétinienne".
La position 4 du tableau indique des états "e", c'est à dire que l'on va programmer les E/S en "entrée", ce qui va les mettre en "haute impédance". Aucun courant ne peut alors passer dans les diodes. Cet état ne sert ici à rien, mais va bientôt servir ...
En ce qui concerne les 2 résistances, on aurait pu, dans ce cas_là n'en mettre qu'une, mais là aussi, cette symétrie va bientôt s'expliquer ...
 | | Et voilà le mystère qui s'éclaircit !... Là, les 3 branches expliquent pourquoi on a besoin du 3° état des sorties en "haute impédance" On va piloter les sorties A,B,C seulement 2 à 2, soit dans un sens, soit dans l'autre, pour allumer une seule diode à la fois. Par exemple, on met la sortie A à 0, la sortie B à 1, la sortie C en haute impédance : la led Rouge BA va s'allumer, la led verte AB sera éteinte, les 4 autres aussi. Vous remarquerez que les diodes qui sont dans les branches "éteintes" sont soit 2 en série avec la diode allumée, ce qui fait qu'elles ne s'allumeront pas, soient en inverse, ce qui ne risque pas des allumer, ni de les abimer d'ailleurs. Ceci est bien réalisé car le 3° point est en "entrée", donc flottant. On comprends également pourquoi on a 3 résistances, pour bien avoir une symétrie complète ! |
Position |
verte AB |
verte BC |
verte CA |
rouge BA |
rouge CB |
rouge BA |
sortie A |
sortie B |
sortie C |
0 |
. |
. |
. |
. |
. |
. |
e |
e |
e |
1 |
* |
. |
. |
. |
. |
. |
1 |
0 |
e |
2 |
. |
* |
. |
. |
. |
. |
e |
1 |
0 |
3 |
. |
. |
* |
. |
. |
. |
0 |
e |
1 |
4 |
. |
. |
. |
* |
. |
. |
0 |
1 |
e |
5 |
. |
. |
. |
. |
* |
. |
e |
0 |
1 |
6 |
. |
. |
. |
. |
. |
* |
0 |
1 |
e |
C'est génial ! avec 3 sorties, on pilote 6 leds ! Plus généralement, avec N sorties, on va pouvoir piloter = N*(N-1) leds !
En effet, voici un tableau qui montre combien de sorties S il faut pour piloter N leds en sortie directe, multiplexage ou Charlieplexage :
nombre de leds |
1 |
2 |
6 |
12 |
20 |
30 |
42 |
56 |
72 |
90 |
110 |
formule |
simplex direct |
1 |
2 |
6 |
12 |
20 |
30 |
42 |
56 |
72 |
90 |
110 |
N led=S |
multiplexage NxM |
- |
- |
2x3 |
3x4 |
4x5 |
5x6 |
6x7 |
7x8 |
8x9 |
9x10 |
10x11 |
  |
multiplexage nbre de S |
- |
- |
5 |
7 |
9 |
11 |
13 |
15 |
17 |
19 |
21 |
N led=(S/2)*(S/2-1) |
charlieplexage nbre de S |
- |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
N led=S*(S-1) |
Le cas à 72 leds est réalisé dans certains multiplexeurs de 8 afficheurs 7 segments+point.
Bien évidemment, vous réalisez qu'il va falloir faire une table pour que le programme mouline correctement ... J'ai testé avec des leds tricolores de chez LEXTRONIC (référence YSRGB7A5BSW25), en associant 4, soit 12 leds à piloter.
 | | Voici le schéma : C'est un carré (4 coins, donc 4 sorties) dont les 4 côtés et les 2 diagonales sont équipées de leds tête-bêche Bon, les couleurs sont franchement mélangées, mais on va s'en sortir : Chaque diode triple est "cathode commune", donc à chaque coin, on a 3 diodes qui arrivent (j'ai mis des numéros pour comprendre, les diodes de même numéro font partie de la même triplette) : rouge,verte,bleue, depuis les 3 autres coins : c'est ok ? |
 | | Voici le schéma résultant sous forme "breadboard" Le câblage semble compliqué, mais en fait il suffit de suivre la règle suivante, (il faut d'abord faut tordre un peu les pattes des leds pour les écarter à 7,5 mm pour les connecter au centre) : - câbler la pin N de la led courante avec la pin N+1 de la suivante (1 vers 2, 2, vers 3, 3 vers 4 et 4 vers 1) - et ceci pour les 4 leds - câbler ensuite les ports A,B,C,D respectivement à 4,3,2, et 1 de la 1° led à travers des résistances de 47 à 75 ohms. |
Avec 68 Ohms, on obtient 21 mA sur les leds ROUGE, et 14 mA sur les vertes et bleues. Ne pas dépasser 40 mA par sortie de l'ARDUINO, et 200 mA au total pour toutes les sorties.
 | | ... Et sur la breadboard ! |
 | | Voilà le résultat sur une breadboard avec un ARDUINO "autonome" Voir chapitre 07b pour l'ARDUINO autonome |
Et voici quelques bouts de programme :
// entrées-sorties
int charlie_led[4] = {5,7,10,11}; // pour charlieplexage 4 sorties = 12 leds
int charlie_i; // indice de multiplexage
// le tableau magique : 0=0volts(LOW) 1=5volts(HIGH) 2=haute_impédance(Input)
struct charlie_t { int etat[4]; } ;
struct charlie_t charliet[] = {
{0,1,2,2}, // R1
{0,2,1,2}, // V1
{0,2,2,1}, // B1
{2,0,1,2}, // R2
{2,0,2,1}, // V2
{1,0,2,2}, // B2
{2,2,0,1}, // R3
{1,2,0,2}, // V3
{2,1,0,2}, // B3
{1,2,2,0}, // R4
{2,1,2,0}, // V4
{2,2,1,0}, // B4
{2,2,2,2} // tout éteint
};// 111222333444
char* charlie_map="RVBRVBRVBRVB"; // variable de commande
// pour les 12 positions : ' '=éteinte 'R,V,B'=allumée (n'importe quel caractère autre que ' ')
char* charlie_mapv="012345678901";
// temporisations
int tempo_a,tempo_b,tempo_led;
// vitesse de clignotement : en millisecondes
int tempo_a_reset=500;
int tempo_b_reset=6000;
int tempo_led_reset=1;
....
//--------------------------------********************--------------------------------
// CHARLIPLEXAGE
if (tempo_led==0) {
// rcehreche led suivante à allumer
i=0;
do {
i++;
charlie_i++; if (charlie_i > 11) charlie_i=0;
} while ( (charlie_map[charlie_i] == ' ' && i < 12));
// led à allumer
if (charlie_map[charlie_i] != ' ') {
charlie(charlie_i);
// extinction générale
} else {
charlie(12);
}
tempo_led = tempo_led_reset;
} // tempo_led==0
//--------------------------------********************--------------------------------
}
//--------------------------------********************--------------------------------
// Sous-programmes
//--------------------------------********************--------------------------------
// commande de CHARLIPLEXAGE
void charlie(unsigned int ipos) {
int il;
for (il=0;il<4;il++) {
switch (charliet[ipos].etat[il]) {
// O volt
case 0:
pinMode(charlie_led[il], OUTPUT); digitalWrite (charlie_led[il],LOW);
break;
// 5 volts
case 1:
pinMode(charlie_led[il], OUTPUT); digitalWrite (charlie_led[il],HIGH);
break;
// haute impédance = entrée
case 2:
pinMode(charlie_led[il], INPUT);
break;
}
}
}
//--------------------------------********************--------------------------------
Explications : la boucle dite "CHARLIPLEXAGE" va scruter la chaine de caractères "charlie_map", et allumer les diodes dont le caractère n'est pas ' '. On appelle le sous-programme "charlie()" qui se charge de positionner les 4 sorties comme il faut selon la table "charliet".
La temporisation "tempo_led" est positionnée par "tempo_led_reset" dont la valeur est 1, et est décrémentée par un sous-programme qui gère le temps, à savoir chaque millisecondes (1000 hertz). Le résultat est satisfaisant.
Dernière mise à jour : 07:50:08 11/09/2013