//================================= // HLIDAC ZAPNUTE MIKROPAJKY //================================= // verze: 21.2.2015 // Velikost prelozeneho kodu pro ATtiny13A: 1014 Bajtu // Dalsi informace, schema a fotky : http://astromik.org/raspi/mikropajka // POPIS: //========== // Pomoci potenciometru se nastavi cas v rozsahu 30 sekund az 9 minut. // Kdyz je hrot mikropajky v drzaku delsi dobu, nez je potenciometrem nastaveny cas, zacne prerusovane pipat piskak. // 15 sekund pred zacatkem pipani se rozsviti LED. // Odpocet nastaveneho casu se automaticky nuluje, kdyz je pajka mimo drzak, nebo kdyz dojde k otoceni potenciometru. // Kdyz ani po dalsi pul minute pipani nenastane zadna reakce, pomoci rele se automaticky odpoji privod napeti do topneho telesa. // V tom pripade se piskak vypne a LED zacne blikat. Pro uvedeni pajky do provozniho stavu je nutne ji vypnout a zapnout. // V drzaku hrotu mikropajky je fotocidlo, ktere pri zasunuti hrotu posila logickou "1" do procesoru ATtiny13A. // Pri vyjmuti hrotu z drzaku je na vystupu tohoto cidla logicka "0". // pozn.: V programu je pripravena i alternativa pro opacnou logiku cidla // Vyznam jednotlivych vyvodu procesoru ATtiny13A: // PB0 = pin 5 = OUT - odpojovaci rele pro topne teleso // PB1 = pin 6 = OUT - akusticky menic (reproduktorek) - BEZ VNITRNIHO PRERUSOVACE! // PB2 = pin 7 = OUT - informacni LED (rozsvecuje se 15 sekund pred piskakem, nebo blika po odpojeni topneho telesa) // PB3 = pin 2 = IN - cidlo zasunuteho hrotu (drzak) // PB4 = pin 3 = ANALOG IN - potenciometr - analogove nastaveni casove prodlevy // PB5 = pin 1 = IN - nepouzito (RESET) // VCC = pin 8 = napajeni +5V // GND = pin 4 = napajeni GND //=================================================================================================== #define F_CPU 9600000 // nastaveni vnitrni frekvence procesoru na 9.6 MHz #include #include // cteni analogove hodnoty z nastaveneho A/D prevodniku int adc_read (void) { // Start bit se nastavi do "1" ADCSRA |= 0b01000000; // cekani na ukonceni prevodu (bit ADSC v registru ADSRA padne do "0") while (ADCSRA & 0b01000000); return ADCH; // V ADCH je 8 nejvyssich bitu z namerene hodnoty (2 nejnizsi bity jsou v ADCL, ale tady nejsou vyuzity) } // piskani asi 2,2kHz void piip (void) { PORTB |= 0b00000010; // nastaveni vystupu pro akusticky menic na "1" - ostatni bity beze zmeny _delay_us (200); PORTB &= 0b11111101; // nastaveni vystupu pro akusticky menic na "0" - ostatni bity beze zmeny // pauza pro signal "0" je tvorena casem vykonavani dalsich prikazu ve smycce (asi 250us) } int main (void) { int ad_sek = 0; // vypocitany pocet sekund nastavenych potenciometrem int pocitadlo_sek = 0; // pocitadlo sekund po ktere je pajka odlozena (porovnava se s promennou "ad_sek") int pocet_cyk = 0; // pocitadlo prubehu hlavni programove smycky (2500 pruchodu trva 1 sekundu) int pom_pot = 0; // pomocna promenna pro testovani, jestli se otocilo potenciometrem byte hystereze_1 = 0 ; // pocet sekund po prvnim rozsviceni LED, o ktere se snizi hranice rozsviceni LED, takze by nemela problikavat byte hystereze_2 = 0 ; // pocet sekund po prvnim pisknuti, o ktere se snizi hranice piskani, takze by neměl piskak probzukavat DDRB = 0b00000111; // nastaveni smeru signalu na portu B ("1" = vystup ; "0" = vstup) - PB2=LED; PB1=piskak; PB0=rele pro topne teleso PORTB = 0b00001001; // pull-up pro cidlo na drzaku (PB3) + sepnuti rele pro topne teleso na PB0 ADMUX = 0b00100010; // zakladni nastaveni A/D prevodniku - ADLAR na "1" (=nejvyssich 8 bitu je pohromade) a nastaveni cteni napeti z PB4 (=ADC2) ADCSRA = 0b10000111; // ADC enable bit na "1" a nastaveni delice frekvence pro ADC na 1:128 (=75kHz) _delay_ms (30000); // pri startu programu se k nastavenemu casu jednorazove pricte jeste 30 sekund (kvuli rozehrati pajky) while (1) // nekonecna hlavni smycka { ad_sek = (adc_read()) * 2 + 30 ; // prevedeni nastaveni potenciometru (hodnota A/D prevodniku 0 az 255) na cas 30 az 540 sekund (9 minut) if (abs(ad_sek - pom_pot) > 30) // kdyz doslo k otoceni potenciometru alespon o 30 sekund { pom_pot = ad_sek; // nova hodnota se zapamatuje pocitadlo_sek = 0; // a vyresetuje se pocitadlo sekund odlozene pajky pocet_cyk = 0; // vynulovani pocitadla smycek } // if ((PINB & 0b00001000) == 8) // hrot mikropajky je mimo drzak (cidlo na PB3 dava signal logicka "1") - ALTERNATIVA K NASLEDUJICI PODMINCE if ((PINB & 0b00001000) == 0) // hrot mikropajky je mimo drzak (cidlo na PB3 dava signal logicka "0") - ALTERNATIVA K PREDCHOZI PODMINCE { pocitadlo_sek = 0; // vynulovani pocitadla sekund (doba necinne - odlozene pajky) pocet_cyk = 0; // vynulovani pocitadla smycek PORTB &= 0b11111011; // zhasnuti informacni LED } else // hrot mikropajky je v drzaku { pocet_cyk ++; // pocitani cyklu if (pocet_cyk == 2500) // 2500 cyklu trva asi 1 sekundu (experimentalne zmereno) { pocet_cyk = 0; // pocitadlo cyklu se po dosazeni cisla 2500 nuluje pocitadlo_sek ++; // kazdou sekundu se pocitadlo sekund odlozene pajky "pocitadlo_sek" zvetsi o 1 } if (pocitadlo_sek > (ad_sek - 15 - hystereze_1)) // 15 sekund pred piskakem se rozsviti informacni LED (po prvnim rozsviceni se hranice snizi na -20 sekund) { PORTB |= 0b00000100; // rozsviceni LED na PB2 hystereze_1 = 5; // snizeni hranice rozsviceni LED o 5 sekund (na nastaveny cas -20 sek.), takze vlivem kolisani A/D prevodniku nebude LED problikavat } else // kdyz je jeste dostatek casu pred spustenim piskaku je informacni LED zhasnuta { PORTB &= 0b11111011; // zhasnuti LED na PB2 hystereze_1 = 0; // kdyz LEDka nesviti, hystereze se nastavi zpatky na -15 sekund } if (pocitadlo_sek >= (ad_sek - hystereze_2) && (pocitadlo_sek/2) == (pocitadlo_sek /2.0)) // kdyz presahne pocitadlo sekund potenciometrem nastavenou hodnotu, ... { piip(); // ... kazdou sudou sekundu se pipne hystereze_2 = 5; // hystereze se pri prvnim pisknuti posune z 0 na -5 sekund } else // kdyz je cas jeste v poradku, jen se na chvili zastavi smycka { _delay_us (200); hystereze_2 = 0; // kdyz piskak nepiska, hystereze se nastavi zpatky na 0 } } if (pocitadlo_sek > ad_sek + 30 ) // po 30 sekundach od zacatku pipani se odpoji topne teleso { PORTB &= 0b11111100; // odpojeni topneho telesa pomoci rele na PB0 a vypnuti piskaku na PB1 while (1) // program skonci v nekonecne smycce pro blikani LED a opetovne nastartovani pajky je mozne pouze vypnutim a zapnutim napajeni { _delay_us (100000); // blikani LED s periodou asi 0,2s (= 5Hz) PORTB &= 0b11111011; // zhasnuti informacni LED (vsechny ostatni vyvody beze zmeny) _delay_us (100000); PORTB |= 0b00000100; // rozsviceni informacni LED (vsechny ostatni vyvody beze zmeny) } } } // konec hlavni smycky }