/*
Two digit Countdown Timer
Written for common cathode
In a real circuit the digit pins should have transistor drivers.
*/
const int START_TIME = 15; // defaults to 15 second countdown
const int BTN_PIN = 13;
const int BUZZ_PIN = 2;
const int DIG_PINS[] = {3, 4};
const int SEG_PINS[] = {5, 6, 12, 9, 10, 7, 8, 11};
const bool DIGITS[][8] = { // numeral lookup table
// A B C D E F G DP
{1, 1, 1, 1, 1, 1, 0, 0}, // 0
{0, 1, 1, 0, 0, 0, 0, 0}, // 1
{1, 1, 0, 1, 1, 0, 1, 0}, // 2
{1, 1, 1, 1, 0, 0, 1, 0}, // 3
{0, 1, 1, 0, 0, 1, 1, 0}, // 4
{1, 0, 1, 1, 0, 1, 1, 0}, // 5
{1, 0, 1, 1, 1, 1, 1, 0}, // 6
{1, 1, 1, 0, 0, 0, 0, 0}, // 7
{1, 1, 1, 1, 1, 1, 1, 0}, // 8
{1, 1, 1, 1, 0, 1, 1, 0}, // 9
{0, 0, 0, 0, 0, 0, 0, 0} // blank
};
const unsigned long ONE_SEC = 1000;
const unsigned long DEBOUNCE_TIME = 20;
bool checkButton() {
static bool lastState = HIGH;
static unsigned long lastTime = 0;
bool isPressed = false;
bool currentState = digitalRead(BTN_PIN);
unsigned long now = millis();
if (currentState != lastState && now - lastTime >= DEBOUNCE_TIME) {
if (!currentState) {
//Serial.println("Button pressed!");
isPressed = true;
} else {
//Serial.println("Button released!");
}
lastTime = now;
lastState = currentState;
}
return isPressed;
}
void writeDigit(int digit, int value) {
for (int seg = 0; seg < 8; seg++) {
digitalWrite(SEG_PINS[seg], DIGITS[value][seg]); // !DIGITS for common anode
}
digitalWrite(DIG_PINS[digit], LOW); // invert for common anode
digitalWrite(DIG_PINS[digit], HIGH); // invert for common anode
}
void updateDisplay(int value) {
if (value < 10) {
writeDigit(0, 10); // writes the blank value in tens digit
} else {
writeDigit(0, value / 10);
}
writeDigit(1, value % 10);
}
void setup() {
Serial.begin(115200);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(BUZZ_PIN, OUTPUT);
for (int digit = 0; digit < 2; digit++) {
pinMode(DIG_PINS[digit], OUTPUT);
}
for (int segment = 0; segment < 8; segment++) {
pinMode(SEG_PINS[segment], OUTPUT);
}
}
void loop() {
static bool isDone = true;
static bool isRunning = false;
static int count = START_TIME;
static unsigned long prevTime = 0;
// check button
bool wasPressed = checkButton();
if (wasPressed) {
if (isDone) { // start / restart counter
isDone = false;
isRunning = true;
Serial.println("Running");
count = START_TIME;
} else { // pause / unpause counter
isRunning = !isRunning;
Serial.println(isRunning ? "Running" : "Paused");
}
prevTime = millis();
}
// every ONE_SEC if running
if (millis() - prevTime >= ONE_SEC && isRunning) {
count--;
if (count <= 0) { // time's up
isDone = true;
isRunning = false;
Serial.println("Time's up!");
tone(BUZZ_PIN, 440, 1000);
}
prevTime = millis();
}
// refresh the display frequently
updateDisplay(count);
}
Start /
Pause