Загрузка данных
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 longPressHandled = false;
// Переменные секундомера
unsigned long stopwatchMillis = 0;
unsigned long stopwatchStart = 0;
bool stopwatchRunning = false;
// Переменные таймера (установим старт по умолчанию, например, 1 минута = 60000 мс)
unsigned long timerTotalMillis = 60000;
unsigned long timerRemaining = 60000;
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 {
runTimer();
}
}
// Функция обработки нажатий кнопки (короткое — старт/пауза, длинное (>1 сек) — смена режима)
void handleButton() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading == LOW && lastButtonState == HIGH) {
// Кнопку только что нажали
buttonPressTime = millis();
longPressHandled = false;
}
else if (reading == LOW && lastButtonState == LOW) {
// Кнопка удерживается
if (!longPressHandled && (millis() - buttonPressTime > 1000)) {
// Прошло больше 1 секунды — ДЛИННОЕ нажатие (смена режима)
currentMode = !currentMode; // Переключение 0 <-> 1
longPressHandled = true;
// Сброс параметров при смене режима
if (currentMode == 0) {
stopwatchRunning = false;
stopwatchMillis = 0;
} else {
timerRunning = false;
timerRemaining = timerTotalMillis;
}
}
}
else if (reading == HIGH && lastButtonState == LOW) {
// Кнопку отпустили
if (!longPressHandled) {
// Это было КОРОТКОЕ нажатие (старт / пауза)
if (currentMode == 0) {
if (!stopwatchRunning) {
stopwatchStart = millis() - stopwatchMillis;
stopwatchRunning = true;
} else {
stopwatchRunning = false;
}
} else {
if (!timerRunning) {
if (timerRemaining == 0) timerRemaining = timerTotalMillis;
timerStart = millis();
timerRunning = true;
} else {
timerRunning = false;
}
}
}
}
}
lastButtonState = reading;
}
// --- РЕЖИМ 0: Секундомер ---
void runStopwatch() {
unsigned long currentMillis = millis();
if (stopwatchRunning) {
stopwatchMillis = currentMillis - stopwatchStart;
}
int totalSeconds = stopwatchMillis / 1000;
int minutes = (totalSeconds / 60) % 100;
int seconds = totalSeconds % 60;
int digits[4] = {
minutes / 10,
minutes % 10,
seconds / 10,
seconds % 10
};
displayDigits(digits);
}
// --- РЕЖИМ 1: Таймер ---
void runTimer() {
if (timerRunning) {
unsigned long elapsed = millis() - timerStart;
if (elapsed >= timerRemaining) {
timerRemaining = 0;
timerRunning = false; // Таймер дошел до нуля
} else {
timerRemaining = timerRemaining - elapsed;
timerStart = millis();
}
}
int totalSeconds = timerRemaining / 1000;
int minutes = (totalSeconds / 60) % 100;
int seconds = totalSeconds % 60;
int digits[4] = {
minutes / 10,
minutes % 10,
seconds / 10,
seconds % 10
};
displayDigits(digits);
}
// Функция динамической индикации 4 цифр
void displayDigits(int digits[]) {
for (int d = 0; d < 4; d++) {
digitalWrite(digitPins[d], HIGH); // Выключаем предыдущий разряд
byte mask = charMasks[digits[d] & 7]; // Ограничиваем индекс от 0 до 9
for (int s = 0; s < 8; s++) {
bool bitVal = bitRead(mask, 7 - s);
digitalWrite(segPins[s], bitVal);
}
digitalWrite(digitPins[d], LOW); // Включаем текущий разряд
delay(4); // Время свечения разряда для мультиплексирования
}
}