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 štvrtý 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. Tento text popisuje aktuálnu verziu kódu 1.3.
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.2. Zaberá po skompilovaní 3038 (6254 so zapnutým debuggovaním) bajtov. Je nutné mať doinštalovanú podporu pre programovanie ATtiny85.
V tomto programe som sa sústredil na zníženie spotreby energie. Väčšinu času totiž program len čaká na signál zo senzora a na to nepotrebuje veľa strojového času. Preto sa program uspáva na bloky času trvajúce 64 ms, počas ktorých je spotreba mikrokontroléra na minime. Celý vývoj prebiehal na vývojovej doske pre ATtiny85, ktorú som už popisoval v predchádzajúcom článku.
Na uspávanie mikrokontroléra sa obvykle využiva watchdog timer
. Aby celé uspávanie fungovalo, je potrebné doplniť do programu nasledovné riadky.
wdtimer
, kde vytvoríme všetky symbolické možnosti pre uspávanie. Aby bol program svižný, budeme používať uspávanie na 64 ms.setup
vypneme ADC
, pretože aj to spotrebuje trochu energie a v programe ho nepotrebujeme. Potom ešte nastavíme watchdog timer funkciou setup_watchdog
.LightDark
je ukrytá celá logika uspávania. Zavolá sa funkcia system_sleep
, ktorá uspí mikrokontrolér. Urobí to vždy, keď nemá signál zo senzora. V praxi strávi mikrokontrolér prakticky všetok čas v tejto funkcii, pretože väčšinu dňa žiadne signály z PIR senzora nebudú prichádzať.system_sleep
slúži na uspatie mikrokontroléra. Po prebudení sa začne vykonávať kód na konci funkcie, čo je presne to, čo potrebujeme. Prebudíme sa zo spánku, skontrolujeme PIR senzor a ak sa nič nedeje, zase sa uspíme.setup_watchdog
slúži na nastavenie správnych bitov pre watchdog timer.signal_wdt
.
#include "wiring_private.h"
#include <avr/sleep.h>
enum wdtimer {wdt16ms=0, wdt32ms, wdt64ms, wdt128ms, wdt250ms, wdt500ms, wdt1s, wdt2s, wdt4s, wdt8s};
volatile boolean signal_wdt = 1;
void setup() {
// disable adc
cbi(ADCSRA, ADEN);
setup_watchdog(wdt64ms);
...
}
void LightDark() {
int p=digitalRead(dig);
if(p)
state=stOn;
else
system_sleep();
}
void system_sleep() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
}
void setup_watchdog(byte t) {
byte bb;
int ww;
if(t>wdt8s)
t=wdt8s;
bb=t&7; // WDP[2:0]
if(t>wdt2s)
sbi(bb,WDP3);
sbi(bb,WDCE);
ww=bb;
cbi(MCUSR,WDRF);
// start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR = bb;
sbi(WDTCR,WDIE);
}
ISR(WDT_vect) {
signal_wdt=1; // set global flag
}
Zdrojový kód sa nachádza na GitHub.
27.06.2017