#include <Arduino.h>
// 74HC595
const byte DATA_PIN = 8; // SDI
const byte CLOCK_PIN = 7; // SFTCLK
const byte LATCH_PIN = 4; // LCHCLK
// Кнопки
const byte BTN_MUL = 2;
const byte BTN_RESET = 3;
// Начальное значение
const uint32_t START_VALUE = 138;
uint32_t value = START_VALUE;
// Предел для 4-разрядного индикатора
const uint32_t MAX_VALUE = 9999;
// Дребезг
const unsigned long DEBOUNCE_MS = 40;
struct ButtonState {
bool lastRead = HIGH;
bool stable = HIGH;
unsigned long lastChange = 0;
};
ButtonState mulBtn;
ButtonState resetBtn;
// Таблица сегментов для common anode
const byte SEG_CA[10] = {
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// Выбор разрядов
const byte DIGIT_SEL[4] = {
0x01,
0x02,
0x04,
0x08
};
byte digits[4] = {0, 0, 0, 0};
void send595(byte firstByte, byte secondByte) {
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, firstByte);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, secondByte);
digitalWrite(LATCH_PIN, HIGH);
}
void splitToDigits(uint16_t n) {
for (byte i = 0; i < 4; i++) {
digits[i] = n % 10;
n /= 10;
}
}
void refreshDisplay() {
uint16_t shown = (uint16_t)(value % 10000UL);
splitToDigits(shown);
for (byte pos = 0; pos < 4; pos++) {
byte seg = SEG_CA[digits[3 - pos]];
byte dig = DIGIT_SEL[pos];
send595(seg, dig);
delayMicroseconds(800);
}
}
bool buttonPressed(ButtonState &btn, byte pin) {
bool reading = digitalRead(pin);
if (reading != btn.lastRead) {
btn.lastChange = millis();
btn.lastRead = reading;
}
if (millis() - btn.lastChange > DEBOUNCE_MS) {
if (reading != btn.stable) {
btn.stable = reading;
if (btn.stable == LOW) return true;
}
}
return false;
}
void setup() {
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
pinMode(BTN_MUL, INPUT_PULLUP);
pinMode(BTN_RESET, INPUT_PULLUP);
digitalWrite(LATCH_PIN, HIGH);
}
void loop() {
refreshDisplay();
if (buttonPressed(mulBtn, BTN_MUL)) {
value *= 3;
if (value > MAX_VALUE) {
value = START_VALUE;
}
}
if (buttonPressed(resetBtn, BTN_RESET)) {
value = START_VALUE;
}
}