Почему цикл while делает два прохода по первому условию, а потом переходит ко второму

byte btn_flag = 1;
boolean btn_off = 1;
boolean reley_on;
boolean btn_on;
unsigned long last_press;
unsigned long wattering_time;


void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(A4, INPUT_PULLUP);
}

void loop() {
  btn_on = !digitalRead(A4);
  
  if(btn_on == 1){
    
    while (btn_flag){
      
      if(millis() - wattering_time > 2000){
        Serial.println(btn_flag);
        Serial.print("btn_on ..... ");Serial.println(btn_on);
        digitalWrite(2, HIGH);
        reley_on = 1;
        wattering_time = millis();
        btn_on = !digitalRead(A4);
      }
      if(reley_on == 1 && millis() - wattering_time > 2000){
        digitalWrite(2, LOW);
        reley_on = 0;
        wattering_time = millis(); 
        Serial.print("btn_on ..... ");Serial.println(btn_on);
        Serial.print("btn_off ..... ");Serial.println(btn_off);
        
      } 
      if(btn_on){
        break;
      }  
    }
  } 
}

Потому что на два таймера одна общая переменная wattering_time

btn_on = !digitalRead(A4);
убираю это из цикла while и все работает корректно, не не могу додуматься как мне выходить из цикла при повторном нажатии на кнопку

Опишите своими словами, как , по вашему, всё должно работать

Я нажимаю на кнопку —> включается реле на определенное время —> после истечения времени реле отключается на определенное время —> этот цикл продолжается пока я повторно не нажму кнопку

Не прописал в условии reley_on ==0

Код надо переписать, сейчас уже занят. Если смогу, отвечу позже

Большое спасибо за содействие

boolean cycle_counter = 1;                 // условие для цикла
boolean reley_flag;                        // флаг положения реле
boolean btn_flag;                          // флаг положения кнопки
byte reley = 2;                            // переменная для пина реле
byte button = 18;                          // переменная для пина кнопки
unsigned long wattering_time;              // переменная для хранения времени
unsigned long button_timer;                // переменная для хранения времени от дребезга


void setup() {
  Serial.begin(9600);
  pinMode(reley, OUTPUT);                  // инициализация пинов
  pinMode(button, INPUT_PULLUP);           //
}

void loop() {
  btn_flag = !digitalRead(button);          // считываю кнопку
  
  if(btn_flag == 1 && millis() - button_timer > 150){                         // если кнопка нажата перехожу к циклу 
    cycle_counter = 1;
    button_timer = millis();
    while (cycle_counter){                  // поочередно включает и отключает реле с заданным промежутком времени
      btn_flag = !digitalRead(button);      // снова считываю положение кнопки
      if(reley_flag == 0 && millis() - wattering_time > 2000){
        digitalWrite(2, HIGH);
        reley_flag = 1;
        wattering_time = millis();
        Serial.println("Реле в работе ");  
      }
      if(reley_flag == 1 && millis() - wattering_time > 2000){
        digitalWrite(2, LOW);
        reley_flag = 0;
        wattering_time = millis(); 
        Serial.println("Реле не работает");
      } 
      if(reley_flag == 0 && btn_flag == 1 && millis() - button_timer > 150){      // если повторно нажал на кнопку, останавливаем цикл
        cycle_counter = 0;                       // можно отключить только когда реле не в работе
        button_timer = millis();
      }
     
    } 
  }
}

переписал немного код.
теперь все функционирует как планировал.
Буду рад замечаниям и советам для дальнейшего улучшения кода

Цикл while тормозит реакцию на кнопку. Пока он не отработает, ничего изменить невозможно.

Вот набросал на скорую руку. Нажатие на кнопку действует немедленно(почти) останавливая/запуская цикл.

Спойлер
#define RelayPin 2
#define BtnPin 18
boolean btn_flag = 0; //нули для наглядности
boolean btn = 0;
boolean relay_on = 0;
boolean btn_on = 0;
boolean ON = false;
boolean OFF = false;
uint8_t btnStat = 0;
unsigned long last_millis = 0;
unsigned long wattering_time = 0;
unsigned long wattering_timeOFF = 0;

void setup() {
  Serial.begin(9600);
  pinMode(RelayPin, OUTPUT);
  pinMode(BtnPin, INPUT_PULLUP);//A4 это цифровой пин 18
}

void loop() {
  if(millis() - last_millis > 10)//опрос кнопки
  {
  last_millis = millis();
  btn = !digitalRead(BtnPin);
  if (btn && btnStat == 0)
  {
    btnStat = 1;
    btn_flag = true;
    relay_on = true;
    ON = true;
  } 
  if (!btn && btnStat == 1)
      btnStat = 2;
  if (btn && btnStat == 2)
  {
    btnStat = 3;
    btn_flag = false;
    relay_on = false;
    OFF = true;
  }     
  if (!btn && btnStat == 3)
      btnStat = 0;
  }    
  if (btn_flag)
  {
    if ((millis() - wattering_time > 1000) || ON) {//мигаем или вкл/выкл
      wattering_time = millis();
      ON = false;
      Serial.print("btn_flag  ");
      Serial.println(btn_flag);
      Serial.print("rele = "); Serial.println(relay_on);
      Serial.println();
      digitalWrite(RelayPin, relay_on);
      relay_on = !relay_on;
    }
  }
  else
  {
    if ((millis() - wattering_timeOFF > 1000) || OFF)
    {//этот таймер лишь для наглядности, для вывода в сериал
     wattering_timeOFF = millis(); 
     OFF = false;
    Serial.print("btn_flag  "); 
    Serial.println(btn_flag);
    digitalWrite(RelayPin, relay_on);
    Serial.print("rele = "); Serial.println(relay_on);
    Serial.println();
    }
  }
}
1 лайк