Загрузка данных



const int segPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
const int digitPins[] = {5, 4, 3, 2};
const int buttonPin = A2; // Кнопка на пине A2 (второй вывод на GND)

// Массив цифр для индикатора (0-9)
const byte charMasks[] = {
  0b11111100, // 0
  0b01100000, // 1
  0b11011010, // 2
  0b11110010, // 3
  0b01100110, // 4
  0b10110110, // 5
  0b10111110, // 6
  0b11100000, // 7
  0b11111110, // 8
  0b11110110  // 9
};

// Режимы: 0 - Секундомер, 1 - Таймер
int currentMode = 0; 

// Переменные для обработки кнопки
bool lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
unsigned long buttonPressTime = 0;
bool longPressTriggered = false;

// Переменные секундомера
unsigned long stopwatchElapsed = 0; // Накопленное время в миллисекундах
unsigned long stopwatchStartMark = 0;
bool stopwatchRunning = false;

// Переменные таймера (старт по умолчанию: 1 минута = 60000 мс)
unsigned long timerTotalMillis = 60000; 
unsigned long timerRemaining = 60000;
unsigned long timerStartMark = 0;
bool timerRunning = false;

void setup() {
  for (int i = 0; i < 8; i++) {
    pinMode(segPins[i], OUTPUT);
  }
  
  for (int i = 0; i < 4; i++) {
    pinMode(digitPins[i], OUTPUT);
    digitalWrite(digitPins[i], HIGH);
  }

  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  handleButton();

  if (currentMode == 0) {
    runStopwatch();
  } else {
    runTimer();
  }
}

// Надежная обработка нажатий
void handleButton() {
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading == LOW && lastButtonState == HIGH) {
      // Кнопку только что нажали
      buttonPressTime = millis();
      longPressTriggered = false;
    } 
    else if (reading == LOW && lastButtonState == LOW) {
      // Кнопка удерживается — проверяем длинное нажатие (> 1 секунды)
      if (!longPressTriggered && (millis() - buttonPressTime > 1000)) {
        longPressTriggered = true;
        currentMode = !currentMode; // Смена режима (0 <-> 1)

        // Сброс при смене режима
        if (currentMode == 0) {
          stopwatchRunning = false;
          stopwatchElapsed = 0;
        } else {
          timerRunning = false;
          timerRemaining = timerTotalMillis;
        }
      }
    } 
    else if (reading == HIGH && lastButtonState == LOW) {
      // Кнопку отпустили
      if (!longPressTriggered) {
        // Это было короткое нажатие — Старт / Пауза
        if (currentMode == 0) {
          if (!stopwatchRunning) {
            stopwatchStartMark = millis();
            stopwatchRunning = true;
          } else {
            stopwatchElapsed += millis() - stopwatchStartMark;
            stopwatchRunning = false;
          }
        } else {
          if (!timerRunning) {
            if (timerRemaining == 0) timerRemaining = timerTotalMillis;
            timerStartMark = millis();
            timerRunning = true;
          } else {
            timerRemaining = timerRemaining - (millis() - timerStartMark);
            timerRunning = false;
          }
        }
      }
    }
  }
  lastButtonState = reading;
}

// Секундомер
void runStopwatch() {
  unsigned long currentMillis = stopwatchElapsed;
  if (stopwatchRunning) {
    currentMillis += (millis() - stopwatchStartMark);
  }

  int totalSeconds = currentMillis / 1000;
  int minutes = (totalSeconds / 60) % 100;
  int seconds = totalSeconds % 60;

  int digits[4] = {
    minutes / 10,
    minutes % 10,
    seconds / 10,
    seconds % 10
  };

  displayDigits(digits);
}

// Таймер
void runTimer() {
  unsigned long currentRemaining = timerRemaining;
  if (timerRunning) {
    unsigned long elapsed = millis() - timerStartMark;
    if (elapsed >= currentRemaining) {
      currentRemaining = 0;
      timerRunning = false;
      timerRemaining = 0;
    } else {
      currentRemaining -= elapsed;
    }
  }

  int totalSeconds = currentRemaining / 1000;
  int minutes = (totalSeconds / 60) % 100;
  int seconds = totalSeconds % 60;

  int digits[4] = {
    minutes / 10,
    minutes % 10,
    seconds / 10,
    seconds % 10
  };

  displayDigits(digits);
}

// Вывод на индикатор
void displayDigits(int digits[]) {
  for (int d = 0; d < 4; d++) {
    digitalWrite(digitPins[d], HIGH); // Выкл разряд
    
    byte mask = charMasks[digits[d] % 10];
    for (int s = 0; s < 8; s++) {
      bool bitVal = bitRead(mask, 7 - s);
      digitalWrite(segPins[s], bitVal);
    }

    digitalWrite(digitPins[d], LOW); // Вкл разряд
    delay(3); 
  }
}