// Подключаем необходимые библиотеки
#include <TimerOne.h>
// Массив для быстрого отображения нужных цифр на семисегментнике
// Формат: abcdefg
const byte digits[] = {
B01000000, // 0
B01111001, // 1
B00100100, // 2
B00110000, // 3
B00011001, // 4
B00010010, // 5
B00000010, // 6
B01111000, // 7
B00000000, // 8
B00010000 // 9
};
// Пин-код для кнопок и светодиодов
const int btnStart = A2; // кнопка начала отсчета
const int btnStop = A3; // кнопка остановки отсчета
const int btnMode = A4; // кнопка переключения режима
const int ledIndicator = A5; // светодиод-индикатор режима
// Выводы семисегментников
const int unitsDisplay[] = {2, 3, 4, 5, 6, 7, 8}; // Единицы секунд
const int tensDisplay[] = {9, 10, 11, 12, 13, A0, A1}; // Десятки секунд
// Текущее время в секундах
int seconds = 0;
// Режим счета (true - прямой, false - обратный)
bool directMode = true;
// Признак начала отсчета
bool countStarted = false;
// Временные метки
unsigned long previousMillis = 0;
unsigned long interval = 1000; // Интервал обновления (1 секунда)
// Период обновления дисплея
void timerUpdate() {
Timer1.detachInterrupt(); // отключаем таймер, пока обновляем
// Получаем единицы и десятки секунд
int unitSec = seconds % 10;
int tenSec = seconds / 10;
// Обновляем оба семисегментника
for (int i = 0; i < 7; i++) {
digitalWrite(unitsDisplay[i],bitRead(digits[unitSec],i));
digitalWrite(tensDisplay[i], bitRead(digits[tenSec],i));
}
Timer1.attachInterrupt(timerUpdate); // вновь подключаем таймер
}
void setup() {
// Конфигурируем пины дисплеев
for (int i = 0; i < 7; i++) {
pinMode(unitsDisplay[i], OUTPUT);
pinMode(tensDisplay[i], OUTPUT);
}
// Настраиваем кнопки и светодиод
pinMode(btnStart,INPUT_PULLUP);
pinMode(btnStop, INPUT_PULLUP);
pinMode(btnMode, INPUT_PULLUP);
pinMode(ledIndicator, OUTPUT);
// Настраиваем внутренний таймер Arduino для периодического обновления дисплея
Timer1.initialize(interval);
Timer1.attachInterrupt(timerUpdate);
// Готовимся начать отсчет
countStarted = false;
seconds = 0;
directMode = true;
digitalWrite(ledIndicator,LOW); // светодиод погашен
}
void loop() {
// Обрабатываем события кнопок
if (digitalRead(btnStart) == HIGH) {
countStarted = true;
}
if (digitalRead(btnStop) == HIGH) {
countStarted = false;
}
if (digitalRead(btnMode) == HIGH) {
directMode = !directMode; // меняем режим счета
digitalWrite(ledIndicator, directMode ? LOW : HIGH); // индикация режима
}
// Обновляем время только если запущен отсчёт
if (countStarted) {
unsigned long currentMillis = millis();
if ((currentMillis - previousMillis) >= interval) {
previousMillis = currentMillis;
if (directMode) {
seconds++;
} else {
seconds--;
// Проверка конца обратного отсчета
if (seconds <= 0) {
countStarted = false;
seconds = 0;
}
}
}
}
}