Сильно не пинайте, давно не развлекался и уже всё забыл. Управляю люком авто в двух направлениях. сам люк двигается. Но встал в тупик на элементарном. 
вырезал основное:
#define BUTTON1F 2
#define BUTTON1R 4
#define BUTTON_LONG_PRESS_TIME 800 //время длинного нажатия кнопки
#define STABILB 20 // время стабилизации дребезга контактов кнопок
bool isRun1 = false; // статус - мотор в движении
uint32_t testTime; // эмуляция мотора
//физическое состояние кнопки
enum ButtonResult {
	buttonNotPress,     //если кнопка не нажата
	button_shortPress,  //код короткого нажатия
	button_longPress    //код длинного нажатия
};
struct ButtonConfiguration {
	//состояние кнопки
	enum ButtonResult curent;
  //отпускание кнопки
  bool depressed;
  //блокировка состояния
  bool lock;
	//номер входа, к которому подключена кнопка
	uint8_t pin;
	//для измерения длительности нажатия
	uint32_t pressingTime;
};
//--------------------------------------------------
//для хранения параметров кнопки
struct ButtonConfiguration button1F = {
  .curent = buttonNotPress,
  .depressed = false,
  .lock = false,
  .pin = BUTTON1F,
  .pressingTime = 0
};
struct ButtonConfiguration button1R = {
  .curent = buttonNotPress,
  .depressed = false,
  .lock = false,
  .pin = BUTTON1R,
  .pressingTime = 0
};
void setup() {
	// входы кнопок
	pinMode(BUTTON1F, INPUT_PULLUP);
	pinMode(BUTTON1R, INPUT_PULLUP);
	//отладка
	Serial.begin(9600);
}
void ButtonCheck(struct ButtonConfiguration &button) {
	bool btnState = !digitalRead(button.pin); // читаем состояние пина и переворачиваем
	//если кнопка нажата
	if (btnState && button.curent == buttonNotPress && millis() - button.pressingTime > STABILB)
	{
		button.curent = button_shortPress;
		button.pressingTime = millis();
	}
	//если кнопка не нажата
	if (!btnState && button.curent != buttonNotPress && millis() - button.pressingTime > STABILB)
	{
		button.curent = buttonNotPress;
		button.pressingTime = millis();
	}
	// если нажата долго
	if (btnState && button.curent == button_shortPress && millis() - button.pressingTime > BUTTON_LONG_PRESS_TIME)
	{
		button.curent = button_longPress;
		//button->pressingTime = millis();
	}
  if(isRun1)
  {
    if ((button.depressed == false) && (button.curent == buttonNotPress))
    {
      Serial.print("test\tRun=");
      Serial.print(isRun1);
      Serial.print("\tbuttoncurent=");
      Serial.print(button.curent);
      Serial.print("\t1R=");
      Serial.print(button1R.curent);
      Serial.print("\t1F=");
      Serial.print(button1F.curent);
      Serial.print("\tdepressed=");
      Serial.print(button.depressed);
      Serial.print("\tb=");
      Serial.println(!digitalRead(button.pin));
      button.depressed = true;
    }
  }
}
void loop() {
	// читаем состояние кнопок
	ButtonCheck(button1F);
	ButtonCheck(button1R);
  if (button1F.curent == button_shortPress) 
  {
    if(!isRun1) Serial.println("run_front");
    isRun1 = true;
    testTime = millis();
  }
	else if (button1R.curent == button_shortPress) 
  {
    if(!isRun1) Serial.println("run_rear");
    isRun1 = true;
    testTime = millis();
  }
  if (isRun1 && millis() - testTime > 5000)
	{
    Serial.println("run_stop");
		isRun1 = false;
    button1R.depressed = false;
    button1F.depressed = false;		
	}
}
 
выхлоп от сюда
18:20:22.195 -> run_rear
18:20:22.195 -> test Run=1 buttoncurent=0 1R=1 1F=0 depressed=0 b=0
18:20:23.093 -> test Run=1 buttoncurent=0 1R=0 1F=0 depressed=0 b=0
18:20:28.113 -> run_stop
18:20:32.154 -> run_front
18:20:32.154 -> test Run=1 buttoncurent=0 1R=0 1F=1 depressed=0 b=0
18:20:32.828 -> test Run=1 buttoncurent=0 1R=0 1F=0 depressed=0 b=0
18:20:37.842 -> run_stop
 
видно, что кнопки отрабатывают верно. Нужен статус отпущенной кнопки во время движения. в связи чем пытаюсь реализовать со строки 75. И не понимаю что происходит:
почему попадаю туда два раза( при нажатии и отпускании)? 
2)почему всегда возврат 0 в строке 82? 
 
             
            
               
               
               
            
            
           
          
            
            
              
Первый раз Вы попадаете туда при нажатии в контексте “другой” (не нажатой) кнопки, а второй раз при отпускании в контексте “своей” кнопки. Я добавил кнопкам имена и поставил вывод имён, сами посмотрите (я заменил Ваши табуляции пробелами, на моём мониторе с табуляциями напряг).
Потому что при нажатии Вы печатаете это добро в контексте “другой” не нажатой кнопки, а при отпускании - в контексте своей, но уже отпущенной, т.е. когда там уже восстановилось в “нот пресс”.
Код с именами кнопок 
#define BUTTON1F 2
#define BUTTON1R 4
#define BUTTON_LONG_PRESS_TIME 800 //время длинного нажатия кнопки
#define STABILB 20 // время стабилизации дребезга контактов кнопок
bool isRun1 = false; // статус - мотор в движении
uint32_t testTime; // эмуляция мотора
//физическое состояние кнопки
enum ButtonResult {
	buttonNotPress,     //если кнопка не нажата
	button_shortPress,  //код короткого нажатия
	button_longPress    //код длинного нажатия
};
struct ButtonConfiguration {
	const char * name;
	//состояние кнопки
	enum ButtonResult curent;
  //отпускание кнопки
  bool depressed;
  //блокировка состояния
  bool lock;
	//номер входа, к которому подключена кнопка
	uint8_t pin;
	//для измерения длительности нажатия
	uint32_t pressingTime;
};
//--------------------------------------------------
//для хранения параметров кнопки
struct ButtonConfiguration button1F = {
	.name = "BTN_F",
  .curent = buttonNotPress,
  .depressed = false,
  .lock = false,
  .pin = BUTTON1F,
  .pressingTime = 0
};
struct ButtonConfiguration button1R = {
	.name = "BTN_R",
  .curent = buttonNotPress,
  .depressed = false,
  .lock = false,
  .pin = BUTTON1R,
  .pressingTime = 0
};
void setup() {
	// входы кнопок
	pinMode(BUTTON1F, INPUT_PULLUP);
	pinMode(BUTTON1R, INPUT_PULLUP);
	//отладка
	Serial.begin(9600);
}
void ButtonCheck(struct ButtonConfiguration &button) {
	bool btnState = !digitalRead(button.pin); // читаем состояние пина и переворачиваем
	//если кнопка нажата
	if (btnState && button.curent == buttonNotPress && millis() - button.pressingTime > STABILB)
	{
		button.curent = button_shortPress;
		button.pressingTime = millis();
	}
	//если кнопка не нажата
	if (!btnState && button.curent != buttonNotPress && millis() - button.pressingTime > STABILB)
	{
		button.curent = buttonNotPress;
		button.pressingTime = millis();
	}
	// если нажата долго
	if (btnState && button.curent == button_shortPress && millis() - button.pressingTime > BUTTON_LONG_PRESS_TIME)
	{
		button.curent = button_longPress;
		//button->pressingTime = millis();
	}
  if(isRun1)
  {
    if ((button.depressed == false) && (button.curent == buttonNotPress))
    {
		Serial.print(button.name);
		Serial.print(": ");
      Serial.print("test Run=");
      Serial.print(isRun1);
      Serial.print(" buttoncurent=");
      Serial.print(button.curent);
      Serial.print(" 1R=");
      Serial.print(button1R.curent);
      Serial.print(" 1F=");
      Serial.print(button1F.curent);
      Serial.print(" depressed=");
      Serial.print(button.depressed);
      Serial.print(" b=");
      Serial.println(!digitalRead(button.pin));
      button.depressed = true;
    }
  }
}
void loop() {
	// читаем состояние кнопок
	ButtonCheck(button1F);
	ButtonCheck(button1R);
  if (button1F.curent == button_shortPress) 
  {
    if(!isRun1) Serial.println("run_front");
    isRun1 = true;
    testTime = millis();
  }
	else if (button1R.curent == button_shortPress) 
  {
    if(!isRun1) Serial.println("run_rear");
    isRun1 = true;
    testTime = millis();
  }
  if (isRun1 && millis() - testTime > 5000)
	{
    Serial.println("run_stop");
		isRun1 = false;
    button1R.depressed = false;
    button1F.depressed = false;		
	}
}
 
 
             
            
               
               
               
            
            
           
          
            
            
              Спасибо большое, осознал.
             
            
               
               
               
            
            
           
          
            
            
              Идеально работающие кнопки я делал в таймерном прерывании, причем дребезг убирался только при замыкании, тк у разомкнутой дребезга быть не может. Первое замыкание - сработка; ждем отпускания с таймером. Тогда кнопки быстрые.
             
            
               
               
               
            
            
           
          
            
              
                nik182  
                
               
              
                  
                    17.Октябрь.2024 21:05:24
                   
                   
              5 
               
             
            
              
А какая разница? Замыкание размыкание подпружиненного контакта с механической точки зрения процессы похожие. И дребезг похож.
             
            
               
               
               
            
            
           
          
            
            
              Когда кнопка отпущена всегда 1. Когда нажата контакт может пропадать. В этом разница.
             
            
               
               
               
            
            
           
          
            
              
                SAB  
                
               
              
                  
                    22.Январь.2025 01:56:14
                   
                   
              7 
               
             
            
              
При размыкании копки дребезг такой же, а может ещё и хуже чем при замыкании в плане возникновения обратной эдс, если коммутируется индуктивная нагрузка. Следуя вашей логике в замкнутом состоянии всегда 0, что совершенно не связано с дребезгом.
             
            
               
               
               
            
            
           
          
            
            
              
Моя логика проверена годами, « Первое замыкание - сработка; ждем отпускания с таймером.» я же написал.
То есть: мы НЕ ждем надежного замыкания, сразу выдаем чо ЕстьНажатие.
А вот потом ждем размыкания: Если замкнуто - сброс таймера отжатия, ждем дальше.