Zápisník experimentátora
Hierarchy: WS2812
LED hodiny vytvorené z NeoPixel Ringu a Arduina. V tomto článku si vysvetlíme základné zapojenie a navrhneme prvú verziu programu. Budeme na to potrebovať Arduino Uno, jedno skúšobné pole a NeoPixel Ring s dvanástimi diódami. Kúpiť sa dá napríklad na Ebay.
NeoPixel Ring budeme priamo zastrkávať do skúšobného poľa, preto je potrebné zo zadnej strany naletovať kus odlamovacej lišty so štyrmi pinmi. Obvykle sú všetky letovacie plôšky na jednom mieste. Môže sa vám ale stať, že si kúpite prstenec, ktorý má letovacie plôšky rozmiestnené inak. Netreba podliehať panike, vždy je treba nájsť štyri konkrétne plôšky a pripojiť na ne vodiče a tie pripojiť na skúšobného poľa v poradí, ako je uvedené v tomto článku:
V článku Napájanie pre NeoPixel Ring si prečítajte zásady pripájania. V našom prípade nebudeme pracovať s vysokým prúdom, pretože v jednej chvíli bude svietiť slabo iba zopár LED, preto budeme prstenec pripájať priamo ku Arduinu. Použijeme kondenzátor medzi Vcc a Gnd a ochranný rezistor medzi Arduinom a Din.
Schéma zapojenia je triviálna:
Prvá verzia programu sa bude zameriavať na naprogramovanie základných funkcií:
Inšpiráciou ku kódu bolo video Arduino RGB LED Clock with adafruit neopixel ring a zdrojový kód ku nemu. Dosť som to ale poupravoval, zjednodušil, opravil chyby a dopracoval chýbajúce časti.
Výpočet je na nasledovných riadkoch. Vychádzame z toho, že základný čas nám beží v milisekundách. Čiže všetky prepočty na relatívnu polohu na kruhu musíme robiť z tejto hodnoty.
void NeoClock::Update()
{
// we use fake time
uint32_t m=millis()+60000L*STARTMINUTE+3600000L*STARTHOUR;
second = map ((m % 60000), 0, 60000, 0, CNT);
milli = map ((m % 1000), 0, 1000, 0, CNT);
minute = map (((m/60000) % 60), 0, 60, 0, CNT);
hour = map (((m/60000/60) % 12), 0, 12, 0, CNT);
}
Môžeme si vybrať, či chceme vidieť aj milisekundy, ktoré obiehajú dosť rýchlo, preto je to skôr voľba na efekt. Dve zvyšné voľby umožňujú nastaviť chvostík 2 alebo 3 diódy dlhý. Výnimkou sú sekundy, ktoré sú vždy dlhé 3 diódy.
// show milliseconds
#define SHOWMILLIS 0
// show long hour
#define SHOWLONGHOUR 0
// show long minute
#define SHOWLONGMINUTE 0
Takto vyzerá definícia milisekundovej farby. Maximálna hodnota je 255, čo svieti tak silno, že sa do toho nemôžete pozerať voľným okom. Takto nastavená červená farba je dobre viditeľná vo vnútornom prostredí bez priameho slnka. Súčasne aj spotrebúva na jednu LED približne iba 20/255*10 mA. Celý prstenec so všetkými farbami naplno by spotreboval 12*3*20 mA, čo by už mohlo byť na hranici možností USB portu, na ktorý máme napojené Arduino.
uint32_t milli_color = strip.Color ( 10, 0, 0);
uint32_t milli_color1 = strip.Color ( 6, 0, 0);
uint32_t milli_color2 = strip.Color ( 3, 0, 0);
CNT nastavujeme na hodnotu 12, pretože používame prstenec s 12 LED diódami. MOVE nastavujeme na 6, pretože na mojej verzii prstenca sa nachádzajú piny na jednom mieste a na tom istom mieste je umiestnená prvá LED. Keďže sa piny zastrčia do skúšobného poľa, mali by sme dvanástku otočenú o 180 stupňov. Posun o 6 nám posunie začiatočný bod tam, kde ho potrebujeme.
#define CNT 12
#define MOVE 6
void NeoClock::Draw()
{
Clear();
#if SHOWLONGHOUR
AddColor((hour+MOVE) % CNT, hour_color );
AddColor((hour+MOVE-1) % CNT, hour_color1 );
AddColor((hour+MOVE-2) % CNT, hour_color2 );
#else
AddColor((hour+MOVE) % CNT, hour_color );
AddColor((hour+MOVE-1) % CNT, hour_color2 );
#endif
Na nasledovnom príklade vidíme definovanie času 19:15. Vo výpočte sa potom používa reálny čas od spustenia programu, ku ktorému je pripočítaný adekvátny počet milisekúnd.
#define STARTHOUR 19
#define STARTMINUTE 15
...
uint32_t m=millis()+60000L*STARTMINUTE+3600000L*STARTHOUR;
Zvyšné podrobnosti je možné nájsť v priloženom programe. Nabudúce sa pozrieme na úpravu jasu LED diód, ktoré sa budú prispôsobovať okolitému svetlu.
22.07.2015