#define button1B 3  // пин кнопки button1

boolean button1S;   // храним состояния кнопок (S - State)
boolean button1F;   // флажки кнопок (F - Flag)
boolean button1R;   // флажки кнопок на отпускание (R - Release)
boolean button1P;   // флажки кнопок на нажатие (P - Press)
boolean button1H;   // флажки кнопок на удержание (многократный вызов) (H - Hold)
boolean button1HO;  // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once)
boolean button1D;   // флажки кнопок на двойное нажатие (D - Double)
boolean button1DP;  // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)

#define DOUBLE_TIMER 500   // время (мс), отведённое на второе нажатие
#define HOLD 2000           // время (мс), после которого кнопка считается зажатой
#define DEBOUNCE 50        // (мс), антидребезг
unsigned long button1_timer; // таймер последнего нажатия кнопки
unsigned long button1_double; // таймер двойного нажатия кнопки
unsigned long _millis;

void setup() {
  Serial.begin(9600);
  pinMode(button1B, INPUT_PULLUP);
}

void loop() {
  button1S = !digitalRead(button1B);
  _millis = millis();
  uint8_t btn = buttons(); //отработка кнопок
  if (3 == btn) {
    Serial.println("pressed");
  }
  if (5 == btn) {
    Serial.println("double");
  }
  if (7 == btn) {
    Serial.println("hold once");
  }
}

uint8_t buttons(void)
{
   uint8_t bt1=0; // Будем возвращать результат в этой переменной
   
  //  if (BitIsClear(BUT1_PIN,BUT1)) button1S=1;
  //  else button1S=0; // Состояние кнопки
   
   // нажали (с антидребезгом)
   if (button1S && !button1F && _millis - button1_timer > DEBOUNCE) 
   {
      button1F = 1; // Установим флаг кнопки
      button1HO = 1; // флаг на удержание
      button1_timer = _millis; // таймер последнего нажатия кнопки
      bt1=1;
   }
   // если отпустили до hold, считать отпущенной
   if (!button1S && button1F && !button1R && !button1DP && _millis - button1_timer < HOLD) 
   {
      button1R = 1; // флаг на отпускание
      button1F = 0; //флаг кнопки
      bt1=2;
      button1_double = _millis; // Таймер двойного нажатия кнопки
   }
   
   // если отпустили и прошло больше double_timer, считать 1 нажатием
   if (button1R && !button1DP && _millis - button1_double > DOUBLE_TIMER) 
   {
      button1R = 0;
      button1P = 1;
      bt1=3;
   }
   
   // если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 разa
   if (button1F && !button1DP && button1R && _millis - button1_double < DOUBLE_TIMER) 
   {
      button1F = 0;
      button1R = 0;
      button1DP = 1;
      bt1=4;
   }
   
   // если была нажата 2 разa и отпущена, считать что была нажата 2 раза
   if (button1DP && _millis - button1_timer < HOLD) 
   {
      button1DP = 0;
      button1D = 1;
      button1_timer = _millis;
      bt1=5;
   }
   
   // Если удерживается более hold, то считать удержанием
   if (button1F && !button1D && !button1H && millis - button1_timer > HOLD) 
   {
      button1H = 1;
      bt1=6;
   }
   
   // Если отпущена после hold, то считать, что была удержана
   if (!button1S && button1F && millis - button1_timer > HOLD) 
   {
      button1F = 0;
      button1H = 0;
      button1_timer = millis;
      bt1=7;
   }
   
   // отработка режимов (опускание флага обязательно!)
  if (button1P) button1P = 0;   
  if (button1D) button1D = 0;    
  if (button1H && button1HO) button1HO = 0;
  if (button1H) button1H = 0;
  
  return bt1;  
}