Animer des LEDs RGB avec un Yocto-Color-V2

Animer des LEDs RGB avec un Yocto-Color-V2

Lors de l'annonce du Yocto-Color-V2, nous avons expliqué que cette nouvelle version est capable de piloter jusqu'à 146 LEDs NeoPixel. Cependant, pour utiliser cette nouvelle fonctionnalité, il faut utiliser une nouvelle API que nous allons découvrir dans cet article.





Le Yocto-Color fournissait deux fonctions ColorLed, une pour chaque LED. Comme le nombre de LEDs NeoPixel branchées au Yocto-Color-V2 peut aller jusqu'à 146, il n'a pas été possible d'avoir 146 fonctions ColorLed. Pour des raisons de rétrocompatibilité, le Yocto-Color-V2 possède toujours deux fonctions ColorLed pour les deux LEDs présentes sur le board, mais le module utilise une nouvelle fonction ColorLedCluster qui permet de contrôler toutes les LEDs branchées.

La fonction ColorLedCluster est une fonction qui est compliquée car elle permet à la fois de gérer les LEDs et les séquences. Avant d'expliquer comment fonctionnent les séquences, examinons comment contrôler chaque LED.

Attribuer une couleur à une LED


La méthode set_rgbColor() permet d'affecter une couleur RGB à n'importe quelle LED. L'exemple suivant donne la couleur rouge à la première LED, la couleur verte à la deuxième LED et la couleur bleue à la troisième LED.

ledCluster.set_rgbColor(0, 1, 0xff0000);
ledCluster.set_rgbColor(1, 1, 0x00ff00);
ledCluster.set_rgbColor(2, 1, 0x0000ff);



Il est possible d'affecter et de lire les valeurs des LEDs en bloc à l'aide des méthodes set_rgbColorArray() et get_rgbColorArray():

ArrayList<Integer> rgbValues = new ArrayList<>();
rgbValues.add(0xff0000);
rgbValues.add(0x00ff00);
rgbValues.add(0x0000ff);
ledCluster.set_rgbColorArray(0, rgbValues);
...
rgbValues = ledCluster.get_rgbColorArray(0, 146);



Il est aussi possible de travailler avec l'espace de couleur HSL à l'aide des méthodes set_hslColor(), set_hslColorArray() et get_hslColorArray().

ledCluster.set_hslColor(0, 1, 0x00ff80);
...
ArrayList<Integer> hslValues = new ArrayList<>();
hslValues.add(0x00ff80);
hslValues.add(0x55ff80);
hslValues.add(0xf0ff80);
ledCluster.set_hslColorArray(0, hslValues);



On peut effectuer une transition douce vers une couleur à l'aide des méthodes rgb_move() et hsl_move(). Ces deux méthodes fonctionnent comme set_rgbColor() et set_hslColor() mais prennent un quatrième argument qui est la durée de la transition.

L'exemple suivant effectue une transitions du noir vers le rouge en 500 millisecondes, puis vers le bleu en une seconde.

ledCluster.set_rgbColor(0, 146, 0);
// transition to red
ledCluster.rgb_move(0, 146, 0xff0000, 500);
YAPI.Sleep(500);
// transition to blue
ledCluster.rgb_move(0, 146, 0x0000ff, 1000);



Toutes ces fonctions changent l'état courant des LEDs, mais il est aussi possible de modifier la couleur des LEDs au démarrage du module. Cela peut être fait avec la méthode set_rgbColorAtPowerOn() qui, au lieu d'appliquer directement la couleur aux LEDs concernées, change la valeur par défaut des LEDs. Cette valeur par défaut est la couleur qui va être appliquée dès que le module est alimenté. Il faut impérativement sauver ces modifications à l'aide de la méthode saveLedsConfigAtPowerOn(), sinon les changements seront perdus.

ledCluster.set_rgbColorAtPowerOn(0, 1, 0xff0000);
ledCluster.set_rgbColorAtPowerOn(1, 1, 0x00ff00);
ledCluster.set_rgbColorAtPowerOn(2, 1, 0x0000ff);
ledCluster.saveLedsConfigAtPowerOn();



Les séquences


Les séquences sont une des nouveautés de ce module. Elles permettent de créer des animations qui sont entièrement gérées par le Yocto-Color-V2. Cela permet de simplifier l'écriture du programme et d’obtenir des animations très fluides même avec des machines peu réactives.

Avant d'examiner plus en détails l'API de programmation des séquences, il faut expliquer son fonctionnement. Une séquence est simplement une suite de transitions de couleurs à appliquer à une ou plusieurs LEDs. Une transition est définie par trois paramètres:

  • L'espace de couleur à utiliser
  • la couleur finale
  • sa durée en ms


Les fonctions addRgbMoveToBlinkSeq() et addHslMoveToBlinkSeq() permettent respectivement d'ajouter une transition RGB ou HSL à une séquence. Ces deux fonctions prennent en argument le numéro de la séquence, la couleur de destination, et la durée de la transition.

Par exemple, pour faire alterner une LED entre le bleu et le rouge, il suffit de créer la séquence suivante:

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 1000);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000ff, 1000);



La méthode resetBlinkSeq() ré-initialise la séquence 0, le premier appel à addRgbMoveToBlinkSeq() représente la transition vers le rouge en 1 seconde, et le deuxième appel représente la transition vers le bleu.

Il est ensuite possible de déclencher l’exécution de la séquence à l'aide de la méthode startBlinkSeq() qui permet d’exécuter la séquence en boucle.

Mais aucune LED ne va s'allumer car aucune LED n'est liée à cette séquence. Pour qu'une LED joue cette séquence, il faut qu'on lui assigne la séquence à jouer à l'aide le la fonction linkLedToBlinkSeq(). Le premier paramètre de cette méthode est l'index de la première LED, le deuxième paramètre est le nombre de LEDs, le troisième est le numéro de la séquence à jouer, enfin le dernier paramètre est un décalage temporel.

L'exemple complet est donc le suivant:

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 1000);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000ff, 1000);
ledCluster.linkLedToBlinkSeq(0, 146, 0, 0);
ledCluster.startBlinkSeq(0);



Ce code crée la séquence, assigne cette séquence à toutes les LEDs, et démarre la séquence. Il est possible d'avoir jusqu'à 8 séquences qui sont exécutées en même temps. Cependant, une LED ne peut être liée qu'à une seul séquence à la fois.

L'exemple suivant crée deux séquences et assigne la première aux 10 premières LEDs et la deuxième aux 15 LEDs suivantes.

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 1000);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000ff, 1000);
ledCluster.resetBlinkSeq(1);
ledCluster.addRgbMoveToBlinkSeq(1, 0x0ff000, 1000);
ledCluster.addRgbMoveToBlinkSeq(1, 0x0000ff, 1000);
ledCluster.linkLedToBlinkSeq(0, 10, 0, 0);
ledCluster.linkLedToBlinkSeq(10, 15, 1, 0);
ledCluster.startBlinkSeq(0);
ledCluster.startBlinkSeq(1);



Tout comme pour les couleurs statiques, il est possible de configurer la séquence par défaut pour une LED. Dans un premier temps, il faut modifier la séquence pour qu'elle soit exécutée automatiquement au démarrage du module. C'est le travail de la méthode set_blinkSeqStateAtPowerOn(). Il faut aussi enregistrer cette séquence sur la flash à l'aide de la méthode saveBlinkSeq.

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 1000);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000ff, 1000);
ledCluster.set_blinkSeqStateAtPowerOn(0, 1);
ledCluster.saveBlinkSeq(0);



Ensuite, il faut utiliser la méthode linkLedToBlinkSeqAtPowerOn() pour lier une ou plusieurs LEDs à cette séquence. Il faut aussi appeler la méthode saveLedsConfigAtPowerOn() pour sauver la configurations des LEDs sur la flash.

ledCluster.linkLedToBlinkSeqAtPowerOn(0, 146, 0, 0);
ledCluster.saveLedsConfigAtPowerOn();



Les séquences avancées


Maintenant que nous avons expliqué le fonctionnement de base des séquences, regardons ce que nous pouvons réaliser avec ces fonctions, plus particulièrement lorsque que l'on joue avec le quatrième paramètre de la fonction linkLedToBlinkSeq().

Pour l'instant, nous avons toujours synchronisé les LEDs, c'est-à-dire que toutes les LEDs qui jouent une même séquence affichent la même couleur en même temps.

Exécution d'une séquence automatique rouge-bleu avec une période de 2 secondes
Exécution d'une séquence automatique rouge-bleu avec une période de 2 secondes



Il est possible de désynchroniser les LEDs en spécifiant un offset à l'appel de la méthode linkLedToBlinkSeq(). Si un offset est définit, les LEDs exécutent toujours la même séquence mais avec un décalage. Le code ci-dessous affecte la LED 0 à la séquence 0 avec un offset de 0ms, puis affecte la LED 1, toujours à la séquence 0 mais avec un offset de 500ms. Ce qui donne l’impression que la couleur rouge se déplace d'une LED à l'autre.

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 500);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000ff, 500);
ledCluster.linkLedToBlinkSeq(0, 1, 0, 0);
ledCluster.linkLedToBlinkSeq(1, 1, 0, 500);
ledCluster.startBlinkSeq(0);



Exécution de la séquence précédente avec un offset de 1 sec entre les deux LEDs
Exécution de la séquence précédente avec un offset de 1 sec entre les deux LEDs



Les offsets dans l'exécution permettent de faire des effets de chenillard très spectaculaires.

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000FF, 0);
ledCluster.addRgbMoveToBlinkSeq(0, 0x00000, 200);
ledCluster.addRgbMoveToBlinkSeq(0, 0x000000, 400);
for (int i = 0; i < 60; i++) {
    ledCluster.linkLedToBlinkSeq(i, 1, 0, 30 * i);
}
ledCluster.startBlinkSeq(0);



Les offsets dans l'exécution permettent de faire des effets de chenillard très spectaculaires
Les offsets dans l'exécution permettent de faire des effets de chenillard très spectaculaires



Il est aussi possible de changer et même d'inverser la vitesse d’exécution d'une séquence à l'aide de la méthode set_blinkSeqSpeed().

ledCluster.set_blinkSeqSpeed(0, 1000);
YAPI.Sleep(2000);
ledCluster.set_blinkSeqSpeed(0, 500);
YAPI.Sleep(1000);
ledCluster.set_blinkSeqSpeed(0, 0);
YAPI.Sleep(1000);
ledCluster.set_blinkSeqSpeed(0, -500);
YAPI.Sleep(1000);
ledCluster.set_blinkSeqSpeed(0, -1000);



Cela permet de créer très facilement des effets de ralenti ou d'inversion.

Voici quelques exemples de séquences et leur résultat:

ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0xff0000, 0);
ledCluster.addRgbMoveToBlinkSeq(0, 0x000000, 100);
ledCluster.addRgbMoveToBlinkSeq(0, 0x000000, 200);
ledCluster.resetBlinkSeq(1);
ledCluster.addRgbMoveToBlinkSeq(1, 0x000000, 0);
ledCluster.addRgbMoveToBlinkSeq(1, 0x000000, 200);
ledCluster.addRgbMoveToBlinkSeq(1, 0x00ff00, 100);
for (int i = 0; i < 30; i++) {
    ledCluster.linkLedToBlinkSeq(i, 1, 0, 10 * i);
}
for (int i = 0; i < 30; i++) {
    ledCluster.linkLedToBlinkSeq(30 + i, 1, 1, 10 * i);
}
ledCluster.set_blinkSeqSpeed(0, 200);
ledCluster.set_blinkSeqSpeed(1, -200);
ledCluster.startBlinkSeq(0);
ledCluster.startBlinkSeq(1);





ledCluster.resetBlinkSeq(0);
ledCluster.addRgbMoveToBlinkSeq(0, 0x0000FF, 100);
ledCluster.addRgbMoveToBlinkSeq(0, 0x000000, 100);
ledCluster.addRgbMoveToBlinkSeq(0, 0x000000, 400);
for (int i = 0; i < 60; i++) {
    ledCluster.linkLedToBlinkSeq(i, 1, 0, 10 * i);
}
ledCluster.startBlinkSeq(0);
ledCluster.set_blinkSeqSpeed(0, 0);
YAPI.Sleep(1000);
ledCluster.set_blinkSeqSpeed(0, 1000);
YAPI.Sleep(1000);
ledCluster.set_blinkSeqSpeed(0, 750);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, 500);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, 250);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, 0);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, -250);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, -500);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, -750);
YAPI.Sleep(500);
ledCluster.set_blinkSeqSpeed(0, -1000);





Vous avez maintenant toutes les cartes en main pour préparer vos prochaines guirlandes de Noël :-)

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.