Загрузка данных
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);
}
}