// // KRMITKO PRO PSA // =================== // verze: 17.3.2016 // velikost prelozeneho kodu: 540 Bajtu // Popis: http://www.astromik.org/raspi/krmitko // Zapojeni: //============= // ATtiny13 // +-\_/-+ // nezapojeno (RESET) - PB5 1| |8 Vcc - napajeni z baterie // SCL u RTC <----- I2C master SCL - PB3 2| |7 PB2 - vykonove spinace pro napajeni serva // SDA u RTC <----> I2C master SDA - PB4 3| |6 PB1 - piskak // TINY GND 4| |5 PB0 - PWM rizeni serva // +-----+ // odeslani bitu "0" po I2C sbernici s tiknutim v hodinach void sda0() { PORTB = 0b00000000; // SDA do "0" delay(1); // pauza pred preklopenim SCL do "1" PORTB = 0b00001000; // SCL do "1" - ted se nesmi SDA menit delay(1); PORTB = 0b00000000; // SCL padem do "0" ukoncuje odeslani bitu a pripravuje moznost zmeny SDA delay(1); // pauza pred dalsi zmenou na SDA } // odeslani bitu "1" po I2C sbernici s tiknutim v hodinach void sda1() { PORTB = 0b00010000; // SDA do "1" delay(1); // pauza pred preklopenim SCL do "1" PORTB = 0b00011000; // SCL do "1" - ted se nesmi SDA menit delay(1); PORTB = 0b00010000; // SCL padem do "0" ukoncuje odesilani bitu a je mozne menit SDA delay(1); } // jen tiknuti hodinami pri nastavenem prijmu na SDA void acktik() { PORTB = 0b00010000; // SCL zustava v "0", SDA se zveda na "1" - ted muze RTC odpovedet DDRB = 0b00001000; // nastaveni smeru signalu na portu B ("1"=vystup CLK; "0"=vstup SDA) delay(2); PORTB = 0b00011000; // SCL do "1" - RTC by mel prizemnit datovy vstup // tady by se melo testovat, jestli je na SDA "0" delay(1); PORTB = 0b00010000; // SCL do "0" delay(1); DDRB = 0b00011000; // nastaveni smeru signalu na portu B ("1"=vystup CLK i SDA) delay(2); } // Podprogram pro reset "Alarm Flagu" v RTC obvodu PCF8563 // Nahrada za prikaz v Pythonu: // bus.write_byte_data(0x51,0x01,0b00010010) void resetAF() { PORTB = 0b00000000; // zrusit Pull-Upy, ale porad drzet SDA i SCL v "1" DDRB = 0b00011000; // nastaveni smeru signalu na portu B (SDA i SCL = "1" = vystup) PORTB = 0b00011000; // SDA i SCL do "1" // START condition PORTB = 0b00001000; // SDA pada do "0" delay(1); PORTB = 0b00000000; // SDA zustava v "0", SCL pada take do "0" delay(2); // I2C adresa je 1010001 (0x51) sda1(); // 1.bit = "1" sda0(); // 2.bit = "0" sda1(); // 3.bit = "1" sda0(); // 4.bit = "0" sda0(); // 5.bit = "0" sda0(); // 6.bit = "0" sda1(); // 7.bit = "1" // R/W bit na "0" - to je zapis sda0(); // 8.bit = "0" // prijem ACK od RTC acktik(); // tiknuti hodinami - tady by se melo testovat, jestli RTC odpovedelo, ale neresim to // odeslani adresy "Control registru" (0b00000001) sda0(); // 1.bit = "0" sda0(); // 2.bit = "0" sda0(); // 3.bit = "0" sda0(); // 4.bit = "0" sda0(); // 5.bit = "0" sda0(); // 6.bit = "0" sda0(); // 7.bit = "0" sda1(); // 8.bit = "1" // prijem ACK od RTC acktik(); // tiknuti hodinami - tady by se melo testovat, jestli RTC odpovedelo, ale neresim to // odeslani dat do control registru (0b00010010) sda0(); // 1.bit = "0" sda0(); // 2.bit = "0" sda0(); // 3.bit = "0" sda1(); // 4.bit = "1" (TI/IP bit) sda0(); // 5.bit = "0" sda0(); // 6.bit = "0" sda1(); // 7.bit = "1" (AIE bit) sda0(); // 8.bit = "0" // prijem ACK od RTC acktik(); // tiknuti hodinami - tady by se melo testovat, jestli RTC odpovedelo, ale neresim to // STOP condition delay(2); // pauza pred ukoncenim komunikace PORTB = 0b00000000; // CLK zustava od posledniho stavu v "0", SDA take zustava v "0" delay(1); PORTB = 0b00001000; // SDA zustava v "0", SCL se zveda do "1" delay(2); PORTB = 0b00011000; // SCL zustava v "1", SDA se taky zveda do "1" delay(2); // na zaver uz jen nastav SDA i SCL jako vstupy, ale az sem by se program nemel dostat, // protoze po resetu Alarm Flagu v RTC se okamzite odpoji napajeni DDRB = 0b00000000; // SDA i SCL nastavit na vstup PORTB = 0b00011000; // a pres Pull-Upy drz na SDA i SCL "1" } // 3x zapipani piskaku na PB1 void zapipej() { for (byte i=0 ; i<3 ; i++) { PORTB = 0b00011010; // PB1= "1" piskak zapnout delay(200); PORTB = 0b00011000; // PB1= "0" piskak vypnout delay(1000); } } void setup() { DDRB = 0b00000111; // SDA i SCL nastavit na vstup, ostatni piny na vystupy PORTB = 0b00011000; // Pres Pull-Upy drz na SDA i SCL 1, vsechno ostatni zatim vypni delay (1000); // a jednu sekundu pockej // priprava PWM TCCR0A = 0b11000011; // rezim FAST PWM; vystup se nastavi do '1' pri dosazeni pozadovaneho cisla TCCR0B = 0b00000101; // FAST PWM, delic základní frekvence na 36Hz (pro prescaler='101b') OCR0A = 255; // PWM na 0% zapipej(); delay (3000); // a 3 sekundy pockej PORTB = 0b00011100; // PB2= "1" napajeni do serva zapnout OCR0A = 232; // Servo na plno (2.5ms) - vysyp obsah misky delay(1000); // sekundu pockej, nez se servo natoci na doraz OCR0A = 250; // Servo na minimum (0.5ms) - vrat misku do vychozi pozice delay(1000); // sekundu pockej, nez se servo natoci na doraz PORTB = 0b00011000; // PB2= "0" napajeni do serva vypnout delay(500); // pul sekundy pockej OCR0A = 255; // vypnout PWM - protoze uz je vypnute napajeni serva, nemelo by se nikam pohnout resetAF(); // vymazani Alarm Flagu v RTC pres I2C komunikaci, cimz dojde k okamzitemu odpojeni do ATtiny //----------------------------------------- // sem uz by se program nemel dostat. // pokud by jeste chvili vydrzel bezet na zbytky napajeni, dostane se do prazdne smycky loop() } void loop() { }