millis в условии

Bandito
Offline
Зарегистрирован: 01.07.2020

Всем привет, проблема такая - хочу сделать на скважину датчик сухого хода т.е. когда вода кончается в скважине (а такое бывает) не спалить насос а отключить его на заданный период.
Алгоритм - если кнопка с фиксацией нажата, запустить таймер отсчитать 15 сек (для того что бы вода поднялась по трубе до датчика), считать состояние датчика, если true то качаем дальше, если false то вырубаем насос и ждём 30мин, после опять запускаем насос ждём 15сек меняем состояние датчика и так по циклу.
Ка ни пытался не получается, подскажите пожалуйста

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Показывайте, как пытались, и что именно в попытках работает не так.

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

Обычно для решения таких задач используется конечный автомат.

Bandito
Offline
Зарегистрирован: 01.07.2020
bool woter_level;       // грубо говоря поплавок в баке (true когда уровень воды упал)
#define nasos 13       // насос
bool potok;            // датчик потока (true когда поток есть)


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(woter_level, INPUT);
  pinMode(nasos, OUTPUT);
  enable_nasos = true;

} 

void loop() {
  
  woter_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (woter_level == true && enable_nasos == true){
  t1 = millis() + 1000;                                     // t1 - момент когда вода уже должна поднятся по трубе и можно считать состояние датчика
  digitalWrite(nasos, HIGH);
}
else {
  digitalWrite(nasos, LOW);
}

if(millis() == t1 && potok == true) {
    enable_nasos == true;
  }
  else if(millis() == t1 && potok == false){              // прошло время для подьема воды, потока нет, насос работает в сухую
    enable_nasos == false;                                // запрещаем насосу включатся
    t2 = millis() + 5000;                                 // t2 - время ожидания возобновления воды в скважине
  }
  
  if(millis() == t2) {                                    // скважина отдохнула
    enable_nasos == true;                                 // включаем насос
  }
 
}

 

Bandito
Offline
Зарегистрирован: 01.07.2020

тайминги уменьшил для проверки, работает это так поплавок true, поток false, светодиод (насос) загорется и не тухнет через секунду хотя должен

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

А строки 1, 11 и 19 ничего не навевают?

И эта программа не компилируется по определению. Вру, может, но бредово.

Bandito
Offline
Зарегистрирован: 01.07.2020

Для наглядности из кода выкидывал лишние функции, и напартачил но сути это не меняет он ведет себя так же

bool woter_level;       // грубо говоря поплавок в баке (true когда уровень воды упал)
#define nasos 13       // насос
bool potok;            // датчик потока (true когда поток есть)


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(3, INPUT);
  pinMode(nasos, OUTPUT);
  enable_nasos = true;

} 

void loop() {
  
  woter_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (woter_level == true && enable_nasos == true){
  t1 = millis() + 1000;                                     // t1 - момент когда вода уже должна поднятся по трубе и можно считать состояние датчика
  digitalWrite(nasos, HIGH);
}
else {
  digitalWrite(nasos, LOW);
}

if(millis() == t1 && potok == true) {
    enable_nasos == true;
  }
  else if(millis() == t1 && potok == false){              // прошло время для подьема воды, потока нет, насос работает в сухую
    enable_nasos == false;                                // запрещаем насосу включатся
    t2 = millis() + 5000;                                 // t2 - время ожидания возобновления воды в скважине
  }
  
  if(millis() == t2) {                                    // скважина отдохнула
    enable_nasos == true;                                 // включаем насос
  }
 
}

 

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

В 30 строке замени условия на "больше"

Bandito
Offline
Зарегистрирован: 01.07.2020

заменил, ничего не поменялось

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

еще в 33 и 38

Bandito
Offline
Зарегистрирован: 01.07.2020

пробовал, не помогает(

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

А теперь о главном! Конструкция с миллис ВСЕГДА должна выглядеть как "настоящее_время-предыдущее_время> интервал". Другие конструкции ведут к херне. Читайте на форуме "Великое переполнение миллис"

И еще - у Вас нет момента наполнения бака. Хорошо - в баке появилась вода, а потом что?

Bandito
Offline
Зарегистрирован: 01.07.2020

Спасибо, буду знать, но в данном случае ничего не изменилось

Bandito
Offline
Зарегистрирован: 01.07.2020
bool woter_level;       // грубо говоря поплавок в баке (true когда уровень воды упал)
#define nasos 13       // насос
bool potok;            // датчик потока (true когда поток есть)


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(3, INPUT);
  pinMode(nasos, OUTPUT);
  enable_nasos = true;

} 

void loop() {
  
  woter_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (woter_level == true && enable_nasos == true){
  t1 = millis();                                     // t1 - момент когда вода уже должна поднятся по трубе и можно считать состояние датчика
  digitalWrite(nasos, HIGH);
}
else {
  digitalWrite(nasos, LOW);
}

if(millis() - t1  > 1000 && potok == true) {
    enable_nasos == true;
  }
  else if(millis() - t1  > 1000 && potok == false){              // прошло время для подьема воды, потока нет, насос работает в сухую
    enable_nasos == false;                                // запрещаем насосу включатся
    t2 = millis();                                 // t2 - время ожидания возобновления воды в скважине
  }
  
  if(millis() - t2 > 5000) {                                    // скважина отдохнула
    enable_nasos == true;                                 // включаем насос
  }
 
}

 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Вы в каждом цикле обновляете пороговое время,

поэтому и не можете его достигнуть.

  if (woter_level == true && enable_nasos == true){
  t1 = millis() + 1000;                                     // t1 - момент когда вода

Bandito
Offline
Зарегистрирован: 01.07.2020

Я это уже понял, но не могу придумать как сделать по другому...

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Добавить третье && - если насос еще не включен.

Тогда засечь время и включить.

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

Bandito пишет:

Я это уже понял, но не могу придумать как сделать по другому...

А если уровень воды чуть поднялся и уже не тру, то что будет?

А где датчик наполнения бака?

Bandito
Offline
Зарегистрирован: 01.07.2020

mykaida пишет:

А если уровень воды чуть поднялся и уже не тру, то что будет?

А где датчик наполнения бака?

НА самом деле будет два датчика нижнего и верхнего уровня, код упрощен дабы не возникало лишних вопросов

Bandito
Offline
Зарегистрирован: 01.07.2020

Bruzzer пишет:

Добавить третье && - если насос еще не включен.

Тогда засечь время и включить.

тоже самое

bool woter_level;       // грубо говоря поплавок в баке (true когда уровень воды упал)
bool nasos;       // насос
bool potok;            // датчик потока (true когда поток есть)


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(3, INPUT);
  pinMode(13, OUTPUT);
  enable_nasos = true;
  nasos = false;
} 

void loop() {
  
  woter_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (woter_level == true && enable_nasos == true && nasos == false){
  t1 = millis();                                     // t1 - момент когда вода уже должна поднятся по трубе и можно считать состояние датчика
  nasos = true;
}
else {
  nasos = false;
}

if(millis() - t1  > 1000 && potok == true) {
    enable_nasos == true;
  }
  else if(millis() - t1  > 1000 && potok == false){              // прошло время для подьема воды, потока нет, насос работает в сухую
    enable_nasos == false;                                // запрещаем насосу включатся
    t2 = millis();                                 // t2 - время ожидания возобновления воды в скважине
  }
  
  if(millis() - t2 > 5000) {                                    // скважина отдохнула
    enable_nasos == true;                                 // включаем насос
  }
  if(nasos == true){
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
}

 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

По моему у вас путаница с nasos и  enable_nasos

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

31, 34, 39 - переведи?

Bandito
Offline
Зарегистрирован: 01.07.2020

SLKH пишет:

31, 34, 39 - переведи?

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

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Прям глаз режет "woter_level", "potok","nasos", "enable_nasos"...
Определись на каком языке пишешь.

water_lvl, flow_sensor ,pomp_on и тд

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Добавьте перед или после 34

nasos = false;

Добавление. БЫЛ НЕПРАВ. это не надо.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Kakmyc пишет:
Прям глаз режет "woter_level", "potok","nasos", "enable_nasos"... Определись на каком языке пишешь. water_lvl, flow_sensor ,pomp_on и тд

Это точно поможет ))) 

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Logik пишет:

Kakmyc пишет:
Прям глаз режет "woter_level", "potok","nasos", "enable_nasos"... Определись на каком языке пишешь. water_lvl, flow_sensor ,pomp_on и тд

Это точно поможет ))) 

 

Конечно.
Порядок должен быть как в коде, так и в названиях переменных.
Как вы яхту назовёте, так она и поплывет :-)

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

Bandito пишет:

SLKH пишет:

31, 34, 39 - переведи?

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

это не флаг. это что-то похожее на проверку на равенство, но без проверки.

Bandito
Offline
Зарегистрирован: 01.07.2020

ой, а я и не туда...  понял, исправил

Logik
Offline
Зарегистрирован: 05.08.2014

Kakmyc пишет:
Logik пишет:

Kakmyc пишет:
Прям глаз режет "woter_level", "potok","nasos", "enable_nasos"... Определись на каком языке пишешь. water_lvl, flow_sensor ,pomp_on и тд

Это точно поможет ))) 

 

Конечно. Порядок должен быть как в коде, так и в названиях переменных. Как вы яхту назовёте, так она и поплывет :-)

Так беспорядок у тя с глазами, займись лучше ими.

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

Без обид. Когда человек не шарит в алгоритме, не понимает код он цепляется к именам, орфографии и пробелам. Это считай закон. Зачем ты это делаешь? Хочешь помочь - найди ошибку, а придираться к мелочам - себя в дурном свете выставлять.

Bandito
Offline
Зарегистрирован: 01.07.2020

может я принципиально не правильно делаю, подскажите в какую сторону копать 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Мне woter_level тоже глаз резанул, но главное, что его значение не понятно без комментария

// грубо говоря поплавок в баке (true когда уровень воды упал)

Да и с комментарием не очень понятно - упал ниже верхнего ограничения или достиг нижнего ограничения.

Logik
Offline
Зарегистрирован: 05.08.2014

копай в отладку. Например мне не очень понятно что творится в условии стр.22-28. Поставь в стр.24 и 27 вывод в сириал. Проверь, ты так предполагал работу? И дальше проверяй сириалом в подозрительных местах.

Bandito
Offline
Зарегистрирован: 01.07.2020

проблема в первом if'е, я t1 присваиваю millis, каждый проходящий цикл, над этой проблемой думаю второй день и до сих пор не придумал как обойти ее

Logik
Offline
Зарегистрирован: 05.08.2014

не каждый. Через раз. Раз делаеш nasos = trueи устанавливаеш t1, а на следующем проходе делаешь nasos = false;. Не похоже чтоб так надо было.

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

Logik пишет:

Kakmyc пишет:
Logik пишет:

Kakmyc пишет:
Прям глаз режет "woter_level", "potok","nasos", "enable_nasos"... Определись на каком языке пишешь. water_lvl, flow_sensor ,pomp_on и тд

Это точно поможет ))) 

 

Конечно. Порядок должен быть как в коде, так и в названиях переменных. Как вы яхту назовёте, так она и поплывет :-)

Так беспорядок у тя с глазами, займись лучше ими.

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

сам по себе "nasos" вместо "pomp" (кстати, а почему не "pump"?) совсем не страшен. Гораздо хуже 

bool nasos;       // насос
bool enable_nasos;
enable_nasos = true;
nasos = false;
 
 
 

(см. #20, #31)
Не запутаться в этом достаточно тяжело.

Logik
Offline
Зарегистрирован: 05.08.2014

так чЁ? меняем "nasos" на "pump" и все заработает? ;)

Или еще что переименовать требуется? Действительно, так же проще чем багу искать. ))))  

Bandito
Offline
Зарегистрирован: 01.07.2020

есть прогресс! теперь работает все, но не без косяков - при поплавке - false, а потоке - true, включается насос

сначала подумал что это никак не помешает работе устройства, но потом вспомнил что датчик потока механический и он может залипнуть, так что нужно это решать

bool water_level;       // грубо говоря поплавок в баке (true когда уровень воды упал)
bool nasos;       // насос
bool potok;            // датчик потока (true когда поток есть)
int timer_zaderzhki = 5000;
int timer_otduha = 10000;


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(3, INPUT);
  pinMode(13, OUTPUT);
  enable_nasos = true;
  nasos = false;
} 

void loop() {
  
  water_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (water_level == true && enable_nasos == true && nasos == false){
  t1 = millis();                                     // t1 - момент когда вода уже должна поднятся по трубе и можно считать состояние датчика
  nasos = true;
}
  if (water_level == false) nasos = false;

if(millis() - t1  > timer_zaderzhki && potok == true){
    enable_nasos = true;
    nasos = true;
  }
  else if(millis() - t1  > timer_zaderzhki && potok == false && enable_nasos == true){              // прошло время для подьема воды, потока нет, насос работает в сухую
    enable_nasos = false;                                // запрещаем насосу включатся
    nasos = false;
    t2 = millis();                                 // t2 - время ожидания возобновления воды в скважине
  }
  
  if(millis() - t2 > timer_otduha) {                                    // скважина отдохнула
    enable_nasos = true;                                 // включаем насос
  }
  if(nasos == true){
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
}

 

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

Logik пишет:

так чЁ? меняем "nasos" на "pump" и все заработает? ;)

Или еще что переименовать требуется? Действительно, так же проще чем багу искать. ))))  

можно не менять, а вот узнать смысл загадочных булевых переменных не мешает. а nasos там,  или pump, pumpe, pompe, pompa и т.д. - неважно.

Logik
Offline
Зарегистрирован: 05.08.2014

Вот тут согласен. Смысл - все, буковки - херня, только чтоб найти где эта переменная заюзана. Ctrl+F одинаково nasos там,  или pump, pumpe, pompe.

Мне например куда больше не нравится конструкция if(millis() - t1  > timer_zaderzhki && potok == true){...} else if(millis() - t1  > timer_zaderzhki && potok == false && enable_nasos == true)...

 как ИМХО if(millis() - t1  > timer_zaderzhki ) {if(potok == true){...} else if( enable_nasos == true)...} облегчит понимание смысла в 100500 раз больше чем любое переименование.

Bruzzer
Offline
Зарегистрирован: 17.03.2020

На мой взгляд, по сравнению с #13 сейчас код стал более запутанным. Раньше насос включался - выключался только в одном блоке условий, а сейчас в нескольких, что и приводит к "но не без косяков - при поплавке - false, а потоке - true, включается насос".

Возможно имеет смысл доработать вариант #13 сделав вместо третьего условия - вложенное.

Примерно так

if (woter_level == true && enable_nasos == true){
  if (nasos == false) {
  	t1 = millis();                                     
	nasos = true;
  }
}
else {
  nasos = false;
}

Или полностью переделать структуру условий, сделав ее более понятной и предсказуемой

Например два больших блока

Если насос выключен - то какие действия

Если насос включен - то какие действия

Но все это - ИМХО.

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

Bruzzer пишет:

На мой взгляд, по сравнению с #13 сейчас код стал более запутанным. Раньше насос включался - выключался только в одном блоке условий, а сейчас в нескольких, что и приводит к "но не без косяков - при поплавке - false, а потоке - true, включается насос".

Возможно имеет смысл доработать вариант #13 сделав вместо третьего условия - вложенное.

Примерно так

if (woter_level == true && enable_nasos == true){
  if (nasos == false) {
  	t1 = millis();                                     
	nasos = true;
  }
}
else {
  nasos = false;
}

Или полностью переделать структуру условий, сделав ее более понятной и предсказуемой

Например два больших блока

Если насос выключен - то какие действия

Если насос включен - то какие действия

Но все это - ИМХО.

и написать эту структуру сначала на русском языке.

примерно так:

// если насос включен И датчик чего-то там равен нулю ....и т.д.

а потом под этой строкой писать всякие ифы с эльзами - уже вражескими буквами.

 

Bandito
Offline
Зарегистрирован: 01.07.2020

Отмучался))

bool water_level;           // грубо говоря поплавок в баке (true когда уровень воды упал)
bool nasos;                 // насос
bool potok;                 // датчик потока (true когда поток есть)
int timer_zaderzhki = 1000;
int timer_otduha = 1000;


uint32_t t1;           // мои городухи
uint32_t t2;
bool enable_nasos;

void setup(){
  pinMode(3, INPUT);
  pinMode(13, OUTPUT);
  enable_nasos = true;
  nasos = false;
} 

void loop() {
  
  water_level = digitalRead(3);
  potok = digitalRead(11);
  
  if (water_level == true && enable_nasos == true){
    if (nasos == false) {
      t1 = millis();                                    
      nasos = true;
  }
    if(millis() - t1  > timer_zaderzhki && potok == false){
      enable_nasos = false;
      t2 = millis();
  }
}
  else {
    nasos = false;
}

  if(millis() - t2 > timer_otduha) {
    enable_nasos = true;
  }
  if(nasos == true){
    digitalWrite(13, HIGH);
  }
  
  else {
    digitalWrite(13, LOW);
  }
}

 

Bandito
Offline
Зарегистрирован: 01.07.2020

Всем спасибо за советы!!!