Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

Avant les vacances de Noël, un collègue me posait une colle: il venait d'installer une guirlande électrique utilisant des LEDs de deux couleurs différentes. La guirlande était munie d'un boitier de commande permettant de l'illuminer dans une couleur, dans l'autre, ou dans les deux à la fois. Où cela était surprenant, c'est qu'il n'y avait que deux fils pour relier les LEDs entre elles.

Je dois avouer que je n'ai pas été bon, car je n'ai pas percuté sur le coup. Par contre en y repensant ce soir là, une solution simple m'est venue en tête. Je ne sais pas si c'est la technique employée sur la décoration en question, mais dès mon retour à la maison, j'ai fait une petite maquette avec une carte Arduino Nano…

La théorie

Illuminer une DEL ou l'autre

Flot du courant entre les broches selon leur état logique
D9
Hi Lo
D8 Hi D8→D9
Lo D9→D8

Avant de vous donner la soluce un peu de théorie pour expliquer pourquoi cela va fonctionner avec ma carte Arduino. Cette carte est basée sur une technologie CMOS. Celle-ci se caractérise notamment par le fait que les sorties logiques sont connectées rail-to-rail à Vcc et la masse. Autrement dit, une sortie logique se comporte virtuellement comme un interrupteur SPDT (simple-pole double-throw). La conséquence est qu'une telle sortie est capable aussi bien de fournir du courant (source current) que d'en drainer (sink current).

D'accord, si vous avez la moindre notion en électronique numérique, rien de nouveau sous le soleil. Considérons maintenant non pas une, mais deux sorties logiques. Par exemple les broches D8 et D9 de ma carte Arduino. Ce qui nous donne les quatre combinaisons possibles résumées dans le tableau ci-contre. Comme vous le voyez, dans deux cas, il n'y a pas d'écoulement du courant électrique. Au contraire, les deux autres permettent le flot du courant, dans un sens pour l'un et dans l'autre pour le second.

Évidement, il devient possible d'exploiter cela en connectant deux DELs tête-bèche entre ces bornes. Selon le sens d'écoulement du courant – correspondant aux combinaisons D[8:9]=01 ou D[8:9]=10 – l'une ou l'autre sera illuminée.

DEL tête bêche.png

Multiplexage de LEDs — Lorsque l'on connecte deux LEDs tête-bêche entre deux sorties logiques, il devient possible d'illuminer l'une ou l'autre (ou aucune des deux) en fonction des différentes combinaisons logiques.


Illuminer les deux DELs à la fois

Intéressant, mais si j'en reviens au problème initial, il reste la question de comment illuminer simultanément les deux DELs. La réponse est simple: c'est impossible. Déçu? Relisez donc attentivement ces dernières phrases: je dis qu'il est impossible d'illuminer simultanément les deux DELs de ce montage. Par contre, ce que l'on peut faire, c'est illuminer alternativement l'une puis l'autre dans un cycle suffisamment rapide pour que l'œil humain ne distingue plus le clignotement. Généralement, on a tendance à considérer que la persistance rétinienne de l'œil humain est de l'ordre de 1/25 de seconde (25 Hz), puisque c'est la vitesse retenue pour le cinéma. Dans la réalité, pour des applications d'éclairage, la modulation reste perceptible bien au delà. Par conséquent une fréquence de l'ordre de 1 kHz est plus souvent admise pour un résultat de qualité.

La pratique

LED Mux montage.png

Montage de deux LEDs tête-bêche entre deux sorties logiques

Le montage qui permet de valider expérimentalement les explications que je donnais plus haut est représenté ci-contre. Il suffit de monter deux DELs en parallèle, en prenant juste soin de placer les deux DELs dans un sens différent.

J'ai reproduis ci-dessous le code source correspondant à ce montage:

void setup() {                
  // initialiser en sortie les broches 8 et 9
  pinMode(8, OUTPUT);     
  pinMode(9, OUTPUT);     
}
 
void loop() {
  unsigned int DELAY = 50000;
 
  // Génère un signal carré entre les broches 9 et 8
  // (rapport cyclique 25% Vmin = 0V, Vmax = +Vcc) 
  for (unsigned int i = 0; i < DELAY; ++i) {
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(8, HIGH);
    digitalWrite(8, LOW);
  }
 
  // Génère un signal carré entre les broches 9 et 8
  // (rapport cyclique 25% Vmin = -Vcc, Vmax = 0V) 
  for (unsigned int i = 0; i < DELAY; ++i) {
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);
  }
 
  // Génère un signal carré entre les broches 9 et 8
  // (rapport cyclique 25% Vmin = -Vcc, Vmax = +Vcc) 
  for (unsigned int i = 0; i < DELAY; ++i) {
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(9, HIGH);
  }
}

Bon, le code n'a rien d'extraordinaire. Il illumine une LED, puis l'autre, et enfin les deux. Vous voyez aussi que je me contente de boucler un certain nombre de fois plutôt que d'armer un timer. Sur mon Arduino Nano, chaque boucle dure un peu moins d'une seconde. À raison de 50000 itérations par boucle, cela met la fréquence de mon signal de modulation un peu au dessus de 50 kHz – largement au delà du seuil de perception de l'œil humain.

Vous remarquerez aussi que je prends la peine de faire à chaque fois 4 appels à digitalWrite – même si ce n'est pas indispensable pour illuminer juste une LED. Je procède ainsi pour deux raisons:

  1. garantir (peu ou prou) que chaque étape ait la même durée;
  2. pour produire un rapport cyclique de 25% même lorsqu'une seule LED est allumée. Cela permet d'obtenir la même intensité lumineuse qu'une seule LED soit allumée, ou que les deux soient multiplexées.

Pourquoi 25%?

Oscillogramme LED mux.png

Au premier abord, on peut se demander pourquoi je vise un rapport cyclique de 25% et non pas de 50%. Après tout, au pire, j'ai deux LEDs à multiplexer. Elles pourraient être illuminées chacune la moitié du temps, non?

En réalité ce n'est pas si simple: puisque j'utilise la fonction digitalWrite, je suis obligé de commuter les deux broches D8 et D9 l'une après l'autre. Autrement dit, à chaque basculement, il y a systématiquement une phase où deux DELs sont éteintes simultanément. C'est ce que confirme l'oscillogramme ci-contre capturé justement lorsque les deux LEDs sont multiplexées. En fait, on constate qu'en réalité chaque LED n'est allumée que 25% du temps.

Rien à voir, mais pour être complet, l'asymétrie entre la phase positive (à quasiment +3V) et la phase négative (environ -2V) que vous pouvez observer sur cet exemple est causée par le fait que j'utilise dans mon montage deux DELs de couleurs différentes – et donc avec des tensions de seuil différentes.

Conclusion

Visuellement, le résultat est convainquant: une LED s'allume, puis l'autre, puis on a l'impression que les deux s'allument simultanément. Bien entendu, pas question d'alimenter une guirlande complète avec ce montage. Le principe est valable, mais l'Arduino ne peut pas fournir directement assez de courant.

Pour aller plus loin, il est possible d'envisager l'ajout de quelques transistors de puissance afin de piloter plus de LED. Si vous n'êtes pas à l'aise en électronique analogique, on trouve également des circuits spécialisés comme le ULN2068B de STMicroelectronics. Ce circuit contient essentiellement 4 darlingtons indépendants et est capable de délivrer 1,5A sous 35V en continu. Par ailleurs, ce modèle est conçu pour limiter la charge capacitive sur le circuit de contrôle numérique. À $2,70 pièce, ça ne vaut pas tellement le coup de s'en priver. Par contre, ce circuit se comporte comme 4 interrupteurs SPST (simple-pole simple-throw). Autrement dit, vous ne pourrez pas basculer directement une sortie de Vcc à la masse ou inversement. Il faudra agir en deux temps selon une logique break-before-make. Ce problème est résolu par le MAX333A, qui appartient à la famille des commutateurs analogiques (analog switches) SPDT. En l'occurrence, ce circuit intègre 4 commutateurs pouvant fournir plus modestement 20mA en continu sous environ 40V. Mais cela reste largement assez pour un vingtaine de LED en série… Bref les possibilités ne manquent pas pour piloter un réseau de LEDs – et toujours avec seulement deux fils. Que voilà un projet intéressant pour Noël prochain!

Circuit Description Caractéristiques Prix indicatif (HT)
ULN2068B STMicroelectronics 4× commutateur Darlington 35V 1,5A 1µs (montée) $2,70
MAX333A Maxim 4× commutateur analogique CMOS SPDT 44V 20mA 145ns (montée) $8,40