Comment régler l’intensité lumineuse d’une LED ?

NIVEAU 2

Objectifs

  • Câbler une LED à un microcontroleur
  • Configurer un signal modulé sur une carte Nucléo pour régler l’intensité de la LED

Pré-requis

Luminosité d’une LED

Méthode analogique

Source de courant réglable

La première méthode pour modifier le courant traversant la LED est d’utiliser une source de courant. Si cette source de courant est réglable en intensité alors il sera possible de moduler l’intensité lumineuse de la LED.

Cependant, une source de courant est difficile à mettre en oeuvre. On préfère les sources de tension.

Source de tension et résistance variable

Pour transformer une source de tension en source de courant, il suffit d’ajouter une résistance à cette source de tension. On obtient une source de tension non parfaite et par transformation Thévenin/Norton, on peut ainsi obtenir une source de courant non idéale.

Les deux montages précédents permettent d’obtenir quasiment le même fonctionnement, à savoir modifier le courant transitant dans la LED par modification : a) de la résistance associée à la source de tension, b) de la tension aux bornes de l’ensemble résistance et LED.

En effet, si on s’intéresse au cas où la LED est passante (i.e. où elle émet un flux lumineux), quand le courant \(I_{LED}\) est positif et la tension aux bornes de la LED est supérieure à la tension seuil (ou directe) \(V_F\), on a alors la relation suivante : \(E = R \cdot I_{LED} + V_F\)

Le courant vaut alors \(I_{LED} = \frac{E – V_F}{R}\).

Attention Avec cette méthode, il faut garantir que le courant ne dépasse pas le courant maximal admissible par la LED. Dans la cas du montage b, il faut en plus garantir que la tension \(E\) est supérieure à la tension seuil \(V_F\) de la LED.

Pilotage numérique

Le problème de la méthode précédente est qu’il n’est pas possible de contrôler à distance l’intensité lumineuse de la LED sans avoir recours à des potentiomètres (ou résistances variables) commandables numériquement (type MCP4022 ou MAX5434). Ces potentiomètres numériques nécessitent l’utilisation d’un pilotage numérique (d’un microcontroleur par exemple). Or il existe une méthode numérique permettant de se passer de ce type de composant.

Persistance rétinienne et MLI

L’être humain est capable de voir les éléments qui l’entourent, grâce à ses yeux, qui captent les informations depuis l’extérieur, et son cerveau, qui traite ces données acquises. Or comme tout système de “traitement” de l’information, il a ses limites :

  • les longueurs d’onde que l’oeil est capable de transmettre
  • la fréquence maximale des événements que le cerveau est capable de traiter

Si on prend l’exemple du cinéma, les images diffusées se font au rythme de 24 images/seconde. A cette fréquence là (i.e. 24 Hz), le cerveau humain est biaisé et n’arrive pas à distinguer deux images successives. Ce que nous voyons est une suite de mouvements fluides. De la même façon, beaucoup d’éléments autour de nous “clignotent” : les écrans d’ordinateur (60 ou 70 Hz), les smartphones (autoud de 100 Hz), les néons (100 Hz)…

En utilisant le principe de la modulation de largeur d’impulsions et en appliquant le signal résultant sur une LED, celle-ci va donc s’allumer durant le temps haut du signal et s’éteindre le reste de la période.

Si ce signal est appliqué avec une fréquence suffisamment élevée pour que l’être humain ne distingue plus l’allumage et l’extinction de la LED, ce dernier verra alors une LED constamment allumée avec une intensité lumineuse variant en fonction du rapport cyclique.

Câblage d’une LED

Pour ce faire, on peut utiliser l’un des câblages suivants pour une LED standard (i.e. dont le courant nominal est de l’ordre du courant admissible par le microcontroleur qui génère le signal PWM) :

Dans le montage 1, un signal modulé de polarité normale, i.e. le temps actif est le temps à l’état haut, permet d’avoir une luminosité au niveau de la LED qui est proportionnel au rapport cyclique (défini par le rapport du temps haut sur la période du signal).
Dans le montage 2, un signal modulé de polarité inversée, i.e. le temps actif est le temps à l’état bas, permet d’avoir une luminosité au niveau de la LED qui est proportionnel au rapport cyclique (défini par le rapport du temps haut sur la période du signal).

Câblage d’une LED de puissance

Parfois, on souhaite piloter des LED de puissance par ce principe. Les microcontrôleurs ne sont cependant pas capables de fournir beaucoup de courant pour commander ce type d’éléments (typiquement les sorties des microcontroleurs sont capables de fournir des courants de l’ordre de la dizaine de milliampères, pour des tensions de l’ordre du volt).

Pour pouvoir les contrôler, il est alors nécessaire de passer par des éléments qui amplifient le courant : des transistors.

Un transistor est un composant à trois broches qui permet d’amplifier un courant soit à partir d’un autre courant plus faible (ce sont des transistors dits bipolaires – NPN, PNP…) soit à partir d’une tension de commande (ce sont des transistors à effet de champs – MOS, JFET, MOSFET…).

Le montage que l’on peut utiliser est le suivant (avec un transistor MOSFET de type IRF540A) :

Sur ce montage, lorsque la sortie D10 est à ‘0’, le transistor n’est pas commandé, il se comporte alors comme un circuit ouvert entre les broches nommées D et S. Il n’y a pas de courant qui passe dans la branche de la LED. Elle est donc éteinte.
Lorsque la sortie D10 est à ‘1’, le transistor est commandé, il se comporte alors comme un circuit fermé entre les broches nommées D et S. Il y a passage de courant dans la branche de la LED. Elle est donc allumée.

La résistance \(R\) est une résistance d’une dizaine de kiloohms, permettant d’assurer le passage d’un courant minimal sur la sortie D10.

N.B. Il existe également des composants tout intégré qui sont constitués de transistors bipolaires (ou MOS pour certains) montés en Darlington (amplification en courant plus importante) de type ULN2804.

Exemple de réalisation

On propose d’appliquer sur une LED rouge standard un signal MLI piloté par le programme suivant à l’aide d’une carte Nucléo :

#include "mbed.h"

PwmOut ma_sortie_pwm(D10);
double rc;

int main() {
    rc = 0;
    ma_sortie_pwm.period_ms(10);
    while(1){
        rc += 0.1;
        if(rc > 1)  rc = 0;
        ma_sortie_pwm.write(rc);
        wait_us(200000);
    }
}

Dans ce programme, on initialise une sortie PWM avec une période de 10ms et un rapport cyclique nul. Dans la boucle infinie, on incrémente ce rapport cyclique de 10% toutes les 200 ms. On obtient alors une rampe de luminosité sur la LED, entre 0 et 100% par pas de 10%, changeant toutes les 200ms.

LEDs RGB Pilotables

Exemple d’un arc de cercle de 15 LEDs (4 arcs de cercle = 60 Leds… = 1 heure ?)

LED WS2812

Les LEDs de type WS2812 sont la combinaison de 3 LEDs trichromes (rouge, verte et bleue) et d’un circuit de commande numérique (registres à décalage et PWM pour chacune des couleurs).

Elles se pilotent donc en numérique par le biais d’une trame binaire de 8 bits par couleur (vert, rouge, bleu – 256 niveaux par couleur), soient 24 bits au total.

Les ‘0’ et les ‘1’ sont codés de la façon suivante :

Les temps haut et bas sont quantifiés : T0H = 0.35us / T0L = 0.8us / T1H = 0.7us / T1L = 0.6us / RES > 50 us.

L’intérêt de ces modules de LED est la possibilité de les mettre en cascade :

Ainsi, on peut transmettre une suite de N x 24 bits successifs pour pouvoir contrôler l’intégralité des N LEDs.

ATTENTION Il existe des matrices de LED basées sur des LED de type SK6812, qui se programme de la même façon que les WS2812, à ceci prêt qu’il faut envoyer 32 bits par LED et non 24 bits. Le dernier octet à émettre est vide (‘0’), mais il faut l’émettre 🙂

Utilisation sous MBED

L’exemple d’application suivant est réalisé autour d’une carte Nucléo L476RG : https://os.mbed.com/teams/IOGS_France/code/EITI_Neopixel/

Bibliothèques nécessaires

Pour pouvoir utiliser cet exemple, les deux bibliothèques suivantes sont nécessaires (à importer) :

Bibliothèque PixelArray

La bibliothèque PixelArray permet de créer et de mettre à jour un tableau de pixels de 3 octets (RGB).
Il est créé à l’aide de la commande suivante :

PixelArray px(10);

L’objet px est alors un tableau de 10 pixels contenant chacun les champs : (R)ed (B)lue (G)reen.

Il est alors possible de modifier chacun de ces pixels à l’aide de 3 fonctions :

void SetR(int i, int val);
void SetB(int i, int val);
void SetG(int i, int val);

qui permettent respectivement de changer la couleur rouge (SetR), la couleur bleu (SetB) et la couleur verte (SetG) de la LED numéro i (la première ayant le numéro 0 et la dernière N-1) avec la valeur val comprise entre 0 et 255 (0 = 0% – 255 = 100%).

Par exemple, pour mettre la couleur R = 20% – B = 40% – G = 20% sur la troisième LED, on peut utiliser les instructions suivantes :

px.SetR(2, 20*255/100.0); px.SetB(2, 40*255/100.0); px.SetG(2, 20*255/100.0);

Sur les versions White des LED, la fonction SetI permet de rajouter du blanc.

Il est également possible d’aller lire chacune des valeurs des pixels grâce aux commandes :

int GetR(int i);
int GetB(int i);
int GetG(int i);

qui permettent respectivement de récupérer la couleur rouge (SetR), la couleur bleu (SetB) et la couleur verte (SetG) de la LED numéro i (la première ayant le numéro 0 et la dernière N-1).

Pour récupérer la valeur rouge de la 5ème LED, il faudra par exemple faire :

int k = px.GetR(4);

Bibliothèque WS2812

La bibliothèque WS2812 permet de mettre à jour la matrice de LED en respectant le protocole demandé par le fabricant de ces LED.
Il est créé à l’aide de la commande suivante :

WS2812 ws(D9, NB_LED, 3, 12, 9, 12);

L’objet ws permet alors de piloter un bandeau de NB_LED LEDs sur la broche D9 de la carte Nucléo. Les valeurs qui suivent permettent de respecter les contraintes de temps imposées par le fabricant pour la carte Nucléo L476RG.

Pour les versions White des LED, il est nécessaire d’utiliser la bibliothèque WS2812 modifiée et d’ajouter le paramètre 1 à la fin de l’initialisation.

WS2812 ws(D9, NB_LED, 3, 12, 9, 12, 1);

Il est indispensable d’initialiser la matrice à l’aide de la commande suivante :

ws.useII(WS2812::GLOBAL);

pour pouvoir modifier de manière globale la luminosité de l’ensemble des LEDs.

On peut alors utiliser la commande suivante pour modifier globalement l’intensité des LEDs avec une valeur val comprise entre 0 et 255 :

void setII(int val);

Par exemple, pour limiter la luminosité à 100 sur 255 l’intensité du bandeau, on peut utiliser la commande suivante :

ws.setII(100);

Enfin, il faut pouvoir transmettre l’ensemble des informations aux différentes LEDs. Pour cela, il faut utiliser la fonction suivante :

void write(int tab[]);

où le paramètre est un tableau de N entiers, pouvant correspondre à un objet de type PixelArray.

Exemple d’application

Ne prêtez pas attention à mes qualités d’artiste pour ce code… Je me suis contenté de faire un exemple fonctionnel sur un arc de cercle de 15 LED.

Jpeg

Pour la partie artistique, laissez libre cours à votre imagination… Et n’hésitez pas à m’envoyer vos meilleurs programmes !

#include "mbed.h"
#include "PixelArray.h"
#include "WS2812.h"

#define NB_LED  15    // Nombre de LEDs en cascade

// Variables globales 
PixelArray px(NB_LED);           // Tableau de pixels / Nb de LEDs en cascade
// For Nucleo F476 : 3, 12, 9, 12
WS2812 ws(D9, NB_LED, 3, 12, 9, 12);    // Lien vers la série de LEDs / Sortie utilisée-Nb de LEDs
// NE PAS MODIFIER LES 4 DERNIERS PARAMETRES

int main() {
    int i, k = 0;
    ws.useII(WS2812::GLOBAL);  // Initialisation de la liaison avec les LEDs
    ws.setII(0);               // Luminosité maximale à 0/255
    
    // Reinitialisation ecran
    for (i = 0; i < NB_LED; i++) {
        px.Set(i, 0);
    }  
    ws.write(px.getBuf());      // Mise à jour de la matrice
    ws.setII(30);               // Luminosité maximale à 30/255

    while(1) {
        for(i = 0; i < NB_LED; i++){
            px.SetR(i, k);
        }
        ws.write(px.getBuf());   // Mise à jour de la matrice
        if(k == 255) k = 0;
        else k++;
        wait_us(200000);               // 200 ms
    }
}

Tutoriel lié

MInE Prototyper Prototyper avec Nucleo et MBED

Nucléo – Régler l’intensité lumineuse d’une LED