const byte SEG_PIN[3] = {15, 2, 16};
byte Data[3] = {0, 0, 0};
const byte dataPin = 21;
const byte latchPin = 22;
const byte clockPin = 23;
const byte LEDs[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};
int countdownValue = 0;
bool startCount = false;
unsigned long lastCountTime = 0; // exact 1 second
unsigned long lastMuxMicros = 0; // 1 ms multiplex
byte muxDigit = 0;
// --------------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
for (byte i = 0; i < 3; i++)
pinMode(SEG_PIN[i], OUTPUT);
Serial.println("Enter number (0-999) to start countdown:");
}
// --------------------------------------------------------------------
void loop() {
// ---------------- READ SERIAL INPUT ----------------
if (Serial.available()) {
String s = Serial.readStringUntil('\n');
s.trim();
int n = s.toInt();
if (n >= 0 && n <= 999) {
countdownValue = n;
startCount = true;
lastCountTime = millis(); // reset timer baseline
Serial.print("Countdown: ");
Serial.println(countdownValue);
}
}
// ---------------- 100% EXACT 1-SECOND COUNTDOWN ----------------
if (startCount) {
unsigned long now = millis();
if (now - lastCountTime >= 1000) {
lastCountTime += 1000; // drift-free correction
if (countdownValue > 0) countdownValue--;
else {
startCount = false;
Serial.println("Finished.");
}
}
}
// ---------------- ALWAYS REFRESH DISPLAY ----------------
refreshDisplay(countdownValue);
}
// --------------------------------------------------------------------
void refreshDisplay(int number) {
Data[0] = number % 10;
Data[1] = (number / 10) % 10;
Data[2] = (number / 100) % 10;
// Switch digit every 1000 microseconds (1 ms)
if (micros() - lastMuxMicros >= 1000) {
lastMuxMicros += 1000;
// turn off all digits
digitalWrite(SEG_PIN[0], HIGH);
digitalWrite(SEG_PIN[1], HIGH);
digitalWrite(SEG_PIN[2], HIGH);
// output segment data
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LEDs[Data[muxDigit]]);
digitalWrite(latchPin, HIGH);
// enable digit (common anode → LOW)
digitalWrite(SEG_PIN[muxDigit], LOW);
// next digit
muxDigit++;
if (muxDigit > 2) muxDigit = 0;
}
}