Previous Entry Share Next Entry
Автополив цветка на ATtiny13
donpavlensio
Второй пошел, поливалка:



Каждые восемь секунд измеряет влажность почвы в горшке (датчик из двух карандашных грифелей, воткнутых в почву и резистора на 10кОм), после чего поливает, если ему показалось, что в горшке слишком сухо.

Мозги, как и сказано - ATtiny13, питается от батарейки для телефона. два самодельных датчика влаги (по сопротилению) из графитовых грифелей и резисторов номиналом 10 кОм, управление нагрузкой через полевой транзистор.
Насос - для стеклоомывателя автомобилей ВАЗ (~150 руб), питается от батареи Крона. Трубки покупал отдельно. Можно в медтехнике или (лучше) в магазинах для аквариумистов.

Разведенная печатная плата для ЛУТ:



Проект в Proteus (что-то там мотор не хочет работать нормально, зараза)
https://yadi.sk/d/1_LnhQXcmj5md

Ну и код для микроконтроллера:
[Нажмите, чтобы посмотреть]

  • /*
    Проект полноценного автополива цветка на ATtiny13, прошивается из среды Arduino
    by donpavlensio.livejournal.com
    При создании использовались стандартные примеры и выложенные в общий доступ, спасибо авторам!
    Прогамма для общего пользования без доп. условий.
    Для работы нужен насос (лучше всего от стеклоомывателя ВАЗ), полевой транзистор,
    датчики влажности почвы легко собираются из графитовых грифелей и резисторов на 10 кОм
    */
    #define F_CPU 1200000UL  // Частота МК в герцах
    #include <avr/io.h>
    #include <avr/wdt.h> // здесь организована работа с ватчдогом
    #include <avr/sleep.h> // здесь описаны режимы сна
    #include <avr/power.h>
    #include <avr/interrupt.h> // работа с прерываниями
    #include <util/delay.h>
    #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<<WDRF);
    // Start the WDT Config change sequence.
    WDTCR |= (1<<WDCE) | (1<<WDE);
    // Configure the prescaler and the WDT for interrupt mode only
    // Раскомментируй тот интервал, какой нужно
    WDTCR = (1<<WDP0) | (1<<WDP3) | (1<<WDTIE); // 8sec
    //WDTCR = (1<<WDP2) | (1<<WDP1) | (1<<WDTIE); // 2sec
    //WDTCR = (1<<WDP2) | (1<<WDP0) | (1<<WDTIE); // 0.5sec
    WDTCR |= (1<<WDTIE);
    sei(); // Enable global interrupts
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
    while(1) {
      sleep_enable(); // разрешаем сон
      sleep_cpu(); // спать!
      sleep_disable();
    }
    }




На сем с ATtiny  я, пожауй, на пока наигрался.



?

Log in