Zápisník experimentátora
Hierarchy: WS2812
Vo štvrtom článku rozvinieme ovládanie tlačidlami. Použijeme tri tlačidlá a naprogramujeme si stavový automat, ktorý umožní prepínanie medzi behom hodín a ich nastavovaním. Táto verzia programu sa už bude blížiť výslednému kódu.
![]()
Voči predchádzajúcej schéme sa zmenilo to, že máme namiesto jedného tlačidla tri.
![]()
Konfigurácia sa nám rozrástla, ale voči minulému článku to nepredstavuje zložitú zmenu. Iba nám pribudli ďalšie premenné. V súbore clockdefs.h máme definície stavov, ktoré môže program nadobúdať. Používame tri stavy, ktoré sa ukladajú v premennej cs:
A pribudli nám aj premenné hour a minute, aby sme mohli tlačidlami upravovať ich hodnotu.
#include "clockdefs.h"
///
/// Program configuration
///
struct Configuration
{
ClockState cs;
bool show_millis;
int hour;
int minute;
Configuration()
: show_millis(SHOWMILLIS), cs(csClock), hour(STARTHOUR), minute(STARTMINUTE) {}
};
Configuration cfg;
///
/// Set all colors
///
void NeoClock::Draw()
{
Clear();
switch(cfg.cs)
{
case csClock:
DrawClock();
break;
case csHourSet:
DrawHour();
break;
case csMinuteSet:
DrawMinute();
break;
};
strip.show();
}
Ak sa nachádzame v stave csHourSet, vykresľujeme iba hodinovú ručičku. Pretože používame NeoPixel s 12 LED, vykresľujeme aktuálnu hodinu iba na konkrétnom bode.
Ak sa nachádzame v stave csMinuteSet, musíme nejakým spôsobom vykresliť 60 hodnôt na 12 LED. Preto používame algoritmus, ktorý počiatočný bod vykresľuje na pozícii minute/5 a ku tomu vykresľuje chvostík zo zvyšného modula minút minute%5. Podľa toho vieme ľahko odpočítať koľko máme nastavených minút.
///
/// Draw hours during setup
///
void NeoClock::DrawHour()
{
AddColor((hour+MOVE) % CNT, hour_color );
}
///
/// Draw minutes during setup
///
void NeoClock::DrawMinute()
{
// position/5
AddColor((minute+MOVE) % CNT, minute_color);
// tail as modulo 5
uint32_t m=millis()+60000L*cfg.minute+3600000L*cfg.hour;
int mm = (m/60000) % 60;
int mmm = mm % 5;
for(int i=0;i<mmm;i++)
AddColor((minute+MOVE-i-1) % CNT, minute_color);
}
Aby sme mohli nastavovať hodiny a minúty, používame tri tlačidlá. Ich význam sa mení podľa stavu, v ktorom sa program nachádza. Keďže používame stavový automat, je výsledný kód ľahko pochopiteľný. Treba si len uvedomiť význam jednotlivých tlačidiel:
// button, 25 ms debounce, no repeat, internal pull_up
Button b_select(SELECTPIN,ButtonActionSelect,25,0,true);
// button, 25 ms debounce, repeat 100 ms, internal pull_up
Button b_plus(PLUSPIN,ButtonActionPlus,25,100,true);
Button b_minus(MINUSPIN,ButtonActionMinus,25,100,true);
///
/// When button is pressed
///
void ButtonActionSelect(Button *b)
{
if(b->pressed)
{
switch(cfg.cs)
{
case csClock:
cfg.cs=csHourSet;
break;
case csHourSet:
cfg.cs=csMinuteSet;
break;
case csMinuteSet:
cfg.cs=csClock;
break;
};
}
}
void ButtonActionPlus(Button *b)
{
if(b->pressed)
{
switch(cfg.cs)
{
case csClock:
cfg.show_millis=!cfg.show_millis;
break;
case csHourSet:
cfg.hour++;
if(cfg.hour>23)
cfg.hour=0;
break;
case csMinuteSet:
cfg.minute++;
if(cfg.minute>59)
cfg.minute=0;
break;
};
}
}
void ButtonActionMinus(Button *b)
{
if(b->pressed)
{
switch(cfg.cs)
{
case csClock:
cfg.show_millis=!cfg.show_millis;
break;
case csHourSet:
cfg.hour--;
if(cfg.hour<0)
cfg.hour=23;
break;
case csMinuteSet:
cfg.minute--;
if(cfg.minute<0)
cfg.minute=59;
break;
};
}
}
V budúcom článku pripojíme ku obvodu hodiny reálneho času. Kto chce študovať zapojenie obvodu DS1307, môže tak urobiť v samostatnom článku už teraz.
24.08.2015