#define BUTTON A0
// Сегменты A B C D E F G DP
int pins[8] = {2, 3, 4, 5, 6, 7, 8, 9};
// Цифры для ИНВЕРТИРОВАННОГО индикатора
// 0 = сегмент включен, 1 = выключен
byte numbers[10] = {
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// Разряды индикатора
int pinDigits[4] = {10, 11, 12, 13};
// Секундомер
int seconds = 0;
int minutes = 0;
unsigned long millis1 = 0;
// Режим:
// false = остановлен
// true = работает
bool mode = false;
// Кнопка
bool curButton = LOW;
bool prevButton = LOW;
void setup() {
pinMode(BUTTON, INPUT);
// Сегменты
for (int i = 0; i < 8; i++) {
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], HIGH);
}
// Разряды
for (int i = 0; i < 4; i++) {
pinMode(pinDigits[i], OUTPUT);
digitalWrite(pinDigits[i], HIGH);
}
}
void loop() {
// -------------------------
// КНОПКА
// -------------------------
curButton = debounce(prevButton);
if (prevButton == LOW && curButton == HIGH) {
mode = !mode;
// Запуск
if (mode) {
millis1 = millis();
}
}
prevButton = curButton;
// -------------------------
// СЕКУНДОМЕР
// -------------------------
if (mode) {
unsigned long currentMillis = millis();
if (currentMillis - millis1 >= 1000) {
// Сохраняем остаток времени,
// чтобы секундомер не накапливал ошибку
millis1 += 1000;
seconds++;
// 60 секунд = 1 минута
if (seconds >= 60) {
seconds = 0;
minutes++;
// После 99:59 начинаем сначала
if (minutes >= 100) {
minutes = 0;
}
}
}
}
// -------------------------
// МУЛЬТИПЛЕКСИРОВАНИЕ
// -------------------------
for (int i = 0; i < 4; i++) {
// Сначала выключаем все разряды
for (int j = 0; j < 4; j++) {
digitalWrite(pinDigits[j], HIGH);
}
int digitValue;
// Получаем нужную цифру
switch (i) {
// Правая цифра секунд
case 0:
digitValue = seconds % 10;
break;
// Левая цифра секунд
case 1:
digitValue = seconds / 10;
break;
// Правая цифра минут
case 2:
digitValue = minutes % 10;
break;
// Левая цифра минут
case 3:
digitValue = minutes / 10;
break;
}
showNumber(digitValue, i);
// Включаем текущий разряд
digitalWrite(pinDigits[i], LOW);
delay(2);
}
}
// -------------------------
// ВЫВОД ЦИФРЫ
// -------------------------
void showNumber(int num, int dig) {
for (int i = 0; i < 8; i++) {
bool segment = bitRead(numbers[num], i);
digitalWrite(pins[i], segment);
}
// Точка между MM и SS
// У нас DP = pins[7]
//
// Инвертированная логика:
// LOW = включено
if (dig == 2) {
digitalWrite(pins[7], LOW);
}
}
// -------------------------
// АНТИДРЕБЕЗГ КНОПКИ
// -------------------------
bool debounce(bool last) {
bool current = digitalRead(BUTTON);
if (last != current) {
delay(5);
current = digitalRead(BUTTON);
}
return current;
}