#include <SPI.h>

// Пины для первого регистра
const int clockPin1 = 10;
const int latchPin1 = 9;
const int dataPin1 = 8;

// Пины для второго регистра
const int clockPin2 = 7;
const int latchPin2 = 6;
const int dataPin2 = 5;

// Пины для третьего регистра
const int clockPin3 = 4;
const int latchPin3 = 3;
const int dataPin3 = 2;

const int buttonPin = 11;

unsigned long previousMillis = 0;
const long interval = 1000; // 1 секунда

bool running = false;
bool reset = false;
int seconds = 0;
int minutes = 0;

int buttonState = 0;
int lastButtonState = 0;

const byte digitToSegment[10] = {
  // от 0 до 9 (порядок a - g) - уточнено для 7-сегментных дисплеев с общим катодом
  B00111111, // 0
  B00000110, // 1
  B01011011, // 2
  B01001111, // 3
  B01100110, // 4
  B01101101, // 5
  B01111101, // 6
  B00000111, // 7
  B01111111, // 8
  B01101111  // 9
};

void setup() {
  pinMode(latchPin1, OUTPUT);
  pinMode(clockPin1, OUTPUT);
  pinMode(dataPin1, OUTPUT);

  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);

  pinMode(latchPin3, OUTPUT);
  pinMode(clockPin3, OUTPUT);
  pinMode(dataPin3, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);
  
  Serial.begin(9600);
}

void loop() {
  unsigned long currentMillis = millis();

  // Чтение состояния кнопки
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
    delay(50); // Антидребезг
    if (buttonState == LOW) {
      if (reset) {
        seconds = 0;
        minutes = 0;
        reset = false;
        running = false;
      } else {
        running = !running;
      }
    }
  }
  lastButtonState = buttonState;

  if (running && (currentMillis - previousMillis >= interval)) {
    previousMillis = currentMillis;
    seconds++;
    if (seconds >= 60) {
      seconds = 0;
      minutes++;
    }
  }
  
  if (buttonState == LOW && !running) {
    reset = true;
  }
  
  // Отображение времени
  displayTime(minutes, seconds);
}


void displayTime(int minutes, int seconds){
  int secondUnits = seconds % 10;
  int secondTens = (seconds / 10) % 10;
  int minuteUnits = minutes % 10;

  // Отправка данных на третий 7-сегментный дисплей (минуты)
  digitalWrite(latchPin3, LOW);
  shiftOut(dataPin3, clockPin3, MSBFIRST, digitToSegment[minuteUnits]);
  digitalWrite(latchPin3, HIGH);

  // Отправка данных на второй 7-сегментный дисплей (десятки секунд)
  digitalWrite(latchPin2, LOW);
  shiftOut(dataPin2, clockPin2, MSBFIRST, digitToSegment[secondTens]);
  digitalWrite(latchPin2, HIGH);

  // Отправка данных на первый 7-сегментный дисплей (единицы секунд)
  digitalWrite(latchPin1, LOW);
  shiftOut(dataPin1, clockPin1, MSBFIRST, digitToSegment[secondUnits]);
  digitalWrite(latchPin1, HIGH);
}
$abcdeabcde151015202530354045505560fghijfghij
74HC595
74HC595
74HC595