Hodiny z NeoPixel Ring - základy

Zápisník experimentátora

Translations: SK EN

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.

Mechanické úpravy

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:

  • Vcc - Sem sa pripojí napájanie. V tomto prípade +5 V.
  • Gnd - Sem sa pripojí zem.
  • Din - Sem sa pripojí dátový vodič z Arduina. Pomocou neho budeme zasielať príkazy. V príklade budeme používať digitálny pin 6.
  • Dout - Sem nebudeme pripájať nič. V prípade, že by sme mali prstencov viac, môžeme ich cez tento výstup vzájomne reťaziť.

Ochrana diód pred poškodením

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

Schéma zapojenia je triviálna:

  • Pin D6 nám bude slúžiť na zasielanie príkazov. Na ňom je ochranný rezistor 330 R.
  • Na napájaní je pripojený ochranný kondenzátor 220 uF.

Programovanie

Prvá verzia programu sa bude zameriavať na naprogramovanie základných funkcií:

  • Svetelné body, reprezentujúce hodiny, minúty, sekundy a milisekundy - Nastavenie svetelných bodov, ktoré reprezentujú ručičky hodín. Každý bod má vlastnú farbu.
  • Dĺžka chvostíka za jednotlivými bodmi - Ak je ručička vykreslená pomocou viacerých LED, môže vyzerať lepšie. Treba ale hľadať kompromis medzi dĺžkou, pretože ak budú po prstenci poletovať štyri body s dlhými chvostíkmi, celé sa to stane vizuálne tažko rozoznateľným.
  • Minimalizovanie spotreby energie znížením jasu na minimum - Na experimenty nepotrebujeme, aby sa jednotlivé body veľmi rozsvietili. Často sa budeme na ne pozerať zblízka a nik nestojí o vypálené body na sietnici.
  • Posun nulového bodu na ľubovoľnú pozíciu - Toto je veľmi dôležitý bod, pretože počiatok LED sa nachádza obvykle pri pine Din. Ak ale budeme prstenec zastrkovať do skúšobného poľa, celé to bude hore hlavou. Preto sa nám bude hodiť funkcia na posun počiatku do iného bodu.
  • Nastavenie simulovaného času po zapnutí - Pri testovaní nepotrebujeme reálny čas, pretože pri ňom by sa niektoré body dosť často prekrývali. Preto bude pre nás vhodnejšie, ak si počas testovania nastavíme konkrétny čas a nad ním budeme ladiť.

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.

Hodiny, minúty, sekundy a milisekundy

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);
}

Dĺžka chvostíka

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

Minimálny jas

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);

Posun nulového bodu

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

Simulovaný čas

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.



Download

22.07.2015


Menu