Проверка выполнения условий

Проверил логика работает корректна.
С

поступил так-

// Глобальные переменные для состояния клапана, режима работы и времени последнего изменения состояния клапана
unsigned long valveChangeTime = 0;

// Функция для проверки аварийной сигнализации
void checkEmergency() {
  // Если состояние клапана не соответствует состоянию обратной связи и прошло больше 2 минут, то включаем аварийную сигнализацию
  if (valveState != digitalRead(FEEDBACK_PIN) && millis() - valveChangeTime > 120000) {  // Если состояние клапана не соответствует состоянию обратной связи и прошло больше 2 минут...
    valveChangeTime = millis();    
    for (;;){    
    digitalWrite(EMERGENCY_LED_PIN, HIGH);  // ... то включаем светодиод аварийного сигнала
    lcd.setCursor(0, 3);  // Устанавливаем курсор на начало четвертой строки
    lcd.print("EMERGENCY!!!");  // Выводим на LCD дисплей надпись "EMERGENCY!!!"
  } 
  } else {  // Если состояние клапана соответствует состоянию обратной связи или прошло меньше 2 минут...
    digitalWrite(EMERGENCY_LED_PIN, LOW);  // ... то выключаем светодиод аварийного сигнала
    lcd.setCursor(0, 3);  // Устанавливаем курсор на начало четвертой строки
    lcd.print("    ");  // Очищаем четвертую строку
  }
}

P/S Цикл для себя подключил для наглядности.
Но логика работает 2 мин., после как только дергаю BUTTON_MANUAL_PIN получаю аварию, понимаю, что достаточно незначительная ошибка, но понять не могу.

Похоже про то, как работать с миллис - вы или не читали совсем, или “недочитали”.
Запоминать начало отсчета надо не тут, а там где вы включает -выключаете кран.

И надеюсь, что бесконечный цикл for вставлен исключительно для отладки… потому что я не понял его смысла.

Не вынесла душа поэта…))

#define ALARM_LED_PIN 8
#define SENS_VALVE_PIN 9
#define DRIVE_VALVE_PIN 10

unsigned long valveChangeTime = 0;
bool alarm_pause_flg = false;
int valveState;

void setup() {
  Serial.begin(9600);
  delay(300);
  Serial.println("Proverka avariynoi systemi...");

  pinMode(ALARM_LED_PIN, OUTPUT);
  pinMode(DRIVE_VALVE_PIN, OUTPUT);
  pinMode(SENS_VALVE_PIN, INPUT_PULLUP);

  digitalWrite(ALARM_LED_PIN, LOW);
  digitalWrite(DRIVE_VALVE_PIN, HIGH);


}


void checkEmergency() {
  // Если состояние клапана не соответствует состоянию обратной связи //
  if (valveState != digitalRead(DRIVE_VALVE_PIN) && !alarm_pause_flg) {
    valveChangeTime = millis();//
    Serial.println("Nachalo otscheta");
    alarm_pause_flg = true;
  }
  if (millis() - valveChangeTime > 5000 && alarm_pause_flg) {
    Serial.println("Zavershenie otscheta");
    Serial.println("ALARM");
    digitalWrite(ALARM_LED_PIN, HIGH);
    alarm_pause_flg = false;
    valveChangeTime = 0;
    while (1);

  }
}

void loop() {

  valveState = digitalRead(SENS_VALVE_PIN);

  checkEmergency();
  delay(500);
}

P.S.

Здесь тоже проверьте, кнопка активна низким лог.уровнем

До этого я бы доходил очень долго и задал бы 100500 вопросов. Благодарю за помощь! В личку напишите ваш номер, отблагодарю “на пиво”.

Спасибо, не надо. В своё время норматив по пиву перевыполнил))

Это упрощённый пример. Возможно, Вам ещё надо дописать условие, если в течении времени проверки , значения датчика и ожидаемое состояние клапана, вдруг снова совпадут. Или ещё хуже - датчик изменит показания несколько раз

Это уже выше моих сил на данном этапе познания основ программирования… Чтобы избежать условий которые вы описали, применю костыль в виде увеличения дельты температур. Надеюсь, мы не доживем до того времени, когда уличная температура будет меняться со скоростью 2-3 градуса за 2 минуты)))))

возможно для обучения это было бы лучше…

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

@Дим-мычъ , надеюсь ты понимаешь, что я это пишу не в упрек тебе и твоему коду :slight_smile:

Поэтому мой топик в песочнице… Если пофлудить, то смотря на код @Дим-мычъ я вижу свои ошибки и учусь на них (в данном случаи на своих ошибках доходчивее)))), можно было бы конечно в целях обучения просто общими фразами направлять, до тех пор пока не “устал” бы учитель или обучаемый и топик бы распух до неприличия и не факт, что хватило бы терпения у обоих сторон дойти до “конца”))))) Но это моё мнение и оно индивидуально.

Можно и упрекнуть, если по делу, не растаю))
Даже полезно будет

Уж слишком упрощённый, дополнил немного, а то и правда mixxx не заметит

void checkEmergency() {
  // Если состояние клапана не соответствует состоянию обратной связи //
  if (valveState != digitalRead(DRIVE_VALVE_PIN) && !alarm_pause_flg) {
    valveChangeTime = millis();//начинаем отсчёт времени
    Serial.println("Nachalo otscheta");
    alarm_pause_flg = true;
  }
  if (millis() - valveChangeTime > 5000 && alarm_pause_flg) {//по истечении времени проверки
    Serial.println("Zavershenie otscheta");
    if(valveState != digitalRead(DRIVE_VALVE_PIN)){//проверяем датчик
    Serial.println("ALARM");
    digitalWrite(ALARM_LED_PIN, HIGH);
    while (1);
    }
    alarm_pause_flg = false;
    valveChangeTime = 0;
  }
}

М-да в стороне стою курю… Почти готовый коммерческий продукт получается))))) У народа сейчас достаточно много шаровых электрокранов в хозяйстве, если кто задумывается, а что будет если кран закиснет, то купит с обратной связью. Вместо датчика температуры ставь любой другой - давления, обьема, протечки и т.д. и вообще универсальное средство будет. Добавлю реле в разрыв питания элетроклапана, чтобы “авария” носила не только информационный характер, но и исполнительный для безопасности.