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


const int segPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
const int digitPins[] = {5, 4, 3, 2};
const int potPin = A0;
const int buttonPin = A2; // Кнопка на пине A2

// Массив символов из твоего исходного кода
const byte charMasks[] = {
  0b11111100, 0b01100000, 0b11011010, 0b11110010,
  0b01100110, 0b10110110, 0b10111110, 0b11100000,
  0b11111110, 0b11110110, 0b11101110, 0b00111110,
  0b10011100, 0b01111010, 0b10011110, 0b10001110,
  0b11110110, 0b00101110, 0b00001100, 0b01111000,
  0b10001110, 0b00011100, 0b11101100, 0b00101010,
  0b11111100, 0b11001110, 0b11100110, 0b00001010,
  0b10110110, 0b00011110, 0b01111100, 0b01111100,
  0b01111100, 0b01101110, 0b01110110, 0b11011010
};
const int totalChars = sizeof(charMasks);

// Переменные состояния
int currentMode = 0; // 0 - Секундомер, 1 - Таймер, 2 - Режим из твоего кода
bool buttonState = HIGH;
bool lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

// Переменные для секундомера
unsigned long stopwatchMillis = 0;
unsigned long stopwatchStart = 0;
bool stopwatchRunning = false;

// Переменные для таймера
unsigned long timerMillis = 60000; // Старт с 1 минуты (в миллисекундах)
unsigned long timerStart = 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); // Кнопка замыкает пин на GND
}

void loop() {
  handleButton(); // Проверка нажатия кнопки для смены режимов

  // Выполнение логики в зависимости от текущего режима
  if (currentMode == 0) {
    runStopwatch();
  } else if (currentMode == 1) {
    runTimer();
  } else if (currentMode == 2) {
    runOriginalMode();
  }
}

// Функция обработки нажатия кнопки
void handleButton() {
  int reading = digitalRead(buttonPin);

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

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading == LOW && buttonState == HIGH) { // Нажатие
      currentMode = (currentMode + 1) % 3; // Переключение режимов 0 -> 1 -> 2 -> 0
      
      // Сброс/инициализация при входе в режим
      if (currentMode == 0) {
        stopwatchRunning = false;
        stopwatchMillis = 0;
      } else if (currentMode == 1) {
        timerRunning = false;
        timerMillis = map(analogRead(potPin), 0, 1023, 10, 300) * 1000; // Время таймера от потенциометра
      }
    }
    buttonState = reading;
  }
  lastButtonState = reading;
}

// --- РЕЖИМ 0: Секундомер ---
void runStopwatch() {
  // Управление паузой/стартом по короткому нажатию кнопки (или можно сделать раздельно, здесь переключаем по клику)
  // Для простоты: пока в режиме секундомера, кнопка запускает/останавливает
  // (Здесь обработка клика упрощена для примера)
  
  unsigned long currentMillis = millis();
  if (stopwatchRunning) {
    stopwatchMillis = currentMillis - stopwatchStart;
  }

  int totalSeconds = stopwatchMillis / 1000;
  int minutes = totalSeconds / 60;
  int seconds = totalSeconds % 60;
  int hundreds = (stopwatchMillis % 1000) / 10; // Сотые доли

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

  displayDigits(digits, true); // Вывод с точкой на разряде минут для красоты
}

// --- РЕЖИМ 1: Таймер ---
void runTimer() {
  int potVal = analogRead(potPin);
  
  if (!timerRunning) {
    timerMillis = (long)potVal * 100; // Настройка времени таймера потенциометром в режиме паузы
  }

  int totalSeconds = timerMillis / 1000;
  int minutes = totalSeconds / 60;
  int seconds = totalSeconds % 60;

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

  displayDigits(digits, false);
}

// --- РЕЖИМ 2: Твой оригинальный код ---
void runOriginalMode() {
  for (int c = 0; c < totalChars; c++) {
    for (int i = 3; i >= 0; i--) {
      // Динамическая индикация внутри цикла твоего кода
      for (int d = 0; d < 4; d++) {
        digitalWrite(digitPins[d], HIGH);
      }
      digitalWrite(digitPins[i], LOW);
      
      for (int s = 0; s < 8; s++) {
        bool bitVal = bitRead(charMasks[c], 7 - s);
        digitalWrite(segPins[s], bitVal);
      }
      
      int potValue = analogRead(potPin);
      int delayTime = map(potValue, 0, 1023, 100, 3000);
      
      // Чтобы кнопка продолжала опрашиваться, заменяем долгий delay на цикл с проверкой
      unsigned long startWait = millis();
      while (millis() - startWait < delayTime) {
        handleButton();
        if (currentMode != 2) return; // Если нажали кнопку и сменили режим — выходим
      }
    }
  }
}

// Универсальная функция динамической индикации 4 цифр
void displayDigits(int digits[], bool showColon) {
  // Быстрое обновление для динамической индикации (мультиплексирования)
  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);
      // Если это второй разряд и нужен разделитель (двоеточие), можно задействовать точку (например, бит 0)
      digitalWrite(segPins[s], bitVal);
    }

    digitalWrite(digitPins[d], LOW); // Включаем нужный разряд
    delay(4); // Задержка для свечения разряда
  }
}