Авто полив растений, с датчиком влажности.

Тема в разделе "Arduino & Shields", создана пользователем Крапивин, 23 апр 2015.

  1. Megakoteyka

    Megakoteyka Оракул Модератор

    Код (Text):
    #define INTERVAL_MEAS 15000
    #define INTERVAL_PUMP 3000

    long timeStartMeas;// время
    long timeStartPump;

    boolean pumpWork = false;// флаг "помпа работает"

    void setup()
    {
      timeStartMeas = millis();
    }

    void loop()
    {
      long currentTime = millis();
      if(currentTime - timeStartMeas >= INTERVAL_MEAS)// прошло 15 минут?
      {
        timeStartMeas = currentTime;// запоминаем время
        if(needWater)// нужно полить?
        {
          startPump();// включаем помпу
        }  
      }
     
      if(pumpWork)// помпа работает?
      {
        if(currentTime - timeStartPump >= INTERVAL_PUMP)// прошло 3 минуты?
          stopPump();// выключаем помпу
      }
    }

    // заглушка вместо измерения влажности
    boolean needWater()
    {
      return true;
    }

    // включение помпы
    void startPump()
    {
      timeStartPump = millis();// запоминаем время включения
      pumpWork = true;// ставим флаг
    }

    // выключение помпы
    void stopPump()
    {
      pumpWork = false;// снимаем флаг
    }
     
    Крапивин нравится это.
  2. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (Text):
    /*
    Раз в 15 мин проверяем влажность почвы.
    Если сухо - включаем полив на 3 мин
    */
    // Подключаем стандартную библиотеку LiquidCrystal
    //#include <LiquidCrystal.h>

    #define SOIL_SENSOR A0 // пин данных датчика влажности
    #define SOIL_POWER 4  // пин питания датчика влажности
    #define RELAY_PUMP 5  // пин для реле полива
    #define LED 13        // пин для индикации событий. Моргает 1 раз в 5 сек: все в порядке, не висим
                          // Горит: идет полив. Мерцает: что-то пошло не так, нужна помощь человека...

    const byte soilMin = 20;    // значение влажности, при котором пора включать полив
    const byte soilMax = 80;    // критическая величина влажности, когда пора паниковать (болото в горшке)
    const unsigned long soilInterval = 720000L; // интервал опроса датчика влажности (12 мин)
    const unsigned long relayTimeout = 180000L; // через сколько отключится полив (3 мин)
    const unsigned int ledBlink = 5000; // частота мигания светодиода
    const unsigned int ledFlick = 50;  // частота мерцания светодиода

    byte soilHumidity;          // переменная, где храним текущее значение влажности (условные проценты, т.е. 0% - пустыня, 80% - болото)
    unsigned long currTime;    // переменная, где храним текущее время проверки
    unsigned long prevSoilTime; // переменная, где храним время последней проверки влажности
    unsigned long prevPumpTime; // переменная, где храним время последней проверки длительности полива
    unsigned long prevBlinkTime; // переменная, где храним время последнего включения LED

    // LiquidCrystal lcd(11, 10, 9, 8, 7, 6); // Подключаем дисплей.


    // ---------------------------------------------------
    void setup()
    {
      Serial.begin(9600);
      pinMode(RELAY_PUMP,OUTPUT);
      pinMode(SOIL_POWER,OUTPUT);
      pinMode(LED,OUTPUT);
      digitalWrite(RELAY_PUMP, LOW); // отключаем полив
      digitalWrite(SOIL_POWER, LOW); // отключаем датчик влажности
      //lcd.begin(16,2);  //активируем дисплей
    }


    // ---------------------------------------------------
    void loop()
    {
      currTime = millis(); // обновляем текущее время проверки
      checkSoilSensor();  // проверяем влажность почвы
      checkPump();        // проверяем состояние полива
      blinkLed();          // управляем индикацией по текущему состоянию
    }


    // работаем с датчиком влажности почвы
    void checkSoilSensor()
    {
      if(currTime - prevSoilTime > soilInterval) // если от предыдущей проверки влажности прошло более 15 минут...
      {
        digitalWrite(SOIL_POWER, HIGH);        // подаем питание на датчик
        delay(100);                            // время на стабилизацию после включения
        soilHumidity = analogRead(SOIL_SENSOR); // читаем абсолютные показания датчика  
        digitalWrite(SOIL_POWER, LOW);          // выключаем питание датчика
        soilHumidity = map(soilHumidity,0,1023,0,100); // преобразуем показания в условные проценты (с ними визуально легче работать)
        outputToLCD();    // выводим показания на дисплей
        outputToSerial();  // дублируем показания на комп  
        if (soilHumidity < soilMin) startPump();  // если сухо, включаем полив
        if (soilHumidity > soilMax) alert();  // если критически мокро, то вопим на всю Ивановскую
        prevSoilTime = currTime;  // запоминаем время проверки
      }
    }


    // выводим показания влажности на дисплей
    void outputToLCD()
    {
      /*
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Soil Humi:");
      lcd.setCursor(12, 0);
      lcd.print(soilHumidity); // выводим значение на LCD
      lcd.print("%");
      */
    }


    // выводим показания влажности в Serial порт
    void outputToSerial()
    {
      Serial.print("Soil Humidity: ");
      Serial.print(soilHumidity);
      Serial.print("%");
      if ( (soilHumidity > soilMin) &&  (soilHumidity < soilMax) ) Serial.print("\t HOPMA");
      else if (soilHumidity < soilMin) Serial.print("\t MALO!");
            else if (soilHumidity > soilMax) Serial.print("\t MHOGO!!");
    }


    // проверяем состояние полива
    void checkPump()
    {
      if( digitalRead(RELAY_PUMP) && (currTime - prevPumpTime > relayTimeout) ) // если реле включено И поливаем уже больше 3 минут...
      {
        stopPump();              // отключаем полив
      }
    }


    // включаем полив
    void startPump()
    {
      //lcd.setCursor(0, 1);                  // выводим сообщения
      //lcd.print("POLIVAEM          ");
      Serial.println("\nPOLIVAEM");
      digitalWrite(LED, HIGH);                // включаем светодиод на постоянное свечение
      digitalWrite(RELAY_PUMP, HIGH);          // включаем реле для полива
      prevPumpTime = currTime;                // запоминаем время включения реле
    }


    // отключаем полив
    void stopPump()
    {
      //lcd.setCursor(0, 1);                    // выводим сообщения
      //lcd.print("POLIV OKOH4EH        ");
      Serial.println("\nPOLIV OKOH4EH");
      digitalWrite(RELAY_PUMP, LOW);          // отключаем реле для полива
      digitalWrite(LED, LOW);                  // отключаем светодиод
    }


    // мигаем LED по текущему состоянию системы
    void blinkLed()
    {
      if(!digitalRead(RELAY_PUMP)) // если сейчас нет полива (реле выключено)...
      {
        if(currTime - prevBlinkTime > ledBlink) // если прошло более 5 сек с момента мигания LED
        {
          digitalWrite(LED, !digitalRead(LED));  // показываем, что не висим: мигаем LED (меняем его состояние на противоположное)
        }
        else if ( (soilHumidity > soilMax) && (currTime - prevBlinkTime > ledFlick) ) // если очень мокро
          {
            digitalWrite(LED, !digitalRead(LED));  // мерцаем LED
          }
      }
    }


    // кричим о том, что в горшке болото и нужна помощь
    void alert()
    {
      //lcd.setCursor(0, 1);                    // выводим сообщения
      //lcd.print("***MHOGO VODY!        ");
      Serial.println("***MHOGO VODY!");
      //stopPump(); // на всякий случай еще раз выключаем реле
    }
     
    Крапивин нравится это.
  3. iglooshtosser

    iglooshtosser Гик

    Смотрите что происходит с вашей провепкой:
    Вы обновили previosMillis, а через одну команду сравниааете прошедшее время с интералом.
    Но мнжду ообновлением и проверкой проходит одна-две миллисекунды, значит условие пикогда не выполняется.
     
  4. Надеюсь, что не ошибся в логике. Не отлаживался. Проверяйте.
    unsigned long PreviousMillis = 0; // храним время последнего переключения чего угодно
    int Job_flag = 1; //Флаг задачи паузы включить

    int pause(long _interval)
    {
    unsigned long currentMillis = millis();
    if((currentMillis - PreviousMillis) > _interval)
    {
    PreviousMillis = currentMillis; //Начинаем новый отсчет времени
    return HIGH;
    }
    else
    return LOW;
    }

    void setup()
    {
    Serial.begin(9600);
    pinMode(5,OUTPUT);

    }

    void loop()
    {
    if(Job_flag == 1)
    {
    if(pause(900000) == HIGH) //Прошло 15 минут проверим влажность почвы. Если влажная ждем еще 15 минут
    {
    if(analogRead(2) <= 450) //Почва сухая. Включаем полив. Проверьте данные с датчика!
    { digitalWrite(5, HIGH);
    Job_flag = 2; //Флаг задачи полива включить
    }
    }
    }
    if(Job_flag == 2)
    { if(pause(60000) == HIGH) //Прошла 1 минута выключим насос
    {
    digitalWrite(5, LOW);
    Job_flag = 1; //Флаг задачи пауза включить
    }
    }
    }
     
    Последнее редактирование: 26 апр 2015
    Крапивин нравится это.
  5. Боюсь соврать, но внутренний таймер Arduino UNO связан с 5 пином. Давно это было. delay() работает от внутреннего таймера, millis() то же. Не знаю Вашу реализацию, что то может пересекаться. Но для работоспособности код должен быть правильным. А код я Вам выложил, смотрите.
     
    Последнее редактирование: 26 апр 2015
  6. Сегодня протестировал на установленной у меня на компьютере программы VBB http://www.virtualbreadboard.com/, код работает на все 100%.
    Уважаемые коллеги! У меня очень мало времени для решения частных задач. Это решение программного кода для меня нонсенс, поверил искренности Коллеги. Решил помочь. Мне тоже пригодится, обязательно! Мне показалось что Коллега продвинутый и попал в классический ступор. Сам грешен. Ждем от него схемы его реализации, хотя бы описательно.
     
    Последнее редактирование: 26 апр 2015
    Крапивин нравится это.
  7. Крапивин

    Крапивин Нерд

    Александр БОЛЬШОЕ Спасибо.
    выручили.
    и в самом деле все оказалось просто, я сам застрял в коде.
    сей час все заработало.
    теперь есть 2 близких кода. и все работают. Всем Спасибо.
    я добавил в код еще сканирование DHT22 датчика влажности и температуры.
    и добавил еще передатчик на 433 мгц. теперь можно включать помпу на расстоянии, чтоб меньше проводов по участку бросать.
    работает всё от аккумуляторов и солнечной батареи.

    4 МАЯ начну полевые испытания на даче, обязательно отпишусь как всё работает.

    Всем спасибо, что столкнули с мертвой точки.
     
  8. Hanter

    Hanter Нерд

    Что то тема совсем завяла, в этом сезоне буду пробовать контроллер полива на меге, датчики влажности емкостные от почвы изолированны двойным слоем термоусадки. Для включения полива и проверки влажности вот кусочек кода :
    if (round(HH1) <= on1) {
    digitalWrite(Pin1, HIGH);
    p1 = 1; }
    if (round(HH1) >= off1) {
    digitalWrite(Pin1, LOW);
    p1 = 0;
    }
    switch (p1) {
    case 0:
    break;
    case 1:
    currentTim1 = millis();
    if (currentTim1 >= (loopTim1 + 180000)) {
    digitalWrite(Pin1, HIGH);
    p1 = 2;
    loopTim1 = currentTim1;
    }
    break;
    case 2:
    currentTim1 = millis();
    if (currentTim1 >= (loopTim1 + T1*60000)) { //задержка 3 мин
    digitalWrite(Pin1, LOW);
    p1 = 3;
    loopTim1 = currentTim1;
    }
    break;
    case 3:
    if (round(HH1) >= off1) {
    digitalWrite(Pin1, LOW);
    p1 = 0;
    }
    else {
    p1 = 1;
    }
    break;

    в первой задержке пауза (полив выключен) сейчас 3 мин, будет минут 5 или больше, во второй Т1 настраивается в меню установок от 0 до 255 минут идет полив. Даже если проскочит помеха, по уровням (on1, off1, то же настраиваются в меню) сработает и восстановится работа.
     
  9. Форумный народ обычно стебается. Они в своей среде для ... ,им не нравится, наверное заумное. Хотят проще . Если хотите, можете посмотреть http://fedoroffalexander.wix.com/Smart
     
    Последнее редактирование: 27 мар 2016
  10. Так и завял.
     
  11. Hanter

    Hanter Нерд

    Александр, я смотрю Вы давно вроде занимаетесь поливом, может экспериментально установили сколько времени надо устанавливать на пропитку земли перед следующим замером.
     
  12. Да сильно не заморачивался. Когда датчик зальет водой, т.е. больше 700 у.е, так и выключаю воду. Если после этого влажность земли ниже 300 у.е., полив снова включается. В программе сделаны переменные которые можно установить в ручном режиме и отражают максимальны и минимальный пороги датчика влажности земли.
     
  13. Hanter

    Hanter Нерд

    А как у тебя сделаны датчики влажности земли?
     
  14. Hanter

    Hanter Нерд

    Федоров Александр нравится это.
  15. Вложения:

  16. Hanter

    Hanter Нерд

    Они же окисляются быстро и пороги плывут. Я примерно такой у китайцев заказывал, лежит без дела. Так этот датчик выдает аналоговый сигнал? на фото видно только пластинка с электродами или электроника с обратной стороны? У тебя эти датчики на участке стоят или в горшках? Если аналоговый какое расстояние до контроллера? Извини за кучу вопросов, просто интересно.
     
  17. Hanter

    Hanter Нерд

    Да, вообще непонятная схема, откуда сигнал снимается? со 2-го вывода датчика, а транзистор для опроса?
     
  18. Да окисляются, но 200 р., не сумма. Электроника запаяна со стороны разъема. Пороги не сильно уходят, для полива достаточно. Тем более можно скорректировать. А так стыдно сказать. В боевой обстановке только поливает горшки дома. Это только хобби, не серьезно. Хотя в свое время и слесарил и автомобили сам ремонтировал. Сейчас лениво приложить руки. Да и основная работа занимает все время. Но работает. Это прикольно. Сейчас заставляю себя подключить счетчики расхода воды. А на даче я все заровнял под английский газон. Очень удобно косить газонокосилкой. Поливать нечего.
     
  19. Мне тоже не очень понятен наворот схемы. Может кто ни будь разъяснит.
     
  20. Hanter

    Hanter Нерд

    А я наоборот, снова начал заниматься, дочура прошлый год сад купила, запущенный..., всю осень приводил его в порядок, теплицу поставил, вот теперь хочу его немного автоматизировать, бак водяной на пару метров поднять, чтобы самотек был, насосик надо приспособить, что бы его наполнять, заодно и программировать немного научился, ардуинку с TFT приобрел. Сейчас скетч на управление 5-ю каналами, опрос трех DHT22 и температуры поливочной воды (DS18B20) написал, на столе вроде все работает, ближе к лету в сад перенесу
     
    Федоров Александр нравится это.