Zápisník experimentátora
Hierarchy: ShiftPWM
V tomto článku nájdete popis algoritmu, ktorý vytvorí psychedelické prechody farieb pomocou RGB LED diód. Ako to vyzerá sa popisuje ťažšie, preto si pozrite video na konci článku, kde sa tieto farby plynule menia. Toto bol prvý experiment na danom poli a preto je výsledok trochu iný, ako som čakal. Využívam totiž náhodné nastavenie farieb a veľmi často sa mi stalo, že výber farieb na oboch koncoch osmice diód bol tak blízky, že sa žiaden psychedelický prechod nekonal. Ale poďme pekne od začiatku.
Na vytvorenie efektu využijeme dve dosky z predchádzajúceho článku. V ňom je popísané ich vyrobenie a spôsob zapojenia. Okrem toho som použil ešte aj:
Algoritmus je navrhnutý tak, aby striedavo vypočítal náhodnú farbu na jednom alebo druhom konci a plynule animoval prechod z predchádzajúcej farby. Takto sa každé dve sekundy jedna strana plynule pretransformuje na novú farbu a celý algoritmus sa opakuje. V článku nebudem popisovať základné nastavenie knižnice ShiftPWM, ten nájdete v predchádzajúcom článku.
Pretože pracujeme s RGB hodnotami, je vhodné si na tie účely zadefinovať štruktúru. Budeme potrebovať tri dvojice takýchto štruktúr, aby sme mohli celý algoritmus realizovať. Premenná v
obsahuje aktuálne vypočítanú hodnotu na oboch koncoch. Premenná val
obsahuje najnovšiu dvojicu RGB farieb. Je to cieľ, ku ktorému sa postupne farba približuje. Premenná oldval
obsahuje predchádzajúcu dvojicu a od nej sa farba vzďaľuje. Premenná side
nadobúda dve hodnoty a hovorí nám, na ktorej strane máme vypočítať novú RGB hodnotu.
struct rgb {
int r;
int g;
int b;
};
rgb v[2];
rgb val[2];
rgb oldval[2];
int side=0;
Vo funkcii loop
vykonávame tieto výpočty:
oldval
poznačíme poslednú vypočítanú hodnotu.
void loop()
{
if(side==0) {
val[0].r=random(255);
val[0].g=random(255);
val[0].b=random(255);
} else {
val[1].r=random(255);
val[1].g=random(255);
val[1].b=random(255);
}
for(int j=0;j<100;j++) {
v[0].r=map(j,0,99,oldval[0].r,val[0].r);
v[0].g=map(j,0,99,oldval[0].g,val[0].g);
v[0].b=map(j,0,99,oldval[0].b,val[0].b);
v[1].r=map(j,0,99,oldval[1].r,val[1].r);
v[1].g=map(j,0,99,oldval[1].g,val[1].g);
v[1].b=map(j,0,99,oldval[1].b,val[1].b);
for(int i=0;i<8;i++)
SetRGB(i,
map(i,0,7,v[0].r,v[1].r),
map(i,0,7,v[0].g,v[1].g),
map(i,0,7,v[0].b,v[1].b));
delay(20);
}
oldval[0]=val[0];
oldval[1]=val[1];
if(side==0) side=1;
else side=0;
}
Slabina algoritmu je v tom, že náhodné hodnoty často nevytvoria dostočne kontrastné farby. Pokiaľ sú RGB hodnoty na oboch stranách približne rovnaké, ľudské oko už nevidí skoro žiadnu animáciu a sila efektu sa stráca. Pokiaľ by ste chceli algoritmus vylepšiť, doporučoval by som mať pole ručne stanovených RGB hodnôt a výberať len spomedzi nich cez index. Tak budete mať zaručené, že bude stále dostatočný kontrast medzi oboma okrajmi.
Zdrojový kód sa nachádza na serveri GitHub.
Doplňujúce video sa nachádza na serveri YouTube.
22.01.2017