Управление Авто поливом

SKub
Offline
Зарегистрирован: 19.04.2015

вы не подскажете, как мне после отработки 1 функции , включить реле но только на 3 мин, реле включается если земля очень сухая, цикл проверки идет 1 раз в 15 мин. если оставить как есть, поливалка работает 15 мин, это много и перелив получается. Перепробовал всё. если просто морнать диодом он моргает тоже с интервалом в 15 мин. если по таймеру, то первый цикл проходит как надо, а на втором цикле просто моргнет очень быстро, и не включается на заданное время.

я уже не знаю где ошибка.

01    #define POLL_INTERVAL 4000   // опрос датчика интервал
02     #define POLL_PERIOD (20*20*1000) // через сколько все отключится
03  
04  //   bool poll_sensor = false;
05     unsigned long time_start;
06     unsigned long time_poll;
07     
08     long previousMillis = 0;        // храним время последнего переключения светодиода
09     long interval = 2000; 
10  
11 void setup(){             // ---------------------------------------------------
12  
13  Serial.begin(9600);
14   
15  ,
16 ,
17  
18 ,
19 ,
20  
21  
22    pinMode(diodRed,OUTPUT);  // для реле
23    pinMode(DAT, OUTPUT);    //используем 13 пин как выход (для включения/выключения датчика)
24  
25 }
26  
27 void loop()          //  ------------------------------------------------------------
28 {
29   int data[2];  
30   
31 ,
32  
33 ,
34 ,
35 ,
36 ,
37  
38     }
39   }  
40   
41    if ((time_poll==time_start) || ((millis()-time_poll)>POLL_INTERVAL))
42       {
43      unsigned long currentMillis = millis();  
44        
45    digitalWrite (DAT, HIGH);   // Включаем питание на датчик
46    delay (200);                     // задержка (для стабилизации питания датчика)
47    dat1 = analogRead (2);      // Считываем показания датчика (датчик в данном случае подключен ко входу А0)
48    digitalWrite (DAT, LOW);    // Выключаем питание датчика
49  
50  if (analogRead(2) <= 450) // Очень влажная почва
51  {
52  // digitalWrite(diodBlue, HIGH);
53   Serial.print("Ochen Vlagno ");
54   digitalWrite(diodRed, LOW);
55 }
56  
57 else if( analogRead(2)>450 && analogRead(2)<700)
58 {
59   Serial.print("Vlagnaya pochva ");  // Влажная почва
60   digitalWrite(diodRed, LOW);
61   
62 }
63  
64 else
65 {
66   digitalWrite(diodRed,HIGH);       // Сухая почва     Тут реле влючается
67   Serial.print("Suhays pochva ");
68   if(millis() - previousMillis > interval) {
69     // сохраняем время последнего переключения
70     previousMillis = millis();
71    
72  digitalWrite(diodRed,LOW); //  должно выключится через заданный интервал
73 digitalWrite(diodRed,!digitalRead(diodRed));
74  
75   }
76  
77  
78       Serial.print("Vlajnost ");
79        Serial.print(dat1);   // Влажность земли
80        Serial.println(" %%");
81        Serial.println();
82       
83        time_poll = millis();
84    
85       }
86       }}

 

SKub
Offline
Зарегистрирован: 19.04.2015

66 строка включает реле . и начинает поливать.

72 строка должна выключить реле через заданное время.  но это происходит только 1 раз. далее реле включается лишь на сотые доли секунды.  

Подскажите прошу , как заставить реле всегда включатся если почва сухая, на 2 мин.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Ну, вот как-то так:

void StartPump(unsigned int pump_time=1000){

      digitalWrite(PumpPin, HIGH);   //

      delay(pump_time);

      digitalWrite(PumpPin, LOW);   //

} // end StartPump

Если хотите в это время еще что-то делать, то в этой функции надо сначала сохранять millis() в previousMillis, после чего проверять, как это сделано у Вас.

Образец кода можно посмотреть в разделе "мигаем светодиодом без delay()"

Отдельной переменной держим состояние насоса: "включен" или "выключен", отсюда и логика обработки: либо старт (если сухо и насос=0), либо проверка интервала времени работы (насос=1), либо выключение (мокро и насос=1)...

А еще надо предусмотреть пролив, обрыв и замыкание датчика влажности. :) У меня было: датчик оборвался, и насос поливал пока вода не закончилась...

SKub
Offline
Зарегистрирован: 19.04.2015

Andrey Y Ostan

я понял вашу идею.

если выключать через delay(******);

через delay я уже пробовал, все работает, но вся программка виснет на это время.

вот я и пытаюсь разобраться как сделать через millis задержку на 3 мин.

когда включаю ардвинку если сухо реле включается на 2 мин. а через 15 мин если сухо, уже не включается, вот я и не понимаю в чем секрет.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

SKub, начните всё сначала. Вот вам основание. Кнопка на А2 -это условие срабатывания полива. Потом переделаете на analogRead, poliv_time - сколько времени поливать. poliv_flag - чтоб программа понимала поливает она или не поливает в данный момент. Светодиод на 13 пине будет гореть вместо насоса.

 

#define poliv_time 10000u // задержка работы на 10секунд
boolean poliv_flag=false; // флаг что идёт полив
void setup() {                
pinMode(A2,INPUT_PULLUP); // вход
pinMode (13,OUTPUT); // светодиод как-бы насос
}

void loop() {
if (digitalRead(A2)==LOW || poliv_flag==true) poliv();

}


void poliv(){
static unsigned long prevmillis; //локальная переменная для записи времени старта полива
  if (poliv_flag==false){ //если ещё не полив, а сюда попади, значит
             poliv_flag=true; //постапвим флаг что полив идёт
             prevmillis=millis(); // запомним время старта
              digitalWrite (13,HIGH); } // включим насос
            else if ((millis()-prevmillis) > poliv_time) { //а если полив уже шёл и время вышло, то
                    digitalWrite (13,LOW); //отключим насос
                    poliv_flag=false; }      //поставим флаг, что полив окончен.
                     }
                     
                     

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

SKub пишет:

когда включаю ардвинку если сухо реле включается на 2 мин. а через 15 мин если сухо, уже не включается, вот я и не понимаю в чем секрет.

Вы previousMillis не там сохраняете. Я же написал: при старте сохраняем, а позже - только проверяем... 70-ю строку сдвиньте на 66-ю позицию. Правда при влажной почве - Вы в этот цикл уже не попадете, так что проверять if(millis() - previousMillis > interval) надо где-то снаружи, наверное независимо от влажности.

SKub
Offline
Зарегистрирован: 19.04.2015

Разобрался сам, всё заработало как надо.

в свой код в Setup добавил Таймер с проверкой включено реле или нет. если вкл то выкл через 3 мин.

bwn
Онлайн
Зарегистрирован: 25.08.2014

SKub пишет:

Разобрался сам, всё заработало как надо.

в свой код в Setup добавил Таймер с проверкой включено реле или нет. если вкл то выкл через 3 мин.

Простите, а каким образом вы это сделали? Setup отрабатывает один раз после Reset. В нем же обычно идут команды инициации выхода (HIGH, LOW). Получается, либо вы не задали значение  для реле, либо оно может работать само по себе. Лучше код, а то людей запутаете.