Каждые восемь секунд измеряет влажность почвы в горшке (датчик из двух карандашных грифелей, воткнутых в почву и резистора на 10кОм), после чего поливает, если ему показалось, что в горшке слишком сухо.
Мозги, как и сказано - ATtiny13, питается от батарейки для телефона. два самодельных датчика влаги (по сопротилению) из графитовых грифелей и резисторов номиналом 10 кОм, управление нагрузкой через полевой транзистор. Насос - для стеклоомывателя автомобилей ВАЗ (~150 руб), питается от батареи Крона. Трубки покупал отдельно. Можно в медтехнике или (лучше) в магазинах для аквариумистов.
/* Проект полноценного автополива цветка на ATtiny13, прошивается из среды Arduino by donpavlensio.livejournal.com При создании использовались стандартные примеры и выложенные в общий доступ, спасибо авторам! Прогамма для общего пользования без доп. условий. Для работы нужен насос (лучше всего от стеклоомывателя ВАЗ), полевой транзистор, датчики влажности почвы легко собираются из графитовых грифелей и резисторов на 10 кОм */ #define F_CPU 1200000UL // Частота МК в герцах #include #include // здесь организована работа с ватчдогом #include // здесь описаны режимы сна #include #include // работа с прерываниями #include #define bottlefeed 1 //питание датчика воды #define bottleread A1 // прием данных по воде #define plantfeed 4 // питание датчика в горшке #define plantread A3 // чтения данных с горшка #define motorfeed 0 // питание мотора int water =0; // переменная для значения влажности в бутылке, т.е. наличия воды int moisture = 0; // переменная для значения влажности в горшке int zadan = 380; //заданное значение влажности, ниже которого проводить полив void setup(){ wdt_reset(); // сначала нужно сбросить вачдог // иначе может быть ребут
pinMode(bottlefeed, OUTPUT); //настариваем соответствующие пины на вход/выход pinMode(plantfeed, OUTPUT); pinMode(motorfeed, OUTPUT); pinMode(bottleread, INPUT); pinMode(plantread, INPUT);
} void loop(){
digitalWrite(bottlefeed, 1); // подаем питание для датчика в бутылке delay(1000); //задержка может быть и меньше, такая осталась со времен отладки)) water = analogRead(bottleread); //читаем напряжение с датчика delay(1000); // аналогично, задержка для удобств отладки if (water > 20){ //если вода есть, то // if (water){ digitalWrite(plantfeed, 1); //подаем питание на датчик в горшке delay(500); //сразу мерять нельзя, будут нули, но можно и меньше 500 moisture = analogRead(plantread); // читаем значения второго датчика
if (moisture < zadan){ // если влажность ниже заданного уровня, то digitalWrite(plantfeed,0); //отключаем питание датчиков digitalWrite(bottlefeed, 0); //
digitalWrite(motorfeed, 1); //подаем питание на мотор (вернее, на затвор полевого транзистора delay(5000); // ждем 5 секунд, пока идет полив digitalWrite(motorfeed, 0); //отключаем мотор delay(60000); //ждем минутку, чтобы прибор ничего не делал, пока вода впитывается. Во избежание переполива } if(moisture >= zadan){ //если влажность больше или равна заданной, то digitalWrite(plantfeed,0); //выключаем датчики digitalWrite(bottlefeed, 0); // delay(1000); // отладочная задержка, можно убрать sleepFewSeconds(); //запускаем программу сна } } else { sleepFewSeconds();// во всех прочих случаях спим } } void sleepFewSeconds() { // программа сна
wdt_reset(); // сбрасываем ватчдог PORTB = 0x00; // подаём лог. 0 на все порты DDRB = 0x00; ADCSRA &= ~(1 << ADEN); // отключаем АЦП // иначе будет лишний ток потребления в режиме сна MCUSR &= ~(1< // Start the WDT Config change sequence. WDTCR |= (1< // Configure the prescaler and the WDT for interrupt mode only // Раскомментируй тот интервал, какой нужно WDTCR = (1< //WDTCR = (1< //WDTCR = (1< WDTCR |= (1< sei(); // Enable global interrupts set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную while(1) { sleep_enable(); // разрешаем сон sleep_cpu(); // спать! sleep_disable(); }