Zápisník experimentátora
Hierarchy: Stmievač LED pásika pomocou ATtiny85
V tomto článku vysvetlím princíp činnosti stmievača LED pásikov. Je to druhý zo série článkov, na ktorých vám ukážem, ako postupne prebieha vývoj programov a ako diametrálne sa môže líšiť výsledný program. Postupne prejdeme zdrojové kódy programu od verzie 1.0 po verziu 1.3.
Tento text popisuje zastaranú verziu kódu. V čase písania článku bola aktuálna verzia kódu 1.3. Táto verzia je tu analyzovaná preto, aby ste si mohli pozrieť, ako prebieha vývoj programov metódou postupného približovania.
V ideálnom svete napíšete ideálny program hneď na prvý raz a nebudú v ňom žiadne chyby a bude robiť presne to, čo ste si predstavovali. A teraz vitajte v reálnom svete, v ktorom som sa pokúsil naprogramovať logiku stmievania tak, aby vyhovovala práci v kuchyni.
Kód bol vyvíjaný ešte pre verziu 1.0.6, ale bez problémov ho možno skompilovať aj v 1.6.13 alebo 1.8.1. Zaberá po skompilovaní 2206 (2440 so zapnutým debuggovaním) bajtov. Je nutné mať doinštalovanú podporu pre programovanie ATtiny85.
V tomto programe som sa sústredil na vylepšenie základnej činnosti programu. Celý vývoj prebiehal na vývojovej doske pre ATtiny85, ktorú som už popisoval v predchádzajúcom článku.
Najprv si popíšeme debuggovanie pomocou pomocnej LED diódy. Debuggovanie je založené na existencii alebo neexistencii makra RDEBUG
. Ak neexistuje (finálna verzia kódu), potom nie sú vôbec použité piny 2 a 3 a všetky makrofunkcie sú definované ako prázdne, čo znamená, že prekladač všetok ten kód zo zdrojáku jednoducho odstráni.
Ak je makro definované (ladiaca verzia kódu), makrofunkcie SIGNAL
a SHOWIN
majú v sebe funkčný kód. Prvá len krátko blikne a druhá signlizuje stav senzora. Používam ich v kóde na to, aby som pomocou bliknutia alebo stavu LED diódy videl, čo sa v programe deje. Ešte stojí za zmienku, že počas ladenia mám skrátený interval hold_value
na 15 sekúnd. Je to z praktických dôvodov, pretože počas ladenia nie je dôvod čakať desiatky sekúnd na zhasnutie osvetlenia.
#define RDEBUG
// pin definitions
const int led = 0;
const int dig = 1;
// base ON period
const unsigned long pot_value = 2000;
unsigned long dig_last;
int value = 0;
// base hold period
#if defined RDEBUG
const int dig_signal = 2;
const int dig_in = 3;
#define SIGNAL digitalWrite(dig_signal, HIGH); \
delay(200); \
digitalWrite(dig_signal, LOW); \
delay(20);
#define SHOWIN(a) digitalWrite(dig_in, a);
const unsigned long hold_value = 15*1000L;
#else
#define SIGNAL
#define SHOWIN(a)
const unsigned long hold_value = 45*1000L;
#endif
Lepšie to bude vidno na konkrétnom príklade. Napŕiklad počas štartu programu vo funkcii setup
. Vidíte, že počas ladenia sa používajú iné príkazy, než počas finálnej verzie.
void setup() {
pinMode(led, OUTPUT);
pinMode(dig, INPUT);
#if defined RDEBUG
pinMode(dig_signal, OUTPUT);
pinMode(dig_in, OUTPUT);
SIGNAL
digitalWrite(dig_in, HIGH);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
digitalWrite(dig_in, LOW);
SIGNAL
#else
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
#endif
}
Ako je vylepšená reakcia na senzor? Po rozsvietení sa nastaví plná dĺžka intervalu. Predtým sa rozsvietenie započítalo do dĺžky intervalu a vďaka tomu to svietilo o čosi kratšie.
void loop() {
int p=digitalRead(dig);
SHOWIN(p)
if(p) {
LightOn();
SIGNAL
dig_last=millis()+hold_value;
LightHold();
SIGNAL
LightOff();
}
}
Zvyšok zmien sú len drobné vylepšenia, ktoré upravujú konkrétne dĺžky jednotlivých stavov programu.
Zdrojový kód sa nachádza na GitHub.
20.04.2017