Il faut bien reconnaître que la semaine dernière, on a un peu bâclé le sapin de Noël USB. C'était rigolo de faire clignoter des leds de couleur, mais ça faisait quand même beaucoup de modules Yocto-Color à connecter pour un résultat assez semblable à celui d'une guirlande achetée 10 francs à la Migros du coin. Alors histoire de rattraper un peu le coup, on a décidé d'améliorer le concept...
On ne va pas toucher au sapin, on va juste améliorer le logiciel de contrôle. L'idée étant de passer de la musique et de faire en sorte que le sapin s'illumine vraiment au même rythme que la musique. Normalement, pour faire cela, il faudrait capturer le flux audio et calculer une transformée de Fourier pour identifier les pointes dans chaque gamme de fréquence. Bref, pas vraiment le genre chose qui se code en cinq minutes. Alors on va utiliser une autre approche: on va s'appuyer sur Winamp. Winamp est un media-player comme il en existe tant d'autres, mais il a été conçu pour permettre facilement l'ajout de plug-ins de visualisation.
Améliorons le concept du sapin USB...
On va coder le plug-in de visualisation en Delphi, en partant du travail de Jan Horn qui a écrit un tutorial expliquant comment développer un plug-in de visualisation pour Winamp en Delphi. En gros, Winamp, en plus de jouer de la musique, se charge de calculer la transformée de Fourier et envoie régulièrement au plug-in les valeurs correspondant à chaque bande de fréquences. Le plugin n'a plus qu'à utiliser ces données pour gérer l'affichage. Dans notre cas, pour un affichage des plus basiques, on va simplement assigner à chaque bande de fréquence une couleur et quelques leds choisies parmi les Yocto-Color sur le sapin.
Une fois encore, le code spécifique aux modules Yoctopuce est relativement court: il y a deux parties importantes: à l'initialisation du plug-in, on fait l'inventaire des leds RGB présentes.
var
errmsg:string;
led:TyColorLed;
begin
// init yoctopuce API
if (yRegisterHub('usb', errmsg)<>YAPI_SUCCESS) then
begin
MessageBox(0,pchar(errmsg), 'Error', MB_OK or MB_ICONERROR);
InitYoctoLeds :=false;
exit;
end;
yDisableExceptions(); // no exceptions, thank you
// enumerate all leds, we store all leds objects in a list
leds:=tlist.create();
led := yFirstColorLed();
while (led<>nil) do
begin
leds.add(led);
led:=led.nextColorLed();
end;
InitYoctoLeds :=true;
end;
Et lorsque Winamp nous appelle pour qu'on rafraîchisse l'interface de notre plug-in de visualisation, on calcule la luminosité que l'on désire donner à nos leds, on envoie les commandes et c'est tout.
begin
...
Les couleurs sont calculées est placées dans un tableau color[0..ColorsCount];
L'interface est redessinée, y'a plus qu'a gérer les leds.
...
for j:=0 to 1 do
begin
i:=j; // first even indexes then odd ones
while (i<leds.count) do
begin
TYcolorLed(leds[i]).set_HslColor( color [i mod ColorsCount] );
inc(i,2);
end;
end;
end;
Il y a juste une petite subtilité: lorsque l'on envoie un ordre à un module Yoctopuce il reste occupé pendant quelques milli-secondes. On peut bien sûr continuer à lui envoyer des ordres, mais les appels suivants vont rester bloquants le temps que le module soit à nouveau disponible. Comme il y a deux leds par module, la requête correspondant à la deuxième led devrait attendre que le module soit disponible après avoir traité celle correspondant à la première led. Dans la plupart des applications ce n'est pas un problème, mais ici on cherche aller le plus vite possible. C'est pourquoi on allume d'abord les leds paires, puis ensuite les led impaires, ce qui entrelace les appels, et évite de perdre du temps en attente. Ainsi, on arrive à mettre à jour les 22 leds du sapin en 30ms environ.
Ok, l'interface n'est pas des plus sexy, mais ce n'était pas le but: on a fait au plus simple
Et voila le résultat en vidéo, c'est quand même autre chose qu'une guirlande à 10 balles, non ?
Si vous possédez au moins un Yocto-Color et que vous avez envie d'essayer, vous pouvez télécharger le plug-in ainsi que les sources. Amusez-vous bien, et Joyeux Noël !