Модификация скетча

SamFer
Offline
Зарегистрирован: 22.04.2019

Уважаемые господа, добрый день!

У меня есть сектч, с помощью некоторых из вас написанный, для полива растений.

Сейчас сделано так, что Relay2 включается в том случае если срабатывает датчик уровня воды и выключается когда уровень воды падает. Но реальность такова, что мне требуется, чтобы после включения Relay2 работал еще какое-то время после падения уровня. Направьте, пожалуйста, куда копать?

Спасибо за помощь!

Скетч во вложении:

 

#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
    iarduino_RTC time(RTC_DS3231);                          // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C
    #include <LiquidCrystal.h>                                                           //
    #define DIODE_DROP  0.7 
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    int relay = 5;
    int relay2 = 6;
    String RT = "50";
    String RT2 = "50";
    String TimeOn = "12:00:00";
    String TimeOff = "12:05:00";
    String TimeOn2 = "23:00:00";
    String TimeOff2 = "23:05:00";
    const uint8_t L1 = 2;
                                                     
void setup(){   
    pinMode(L1, INPUT_PULLUP);   
    pinMode(relay, OUTPUT);
    pinMode(relay2, OUTPUT);
    digitalWrite(relay, LOW);                                                        //
    digitalWrite(relay2, LOW);
    delay(300);                                             // Ждем готовности модуля отвечать на запросы
    Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
    time.begin();                                           // Инициируем работу с модулем.
    lcd.begin(16, 2);
    lcd.print("Current time:");

}                                                           //
void loop()
{                                               
  if(millis()%1000>=0)
{                                                            // Если прошла 1 секунда.
      lcd.setCursor(0, 1);
      lcd.print(time.gettime("d-m H:i:sA"));                 // Выводим время.
}  
    
RT = time.gettime("H:i:s");
RT2 = time.gettime("H:i:s");
    
  if (RT == TimeOn)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT == TimeOff)
{
  digitalWrite(relay, LOW);
} 
if (RT2 == TimeOn2)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT2 == TimeOff2)
{
  digitalWrite(relay, LOW);
} 

if (!digitalRead(L1))
  digitalWrite(relay2, HIGH);
  else
  digitalWrite(relay2, LOW);

}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Вместо отключения реле2(стр 62) запомните время в новой переменной события(как стр37) и добавьте к нему время на ожидание. Добавте провеку события так же как в строках 45-47 и выключитите реле2. 

SamFer
Offline
Зарегистрирован: 22.04.2019

Спасибо большое за подсказку!

Сделал вот так:

А теперь при проверки скетча пишет "Ошибка для компиляции платы".

#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
    iarduino_RTC time(RTC_DS3231);                          // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C
    #include <LiquidCrystal.h>                                                           //
    #define DIODE_DROP  0.7 
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    int relay = 5;
    int relay2 = 6;
    String RT = "50";
    String RT2 = "50";
    String RT3 = "50";
    String TimeOn = "12:00:00";
    String TimeOff = "12:05:00";
    String TimeOn2 = "23:00:00";
    String TimeOff2 = "23:05:00";
    String TimeOff3 = "00:02:00";
    const uint8_t L1 = 2;
                                                     
void setup(){   
    pinMode(L1, INPUT_PULLUP);   
    pinMode(relay, OUTPUT);
    pinMode(relay2, OUTPUT);
    digitalWrite(relay, LOW);                                                        //
    digitalWrite(relay2, LOW);
    delay(300);                                             // Ждем готовности модуля отвечать на запросы
    Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
    time.begin();                                           // Инициируем работу с модулем.
    lcd.begin(16, 2);
    lcd.print("Current time:");

}                                                           //
void loop()
{                                               
  if(millis()%1000>=0)
{                                                            // Если прошла 1 секунда.
      lcd.setCursor(0, 1);
      lcd.print(time.gettime("d-m H:i:sA"));                 // Выводим время.
}  
    
RT = time.gettime("H:i:s");
RT2 = time.gettime("H:i:s");
    
  if (RT == TimeOn)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT == TimeOff)
{
  digitalWrite(relay, LOW);
} 
if (RT2 == TimeOn2)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT2 == TimeOff2)
{
  digitalWrite(relay, LOW);
} 

if (!digitalRead(L1))
  digitalWrite(relay2, HIGH);
  RT3 = time.gettime("H:i:s");
if (RT3 + TimeOff3 == time.gettime("H:i:s"));
  digitalWrite(relay2. LOW);
}

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Пардонте. Нашел ошибку вот тут: digitalWrite(relay2. LOW);

Исправил "точку" на "запятую". Сейчас пойду и проверю, работает ли )))

 

Спасибо за помощь!

nik182
Offline
Зарегистрирован: 04.05.2015

В таком виде может пропускать отключение. Если датчик сработает позже 2 минут, то условие в сторке 64 никогда не выполнится. Нужно поставить знак сравнения больше. У Вас отчёт от включения, а надо от срабатывания датчика. 

SamFer
Offline
Зарегистрирован: 22.04.2019

Спасибо за совет!

Сейчас попробовал первоначальный вариант и Ваш. Но в итоге все равно не работает. Если поплавок поднять, то реле начинает выдавать "автоматную очередь". За секунду включается и выключается неисчислимое количество раз. :)

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

64 строка вообще не работает, да что предполагается во всей связки строк 61-65 я могу только догадываться. Уважаемый ТС, Вы конечно крутой программист, но пока я бы посоветовал использовать if(){Ваши действия } 

SamFer
Offline
Зарегистрирован: 22.04.2019

В строках:

 

61: Если поднимается датчик уровня воды

62: Включить реле

63: В переменную RT3 записываем текущее время с часов.

64: Если текущее время + время в переменной TimeOff3 равно текущему времени

65: Выключить реле.

Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Тогда должно быть вот так:

if (!digitalRead(L1)){
  digitalWrite(relay2, HIGH);
  RT3 = time.gettime("H:i:s");
}
if ((RT3 + TimeOff3) == time.gettime("H:i:s")){
  digitalWrite(relay2. LOW);
}

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Спасибо большое за помощь!

Сделал так, но чет не работает. Реле включается, но работает бесконечно, не реагируя на условие. Не выключается по заданному промежутку времени.

nik182
Offline
Зарегистрирован: 04.05.2015

Главная ошибка - запоминать время нужно не в момент включения а в момент выключения. А потом делать отдельную проверку полученного времени и потом только отключать реле. В одно if этого не сделать. Они разнесены у вас по времени. Это отдельные процессы и для каждого нужен свой отдельный if. 

SamFer
Offline
Зарегистрирован: 22.04.2019

Имеется ввиду: момент выключения датчика уровня воды?

nik182
Offline
Зарегистрирован: 04.05.2015

Момент когда надо отключить реле. Как это момент связан с датчиком я не знаю. У вас нет комментариев что чему соответствует в программе. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

SamFer пишет:

Спасибо большое за помощь!

Сделал так, но чет не работает. Реле включается, но работает бесконечно, не реагируя на условие. Не выключается по заданному промежутку времени.

Да оно и не должно работать.

Пока я Вам показал только неправильность синтаксиса. Теперь перейдем к логике Вашей программы. Итак - у Вас упал уровень Вы зафиксировали это время (реле не трогаем), когда нужное время прошло мы выключаем реле.

Но есть у меня сомнения: первое в строке 66 надо ставить не ==, а >=, и второе - а выдайте на порт (RT3 + TimeOff3) и time.gettime("H:i:s") из строки 65. Чет мне кажется, что они не сравнимы.

SamFer
Offline
Зарегистрирован: 22.04.2019

1) Поставил ">=" - при поднятии уровня воды реле начинает выдавать "автоматную очередь".

2) Вывел на порт и действительно, они не сравнимы. time.gettime выдает 12:32:56, а (RT3 + TimeOff3) выдает 5000:00:05.

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Просто RT3 выдает значение "50" - изначально заложенное

Просто TimeOff3 выдает "00:02:00" - изначальное заложенное

 

Получается, что RT3 не записывает текущее время после If.

#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
    iarduino_RTC time(RTC_DS3231);                          // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C
    #include <LiquidCrystal.h>                                                           //
    #define DIODE_DROP  0.7 
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    int relay = 5; // Определение пина для реле включения насоса полива
    int relay2 = 6; // Определение пина для реле включения насоса перекачки воды в основной бак
    String RT = "50";
    String RT2 = "50";
    String RT3 = "50";
    String TimeOn = "12:00:00";
    String TimeOff = "12:03:00";
    String TimeOn2 = "23:00:00";
    String TimeOff2 = "23:03:00";
    String TimeOff3 = "00:02:00";
    const uint8_t L1 = 2;
                                                     
void setup(){   
    pinMode(L1, INPUT_PULLUP);   
    pinMode(relay, OUTPUT);
    pinMode(relay2, OUTPUT);
    digitalWrite(relay, LOW);                                                        //
    digitalWrite(relay2, LOW);
    delay(300);                                             // Ждем готовности модуля отвечать на запросы
    Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
    time.begin();                                           // Инициируем работу с модулем.
    lcd.begin(16, 2);
    lcd.print("Current time:");

}                                                           //
void loop()
{                                               
  if(millis()%1000>=0)
{                                                            // Если прошла 1 секунда.
      lcd.setCursor(0, 1);
      lcd.print(time.gettime("d-m H:i:sA"));                 // Выводим время.
}  
    
RT = time.gettime("H:i:s");
RT2 = time.gettime("H:i:s");
    
  if (RT == TimeOn)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT == TimeOff)
{
  digitalWrite(relay, LOW);
} 
if (RT2 == TimeOn2)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT2 == TimeOff2)
{
  digitalWrite(relay, LOW);
} 

if (!digitalRead(L1)){
  digitalWrite(relay2, HIGH);
  RT3 = time.gettime("H:i:s");
}
if ((RT3 + TimeOff3) >= time.gettime("H:i:s")){
  digitalWrite(relay2, LOW);
}
Serial.println(time.gettime("H:i:s"));
Serial.println(RT3+TimeOff3);
Serial.println(RT3);
Serial.println(TimeOff3);
//else 
  //digitalWrite(relay2, LOW);
//RT3 = time.gettime("H:i:s");

//if (RT3 + TimeOff3 > time.gettime("H:i:s"));
  //digitalWrite(relay2, LOW);
}

 

SamFer
Offline
Зарегистрирован: 22.04.2019

А если сделать так, чтобы сработал датчик уровня воды, то значение в (RT3 + TimeOff3) принимает вот такой вид: "12:45:2500:02:00". 

То есть он не плюсует время, а просто добавляет в строку.

 
SLKH
Offline
Зарегистрирован: 17.08.2015

А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

SLKH пишет:

А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?

Здравая мысль! А почему Вам после того, как опустился уровень просто не подождать с помоцью delay() и не выключить реле? delay() пугает? Так Вы его не бойтесь - он хороший и многие программы на ассемблере написаны именно с подобной функцией.

SLKH
Offline
Зарегистрирован: 17.08.2015

SamFer пишет:

 

Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.

loop()

{

  если (сработал датчик)  { включили реле;   запомнили t1=millis();   }

  если (millis()-t1 > 2 минут)   {    выключили реле;   }

}

Уфф...

SamFer
Offline
Зарегистрирован: 22.04.2019

SLKH пишет:

А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?

 

Видимо да, я из-за незнания многих вещей путаю сам себе и вам мозги )))

SamFer
Offline
Зарегистрирован: 22.04.2019

mykaida пишет:

SLKH пишет:

А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?

Здравая мысль! А почему Вам после того, как опустился уровень просто не подождать с помоцью delay() и не выключить реле? delay() пугает? Так Вы его не бойтесь - он хороший и многие программы на ассемблере написаны именно с подобной функцией.

Если честно, то да. Побаиваюсь Delay, так как у меня время выведено на LCD экран и если ставить delay, но оно перестает "тикать". Чисто эстетическая "заморочка". :) Да еще я подумал, раз есть RTC, то почему бы к нему все и не привязывать, но видимо криво все получается у меня. ))

SamFer
Offline
Зарегистрирован: 22.04.2019

SLKH пишет:

SamFer пишет:

 

Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.

loop()

{

  если (сработал датчик)  { включили реле;   запомнили t1=millis();   }

  если (millis()-t1 > 2 минут)   {    выключили реле;   }

}

Уфф...

 

Спасибо большое за помощь! Сегодня вечером доеду еще раз до гаража и попробую это реализовать.

SamFer
Offline
Зарегистрирован: 22.04.2019

Спасибо Вам большое за помощь!

Код работает, но с существенным нюансом. Если срабатывает датчик уровня воды, то включается реле и работает 2 минуты (либо любое другое заданное время). Но если датчик уровня воды срабатывает повторно, то ничего не происходит. Цикл не выполняется. :)

SLKH
Offline
Зарегистрирован: 17.08.2015

SamFer пишет:

Спасибо Вам большое за помощь!

Код работает, но с существенным нюансом. Если срабатывает датчик уровня воды, то включается реле и работает 2 минуты (либо любое другое заданное время). Но если датчик уровня воды срабатывает повторно, то ничего не происходит. Цикл не выполняется. :)

Как можно не выполнить "  если (сработал датчик)  { включили реле;   запомнили t1=millis();   } " ?

Давай весь код.  

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Может так (стоит 2 мин - не проверял)

#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS3231);                          // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C
#include <LiquidCrystal.h>                                                           //
#define DIODE_DROP  0.7 
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
int relay = 5;
int relay2 = 6;
String RT = "50";
String RT2 = "50";
String TimeOn = "12:00:00";
String TimeOff = "12:05:00";
String TimeOn2 = "23:00:00";
String TimeOff2 = "23:05:00";
const uint8_t L1 = 2;

uint32_t pausa;
bool f_pausa = 0;

void setup(){   
  pinMode(L1, INPUT_PULLUP);   
  pinMode(relay, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay, LOW);                                                        //
  digitalWrite(relay2, LOW);
  delay(300);                                             // Ждем готовности модуля отвечать на запросы
  Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
  time.begin();                                           // Инициируем работу с модулем.
  lcd.begin(16, 2);
  lcd.print("Current time:");

}                                                           //
void loop()
{                                               
  if(millis()%1000>=0)
  {                                                            // Если прошла 1 секунда.
    lcd.setCursor(0, 1);
    lcd.print(time.gettime("d-m H:i:sA"));                 // Выводим время.
    if(f_pausa) pausa++;
    if(pausa >= 120000) { // 2 minut
      f_pausa = 0;
      pausa = 0;
    }
  }  

  RT = time.gettime("H:i:s");
  RT2 = time.gettime("H:i:s");

  if (RT == TimeOn)
  {
    digitalWrite(relay, HIGH);
  }

  if (RT == TimeOff)
  {
    digitalWrite(relay, LOW);
  } 
  if (RT2 == TimeOn2)
  {
    digitalWrite(relay, HIGH);
  }

  if (RT2 == TimeOff2)
  {
    digitalWrite(relay, LOW);
  } 
  if (!digitalRead(L1)) f_pausa = 1;
  digitalWrite(relay2, f_pausa);
}

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Вот так выглядит код. 

Элемент Вашего кода сейчас закомментирован, так как новые культуры уже посадил и загрузил старую прошивку, чтобы полив осущствлялся. Но когда пробовал, то второй раз не включалось. Вручную активировал датчик уровня воды, а релюшка не включалась. Строки с 69.

 

#include <iarduino_RTC.h>                                   // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
    iarduino_RTC time(RTC_DS3231);                          // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C
    #include <LiquidCrystal.h>                                                           //
    #define DIODE_DROP  0.7 
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    int relay = 5; // Определение пина для реле включения насоса полива
    int relay2 = 6; // Определение пина для реле включения насоса перекачки воды в основной бак
    String RT = "50";
    String RT2 = "50";
    //String RT3 = "50";
    int RT3 = "50";
    String TimeOn = "12:00:00";
    String TimeOff = "12:02:00";
    String TimeOn2 = "22:00:00";
    String TimeOff2 = "22:02:00";
    String TimeOff3 = "00:00:05";
    const uint8_t L1 = 2;
                                                     
void setup(){   
    pinMode(L1, INPUT_PULLUP);   
    pinMode(relay, OUTPUT);
    pinMode(relay2, OUTPUT);
    digitalWrite(relay, LOW);                                                        //
    digitalWrite(relay2, LOW);
    delay(300);                                             // Ждем готовности модуля отвечать на запросы
    Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
    time.begin();                                           // Инициируем работу с модулем.
    lcd.begin(16, 2);
    lcd.print("Current time:");

}                                                           //
void loop()
{                                               
  if(millis()%1000>=0)
{                                                            // Если прошла 1 секунда.
      lcd.setCursor(0, 1);
      lcd.print(time.gettime("d-m H:i:sA"));                 // Выводим время.
}  
    
RT = time.gettime("H:i:s");
RT2 = time.gettime("H:i:s");
    
  if (RT == TimeOn)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT == TimeOff)
{
  digitalWrite(relay, LOW);
} 
if (RT2 == TimeOn2)
    {
     digitalWrite(relay, HIGH);
    }

  if (RT2 == TimeOff2)
{
  digitalWrite(relay, LOW);
} 

if (!digitalRead(L1)){
  digitalWrite(relay2, HIGH);
}
else(digitalWrite(relay2, LOW));
}


/*if (!digitalRead(L1)){
  digitalWrite(relay2, HIGH);
  RT3 = millis();
}
if (millis()-RT3 > 20000){
  digitalWrite(relay2, LOW);
}
}
*/

/*if (!digitalRead(L1)){
  digitalWrite(relay2, HIGH);
  RT3 = time.gettime("H:i:s");
}

if ((RT3 + TimeOff3) >= time.gettime("H:i:s")){
  digitalWrite(relay2, LOW);

}
//Serial.println(time.gettime("H:i:s"));
//Serial.println(RT3+TimeOff3);
//Serial.println(RT3);
//Serial.println(TimeOff3);
//else 
  //digitalWrite(relay2, LOW);
//RT3 = time.gettime("H:i:s");

//if (RT3 + TimeOff3 > time.gettime("H:i:s"));
  //digitalWrite(relay2, LOW);
*/

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Рабочая программа, можно собрать на столе и проверить.

// Arduino 1.8.8.

#define pumpPin 6
#define waterSensorPin 2 //при отсутствии воды замыкается на GND
#define pump_ON digitalWrite(pumpPin, HIGH)
#define pump_OFF digitalWrite(pumpPin, LOW)
#define noWater digitalRead(waterSensorPin) == LOW

unsigned long timeON;
unsigned long workTime = 120000; // 2 минуты
boolean flag = true;

void setup()
{
	pinMode(waterSensorPin, INPUT_PULLUP);
	pinMode(pumpPin, OUTPUT);
	pump_OFF;
	Serial.begin(115200);
}                                                           //

void loop()
{
	if (noWater && flag)
		{
			pump_ON;
			timeON = millis();
			flag = false;
		}
	if (millis() - timeON > workTime)
		{
			pump_OFF;
			flag = true;
		}
}

 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее так получше.Так как во втором if нет проверки на флаг

// Arduino 1.8.8.

#define pumpPin 6
#define waterSensorPin 2 //при отсутствии воды замыкается на GND
#define pump_ON digitalWrite(pumpPin, HIGH)
#define pump_OFF digitalWrite(pumpPin, LOW)
#define noWater digitalRead(waterSensorPin) == LOW

unsigned long timeON;
unsigned long workTime = 120000; // 2 минуты
boolean flag = true;

void setup()
{
  pinMode(waterSensorPin, INPUT_PULLUP);
  pinMode(pumpPin, OUTPUT);
  pump_OFF;
  Serial.begin(115200);
}                                                           //

void loop() {
  if (flag)
    if (noWater) {
      pump_ON;
      timeON = millis();
      flag = false;
    };
  else if (millis() - timeON > workTime)
  {
    pump_OFF;
    flag = true;
  };
}

А еще лучше через автомат Пуха.

#define pumpPin 6
#define waterSensorPin 2 //при отсутствии воды замыкается на GND
unsigned long timeON;
boolean flag = true;
const unsigned long workTime = 120000; // 2 минуты
void set(boolean f) {
  flag = f;
  timeON = millis();
  if (f) {
    digitalWrite(pumpPin, HIGH);
  }
  else {
    digitalWrite(pumpPin, LOW);
  }
}

void setup() {
  pinMode(waterSensorPin, INPUT_PULLUP);
  pinMode(pumpPin, OUTPUT);
  set(false);
}                                                           //

void loop() {
  switch (flag) {
    case true:
      if (!digitalRead(waterSensorPin))set(true);
      break;
    default:
      if (millis() - timeON > workTime)
        set(false);
  }
}

 

SLKH
Offline
Зарегистрирован: 17.08.2015

qwone пишет:

во втором if нет проверки на флаг

не нужна там эта проверка.
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

SLKH пишет:
не нужна там эта проверка.

Экономия ресурса работы процессора. Конечно. Если там задача одна, то на этом экономить не стоит. Но если много...

SLKH
Offline
Зарегистрирован: 17.08.2015

qwone пишет:

SLKH пишет:
не нужна там эта проверка.

Экономия ресурса работы процессора. Конечно. Если там задача одна, то на этом экономить не стоит. Но если много...

В первые 2 минуты после запуска программы, возможно, процессор отработает несколько лишних команд. Какой ресурс процессора израсходуется? насколько хватит запасов?

sadman41
Offline
Зарегистрирован: 19.10.2016

Ардуина протрется - это ладно. Перелива не боитесь?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

SLKH пишет:
В первые 2 минуты после запуска программы, возможно, процессор отработает несколько лишних команд. Какой ресурс процессора израсходуется? насколько хватит запасов?

А Вы попробуйде открыть в браузере до фига станиц. Или на компе загрузить кучу программ. Вроде проц не стерся, а лагать начнет непадецки. Вот это и есть ресурс процессора. Если он расчитан на выполнения миллиона операций в секунду, то два милиона в секунду ему не подтянуть. Так что экономить желательно не только память , но и операции в секунду. При расширении проекта они пригодятся.

SamFer
Offline
Зарегистрирован: 22.04.2019

Господа SLKH и qwone, спасибо Вам огромнейшее за помощь! На днях доеду до гаража и загружу Ваши коды и потом отпишусь.

 

sadman41, поясните, пожалуйста, что Вы имели ввиду?

sadman41
Offline
Зарегистрирован: 19.10.2016

Я вижу, что в последних вариантах насос включается по датчику, но выключается по интервалу. А это потенциальная проблема.

SamFer
Offline
Зарегистрирован: 22.04.2019

Так я писал выше, что это нужно для того, чтобы насос не срабатывал по нескольку раз после откачки воды, так как там у меня стоит поплавок (геркон) и когда попалвок опускается насос отключается, но так как он китайский и не стабильный (плавает какое-то время), насос включается и выключается еще несколько раз. Именно эта часть кода управляет не насосом полива, а насосом перекачки воды от "отсойного" бака в основной. Поэтому там никакого перелива и не будет.

SLKH
Offline
Зарегистрирован: 17.08.2015

sadman41 пишет:

Я вижу, что в последних вариантах насос включается по датчику, но выключается по интервалу. А это потенциальная проблема.

#27 - прямая перекладка ТЗ на нечеловеческий язык: "Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз."

sadman41
Offline
Зарегистрирован: 19.10.2016

Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )

SLKH
Offline
Зарегистрирован: 17.08.2015

qwone пишет:

SLKH пишет:
В первые 2 минуты после запуска программы, возможно, процессор отработает несколько лишних команд. Какой ресурс процессора израсходуется? насколько хватит запасов?

А Вы попробуйде открыть в браузере до фига станиц. Или на компе загрузить кучу программ. Вроде проц не стерся, а лагать начнет непадецки. Вот это и есть ресурс процессора. Если он расчитан на выполнения миллиона операций в секунду, то два милиона в секунду ему не подтянуть. Так что экономить желательно не только память , но и операции в секунду. При расширении проекта они пригодятся.

Во-первых, на хера эта демагогия про браузеры? "Зачем нам весь этот тюнинг в саратовском зоопарке?"

Во-вторых, вызовы функции set() при каждом проходе loop() сотрут ардуину гораздо больше, чем мой вариант.

В-третьих, автоматный код вообще нерабочий. 

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Подскажите, пожалуйста, что означает "сотрут Ардуино"? Имеется ввиду, что у такой код быстро вырабатывает ресурс микроконтроллера?

SLKH
Offline
Зарегистрирован: 17.08.2015

sadman41 пишет:

Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )

Если хозяин точно знает, что через 2 минуты работы насоса уровень заведомо будет ещё далеко от края бочки - не страшно.

SamFer
Offline
Зарегистрирован: 22.04.2019

Так почему от края бочки?)

Для общего понимания распишу полный цикл:

Есть стеллаж из 5 полок на котором я выращиваю различную травушку-муравушку. На каждой полке стоит по 4 поддона с посевами. Над каждым поддоном есть форсунка, которая распрыскивает воду (поливает всходы). Вода к форсункам подается из основного бака и этим поливом управляется первая реле, которая включается по расписанию 2 раза в сутки по 2-3 минуты. Далее, у каждого поддона есть дренажные отверстия через которые излишки воды стекают на стеллаж и самотеком по системе труб стекает в бак, в котором отстаивается (это нужно потому что выращиваю на земле и мне надо, чтобы вода немного отстоялась перед тем как вернуть ее в основной бак). В баке в котором вода отстаивается стоит насос, который отдалет от дна (чтобы не захватывать грязь) и в этом баке стоит поплавок. Поплавок стоит у края этого отстоечного бака. Как только срабатывает поплавок - включается насос. Но когда поплавок падает, то получается, что насос выкачал ровно столько, сколько требуется, чтобы поплавок упал. И получается, что поплавок плавает на поверхности и иногда провоцирует включаение насоса на пару секунд (так как дренаж работает и капелька за капелькой стекает в отстоечный бак). А там помимо уровня поплавка еще есть 5 литров воды, которую можно откачать, на это и требуется дополнительные две минуты. Вот для этого я и затеял всю эту котовасию. Наверное сейчас понятно написал. )))

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, если объем конечный, то пусть качает по времени, конечно.

SLKH
Offline
Зарегистрирован: 17.08.2015

SamFer пишет:

Подскажите, пожалуйста, что означает "сотрут Ардуино"? Имеется ввиду, что у такой код быстро вырабатывает ресурс микроконтроллера?

Дык... речь про это:

 if (millis() - timeON > workTime)
30         {
31             pump_OFF;
32             flag = true;
33         }

Первые 2 минуты после запуска (если за это время не сработает датчик) процессор бесполезно отработает команды в строках 31 и 32, которые ничего не меняют - ни уровня на пине, ни состояния переменной. Это никому не мешает, кроме qwone: он считает, что следует добавить ещё одну проверку ради экономии ресурсов процессора, т.к. при открытии в браузере до фига страниц он (браузер) начинает тормозить.

как-то так...

Ничего там не сотрется, ты всё-то всерьёз не принимай.

SLKH
Offline
Зарегистрирован: 17.08.2015

SamFer пишет:

Так почему от края бочки?)

Не знаю, мне так представилось: что-то вроде расходного танка.

Цитата:
Наверное сейчас понятно написал. )))
я ещё меньше понял, но это значения не имеет. Я писал для задачи "при срабатывании датчика насос должен включиться и тупо отработать 2 минуты, не обращая внимания ни на какие дребезги/переключения поплавка".

SamFer
Offline
Зарегистрирован: 22.04.2019

Не, это как раз не расширительный бачок, а наоборот - бак в котором скапливается вода уже после полива растений (излишки воды стекают со стеллажей, чтобы предотвратить перелив). В этом баке вода отстаивается и уже потом при наполнении перекачивается в основной бак. Такой круговорот воды. Тем самым я экономлю воду. 

 

 

SamFer
Offline
Зарегистрирован: 22.04.2019

Вот такая "чудо" система.

Много компромисов, так как это эксперимент и все делаю в гаража в ограниченном пространстве. :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sadman41 пишет:

Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )

Мне кажется, хотели сказать про гистерезис. Но не сумели...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Конечно много компромисов. Если воды много, то будет банально гонять по кругу.2 минуты качаем- проверяем наличие воды-воды много и датчик говорить ОК - качаем 2 минуты.  Или воды очень мало. - ждем до упора пока "дождь не пойдет", так как воды в системе мало.

nik182
Offline
Зарегистрирован: 04.05.2015

Это стандартное поведение многих датчиков, покачаться при резком изменении измеряемых параметров. Решения разные в этом случае. Можно как дребезг клавиш устранять например. Мне нравится вариант с накоплением сигнала датчика. Если датчик в состоянии сработал, то плюсуем единицу к переменной, нет - вычитаем. Если накапливаемое значение превысило порог отключаем насос. Это решение имеет несколько плюсов. Не чувствительность к помехам. Включение рядом точила не приводит к ложному срабатыванию. Время долива можно регулировать поргом отключения.