Stmievač LED pásika - Softvér v. 1.1

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.

Arduino IDE

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.

Programovanie

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.

  • Debuggovanie - Doplnil som jednoduché debuggovanie pomocou podmieneného prekladu a blikania pomocnou LED diódou.
  • Vylepšenie reakcie na signály zo senzora - Teraz program trvale svieti, pokiaľ zaznamenáva signál zo senzora a čas rozsvietenia nie je súčasťou intervalu svietenia, čiže svetlo svieti o trochu dlhšie. Až keď signály ustanú (čo je znamením, že človek opustil miestnosť), svetlo sa po čase zhasne.

Debuggovanie

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
}

Vylepšenie reakcie na senzor

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

Zdrojový kód sa nachádza na GitHub.


20.04.2017


Menu