// Bateriove napajeny GSM alarm //================================ // verze: 09.04.2017 // http://www.astromik.org/raspi/gsmalarm/ // Hlavni duraz byl kladen na minimalni spotrebu proudu pri hlidani. // Alarm musi vydrzet v provozu i nekolik mesicu bez zasahu obsluhy. // Popis funkce: // Pri zapnuti napajeni (aktivaci hlidani) se na 20 sekund rozblika LED. V tomto case je nutne opustit hlidany prostor. // Po 20 sekundach od zapnuti napajeni prejde zabezpecovaci zarizeni do rezimu s minimalni spotrebou (kolem 6uA). // Kdyz v teto dobe nekdo aktivuje kontakt na dverich, zabezpecovaci zarizeni se probudi a nastava dalsi 20-sekundovy odpocet. // Behem tohoto odpoctu je mozne hlidani deaktivovat. // Kdyz ale k deaktivaci nedojde, zapne se napajeni do GSM modulu. // GSM modul zacne navazovat spojeni se siti. Po navazani spojeni s GSM siti se prozvoni vybrane telefonni cislo. // Prozvaneni trva si 20 sekund, po kterych dojde k vypnuti napajeni GSM modulu a k uspani zarizeni. // Zakladni zapojeni Arduina: // Tx (D1) -> GSM modul U_RXD. // Rx (D0) -> GSM modul U_TXD. // D2 -> Koncovy prepinac na dverich (pri otevrenych dverich spina na GND, pri zavrenych dverich spina na Vcc). // D5 -> Ovladani napajeni pro GSM modul (pres N-FET tranzistor). // D10 -> Informacni LED. // Vcc -> Prepinac (Aktivace / Deaktivace hlidani). // Nastaveni FUSE bajtu v ATmega328: // LFuse = 0xFF // HFuse = 0xDF // EFuse = 0x07 //========================================= #include int i = 0 ; // Pomocna promenna pro ruzne casovaci smycky. String odpoved = "" ; // Retezec prijimany Arduinem od GSM modulu. volatile boolean prozvoneno = false ; // Informace o tom, jestli uz probehla sekvence prozvaneni z GSM modulu. String telefon = "ATD123456789" ; // Telefonni cislo, ktere se bude prozvanet (ve formatu "ATD" a 9-mistne telefonni cislo). //========================================= // Prijem komunikace od GSM modulu. void komunikace() { char znak; delay(200); // Kratka pauza pro nacteni celeho retezce do bufferu. while(Serial.available()) { znak = Serial.read(); odpoved.concat(znak); } if (odpoved.substring(2,20) == "+CIEV: service, 1") // Spojeni s GSM siti je navazano. { delay(1000); // Sekundu po tom, co se navaze spojeni se siti ... Serial.println(telefon); // ... zacne prozvanet vybrane telefonni cislo (prikaz "ATD123456789"). delay(20000); // Prozvaneni bude trvat 20 sekund. Serial.println("ATH"); // Pak se vyzvaneni ukonci. prozvoneno = true; // Znacka o tom, ze probehlo prozvaneni. } Serial.flush(); // Vymaze prijimaci buffer. odpoved=""; } //========================================= // Podprogram pro "interrupt" kontaktem pri otevirani dveri. void dvere () { sleep_disable(); detachInterrupt (0); } //========================================= void setup () { for (i = 0; i <= A5; i++) // Kvuli snizeni spotreby ve sleep rezimu vsechny piny nastavit na vystup a stahnout do LOW ... { pinMode (i, OUTPUT); digitalWrite (i, LOW); } pinMode (2, INPUT); // ... krome kontaktu na dverich, ktery slouzi k probuzeni z rezimu spanku. // Kvuli omezeni proudu pri trvale otevrenych dverich nesmi byt zapnuty Pull-Up. // Kontakt na dverich musi zajistit preklapeni mezi GND a Vcc // (ovladaci pin nesmi zustavat "ve vzduchu" - to by zpusobovalo neustale hlaseni alarmu). Serial.begin(115200); // Po zapnuti napajeni je 20 sekund pauza na opusteni objeku. Pri teto pauze RYCHLE blika informacni LED. for ( i = 0 ; i < 200 ; i++) // 200 * 0.1 sekundy = 20 sekund { digitalWrite (10, HIGH); delay(10); digitalWrite (10, LOW); delay(90); } } //========================================= // HLAVNI SMYCKA void loop () { //------------- // hned po startu (po 20 sekundach) se procesor uspi do stavu s minimalnim odberem (kolem 6uA) // (opsano a upraveno z: http://www.gammon.com.au/power ) ADCSRA = 0; set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows attachInterrupt (0, dvere, FALLING); EIFR = bit (INTF0); // clear flag for interrupt 0 sleep_enable(); interrupts (); // guarantees next instruction executed sleep_cpu (); // sleep within 3 clock cycles of above //------------- //============================================================================================== // V tomto miste ceka procesor na probuzeni pomoci sestupne hrany na pinu D2 (kontakt na dverich). //============================================================================================== // Po probuzeni je tu dalsich 20 sekund na vypnuti napajeni, pri kterych POMALU blika LED. // V teto fazi ma hlidac jeste pomerne malou spotrebu (asi 10mA). for ( i = 0 ; i < 40 ; i++) // 40 * 0.5 sekundy = 20 sekund { digitalWrite (10, HIGH); delay(50); digitalWrite (10, LOW); delay(450); } //========================================= // Kdyz se napajeni behem 20 sekund nevypne, program se dostane az sem a spusti // se sekvence prikazu pro zapnuti napajeni GSM modulu a vytoceni cisla. // Zapnuty GSM modul uz zpusobuje znacny odber proudu (spickove az 200mA, trvale asi 100mA). pinMode (0, INPUT); // Pin pro prijem seriove komunikace z GSM modulu docasne nastavit na vstup. digitalWrite (5, HIGH); // Zapnuti napajeni do GSM modulu. prozvoneno = false; // Znacka, ze se jeste nepodarilo prozvonit cilovy telefon. i = 0; // Vynulovani casoveho pocitadla. while (prozvoneno == false && i < 1000) // V teto smycce ceka tak dlouho, dokud se neprovede prozvoneni, { // nebo dokud nevyprsi casovy interval v desetinach sekundy. delay(100); // Casovani neuspesneho pripojeni GSM modulu (desetina sekundy na jeden pruchod). i++; if (Serial.available()>0) // Kdyz dojde k nejake komunikaci s GSM modulem, ... { komunikace(); // ... vyhodnocuje se v podprogramu, jestli uz je navazano spojeni se siti } // (ceka se na prijem retezce: "+CIEV: service, 1" ze seriove komunikace). } if (prozvoneno == false) // Kdyz ani po 100 sekundach nedojde k vytoceni cisla { // (napriklad kvuli nejakemu problemu v komunikaci), ... Serial.println (telefon); // ... zkusi se to cislo vytocit jeste jednou // (tentokrat uz bez kontroly, jestli je navazano spojeni se siti). delay(20000); // Prozvaneni bude trvat 20 sekund. Serial.println("ATH"); // Vyzvaneni se ukonci. } // Pak se vypne se napajeni GSM modulu a procesor se uspi. digitalWrite (5, LOW); // Vypnuti napajeni GSM modulu. pinMode (0, OUTPUT); // Kvuli zmenseni odberu se prijimaci pin od komunikace (Rx) nastavi na dobu spanku na vystup a do LOW. digitalWrite (0, LOW); // Po vytoceni cisla GSM modulem se program vrati na zacatek hlavni smycky a usne do doby, nez se znova pohne dvermi. // Pokud nechal zlodej dvere otevrene, dalsiho zlodeje uz system nezaznamena (hlida se pouze otevirani dveri). // Kdyz zlodej za sebou dvere zavre, dojde po jejich nasledujicim otevreni k dalsimu casovanemu alarmu. } // Konec hlavni smycky.