/* Контроль протечки и перелива воды в баке fuses: Low = 0x6a High = 0xff atTiny13a ----------------- PB5 - 1 - | RES VCC | - 8 Open - 2 - | PB3 PB2 | - 7 SCK - Beep Close - 3 - | PB4 PB1 | - 6 MISO - sensors 4 - | GND PB0 | - 5 MOSI - Led ----------------- */ #include #include #include #define PIN_OPEN PB3 // открытие #define PIN_CLOSE PB4 // закрытие #define PIN_BEEP PB2 // выход beep #define PIN_LED PB0 // выход led #define PIN_SENSOR PB1 // датчики uint8_t TIME_WORK_VALVE = 3; // время работы клапана, сек (нужно измерить и немного прибавить) uint8_t PAUSE_OPEN = 5; // пауза до открытия вентиля после его закрытия, сек bool flagOpen = true; bool flagClose = true; const uint8_t timeBlink = 5; // время между вспышками LED в покое const uint32_t countInterrupt = 92; // Время через которое вентиль закроется/откроется автоматически (антиприкипание): // 7дн * 24ч * 60м * 60с = 604800сек / (1 / 1200000 / 1024 / 255 = 0.218сек) = 2774312 // 2774312 - заносим в переменную =countInterrupt= uint32_t count = countInterrupt; //==================================================================== void beepHold(uint8_t b) // Звуковая индикация режима: { for (uint8_t i = 0; i < b; ++i) { PORTB &= ~(1 << PIN_BEEP); _delay_ms(50); PORTB |= (1 << PIN_BEEP); _delay_ms(50); } } //==================================================================== void workServoOpen() { cli(); PORTB |= (1 << PIN_LED); beepHold(1); PORTB |= (1 << PIN_OPEN); PORTB &= ~(1 << PIN_CLOSE); flagOpen = false; flagClose = true; sei(); _delay_ms(TIME_WORK_VALVE * 1000); PORTB &= ~(1 << PIN_OPEN); PORTB &= ~(1 << PIN_CLOSE); } //==================================================================== void workServoClose() { PORTB |= (1 << PIN_LED); beepHold(2); PORTB &= ~(1 << PIN_OPEN); PORTB |= (1 << PIN_CLOSE); _delay_ms(TIME_WORK_VALVE * 1000); PORTB &= ~(1 << PIN_OPEN); PORTB &= ~(1 << PIN_CLOSE); } //==================================================================== void ledWorkPause(uint16_t b) // Индикация паузы после закрытия вентиля: { PORTB |= (1 << PIN_LED); for (uint8_t i = 0; i < b; ++i) { PORTB ^= (1 << PIN_LED); _delay_ms(1000); } PORTB &= ~(1 << PIN_LED); } //==================================================================== ISR(INT0_vect) { if (flagClose) workServoClose(); ledWorkPause(PAUSE_OPEN); flagOpen = true; // флаг разрешения открытия вентиля flagClose = false; count = countInterrupt; } //==================================================================== ISR(TIM0_OVF_vect) { if (!--count) { beepHold(2); workServoClose(); ledWorkPause(PAUSE_OPEN); flagOpen = true; // флаг разрешения открытия вентиля flagClose = false; } } //==================================================================== int main(void) { // инициализация порта DDRB |= (1 << PIN_CLOSE) | (1 << PIN_OPEN) | (1 << PIN_BEEP) | (1 << PIN_LED); DDRB &= ~(PIN_SENSOR); PORTB |= (1 << PIN_SENSOR) | (1 << PIN_BEEP); _delay_ms(1000); // заводим таймер Т0 по переполнению: TIMSK0 |= (1 << TOIE0); TCCR0B |= (1 << CS02) | (1 << CS00); TCNT0 = 0; // заводим INT0: GIMSK |= (1 << INT0); sei(); //=================================== while (1) { if (flagOpen) { workServoOpen(); count = countInterrupt; PORTB &= ~(1 << PIN_LED); } // Мигаем светодиодом: PORTB ^= (1 << PIN_LED); if (PORTB & (1 << PIN_LED)) { _delay_ms(timeBlink * 1000 / 60); } else { _delay_ms(timeBlink * 1000 - timeBlink * 1000 / 60); } } } //====================================================================