Zápisník experimentátora
Hierarchy: ShiftPWM
V tomto článku najdete popis algoritmu, který vytvoří psychedelické přechody barev pomocí RGB LED diod. Jak to vypadá se popisuje obtížněji, proto se podívejte na video na konci článku, kde se tyto barvy plynule mění. Toto byl první experiment na daném poli a proto je výsledek trochu jiný, než jsem čekal. Využívám totiž náhodné nastavení barev a velmi často se mi stalo, že výběr barev na obou koncích osmice diod byl tak blízký, že se žádný psychedelický přechod nekonal. Ale pojďme pěkně od začátku.
K vytvoření efektu využijeme dvě desky z předchozího článku. V něm je popsáno jejich vyrobení a způsob zapojení. Kromě toho jsem použil ještě i:
Algoritmus je navržen tak, aby střídavě vypočítal náhodnou barvu na jednom nebo druhém konci a plynule animoval přechod z předchozí barvy. Takto se každé dvě sekundy jedna strana plynule přetransformuje na novou barvu a celý algoritmus se opakuje. V článku nebudu popisovat základní nastavení knihovny ShiftPWM, ten najdete v předchozím článku.
Protože pracujeme s RGB hodnotami, je vhodné si na ty účely definovat strukturu. Budeme potřebovat tři dvojice takových struktur, abychom mohli celý algoritmus realizovat. Proměnná v
obsahuje aktuální vypočtenou hodnotu na obou koncích. Proměnná val
obsahuje nejnovější dvojici RGB barev. Je to cíl, ke kterému se postupně barva přibližuje. Proměnná oldval
obsahuje předchozí dvojici a od ní se barva vzdaluje. Proměnná side
nabývá dvě hodnoty a říká nám, na které straně máme vypočítat novou RGB hodnotu.
struct rgb {
int r;
int g;
int b;
};
rgb v[2];
rgb val[2];
rgb oldval[2];
int side=0;
Ve funkci loop
provádíme tyto výpočty:
oldval
poznačit poslední vypočtenou 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 nevytvoří dostočne kontrastní barvy. Pokud jsou RGB hodnoty na obou stranách přibližně stejné, lidské oko už nevidí skoro žádnou animaci a síla efektu se ztrácí. Pokud byste chtěli algoritmus vylepšit, doporučoval bych mít pole ručně stanovených RGB hodnot a vybírat jen z nich přes index. Tak budete mít zaručeno, že bude stále dostatečný kontrast mezi oběma okraji.
Zdrojový kód se nachází na serveru GitHub.
Doplňující video se nachází na serveru YouTube.
01.07.2019