Управление одной кнопкой тремя реле

Спойлер
/*
   Абзавём входные данные, а именно пины для КНОПКИ и ТРЁХ РЕЛЕ
*/

#define     BUTTON_PIN        12    // Кнопка
#define     RELE1_PIN         2     // Реле 1
#define     RELE2_PIN         3     // Реле 2
#define     RELE3_PIN         4     // Реле 3
#define     TIME_BOUNCE       70    // 70мс время "фильтрации" дребезга контактов
#define     LONG_PRESS_TIME   2000  // 2 секунды время удержания кнопки
#define     SHORT_TIME        3000

enum BUTTON_RESULT : uint8_t {
  NOT_PRESS,
  PRESS,
  LONG_PRESS
};

BUTTON_RESULT current_button_res = NOT_PRESS;

const uint8_t     RELE_PINS[] = {RELE1_PIN, RELE2_PIN, RELE3_PIN}, r_count = sizeof(RELE_PINS) / sizeof(RELE_PINS[0]);
      uint8_t     cur_rele = 0;

void releOff () {
  for (uint8_t i = 0; i < r_count; i++) {
    digitalWrite(RELE_PINS[i], LOW);
  }
}

void setup() {
  // Теперь настроим пины
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")

  for (uint8_t i = 0; i < r_count; i++) {
    pinMode(RELE_PINS[i], OUTPUT);         // А пины реле на выход
  }
    // И выключим их все
  releOff();
}

void loop() {

  uint8_t button_state = digitalRead(BUTTON_PIN); // Ну во, вот тут мы её и "уконтропупили".
  uint32_t _millis = millis();                    // Запомним текущее значение миллисекунд
  static uint32_t timeHoldBegin;                  // Время начала удержания кнопки
  static uint32_t timeHold;                       // Длительность удержания кнопки

  // А дальше нам нужно узнать - нажимал кто на кнопку? А если нажимал - то как долго удерживал?
  if (!button_state) {                            // Если кнопка нажата
    timeHold =  _millis - timeHoldBegin;          // Считаем длительность удержания
  } else {                                        // Еслди кнопку отпустили
    timeHoldBegin = _millis;                      // Сбрасываем
    timeHold = 0;
    current_button_res = NOT_PRESS;
  }

  if (timeHold > TIME_BOUNCE && timeHold < LONG_PRESS_TIME) { // Если время удержание в интервале между временем подавления дребезга и удержанием
    current_button_res = PRESS;                               // То нужно как-то "зарегистрировать нажатие"
  }

  if (timeHold > LONG_PRESS_TIME) {                           // Если время удержание больше времени удержаниея (2 сек)
    current_button_res = LONG_PRESS;                          // То нужно как-то "зарегистрировать долгое удержание"
  }

  // Состояние кнопки узнали.
  // А дальше пошла "жара" (то есть обработка нажатий)

  switch (current_button_res) {
    case PRESS:                                               // Если кликнули один раз
      releOff();
      if (cur_rele < (r_count - 1)) {
        digitalWrite(RELE_PINS[cur_rele], HIGH);
      }
      cur_rele = (cur_rele++) % r_count;
      break;
    case LONG_PRESS:                                          // Если кномпу долго удерживали
      releOff();
      digitalWrite(RELE_PINS[r_count - 1], HIGH);
      delay(SHORT_TIME);
      digitalWrite(RELE_PINS[r_count - 1], LOW);
      cur_rele = 0;
      break;
    case NOT_PRESS:                                           // Если кнопку не нажимали
      // Ничего не делаем. Это просто для наглядности
      break;
    default:
      break;
  }
}

Скетч использует 1396 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 23 байт (1%) динамической памяти, оставляя 2025 байт для локальных переменных. Максимум: 2048 байт.