#include <IRremote.h>
int receiverPin = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11
const byte BUZZER_PIN = 12; // Active buzzer
int latch = 9; //74HC595 pin 9 STCP
int clock = 10; //74HC595 pin 10 SHCP
int data = 8; //74HC595 pin 8 DS
unsigned char table[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00 };
// 4 digit select pins (active LOW for common anode, HIGH for common cathode)
int digitPins[4] = { 7, 6, 5, 4 };
// --- IR Codes (Copied from Elegoo Code) ---
const int IR_0 = 104; // Code for button 0
const int IR_1 = 48; // Code for button 1
const int IR_2 = 24; // Code for button 2
const int IR_3 = 122; // Code for button 3
const int IR_4 = 16; // Code for button 4
const int IR_5 = 56; // Code for button 5
const int IR_6 = 90; // Code for button 6
const int IR_7 = 66; // Code for button 7
const int IR_8 = 74; // Code for button 8
const int IR_9 = 82; // Code for button 9
// For start/stop and reset if you want to use any other key then just replace the below code with the key you want to use.
const int IR_POWER = 162; // Start / Stop
const int IR_RESET = 194; // Reset
// --- Timer State ---
enum State { IDLE,
RUNNING,
FINISHED };
State state = IDLE;
unsigned int timerValue = 0; // supports up to 9999
unsigned long lastSecond = 0;
unsigned long lastDisplay = 0;
int digits[4] = { 0, 0, 0, 0 }; // individual digits
// ---------------- DISPLAY FUNCTIONS ----------------
void showDigit(byte digit, byte pos) {
// Turn all digits OFF
for (int i = 0; i < 4; i++) digitalWrite(digitPins[i], HIGH);
// Send segment data
digitalWrite(latch, LOW);
shiftOut(data, clock, MSBFIRST, table[digit]);
digitalWrite(latch, HIGH);
// Turn this digit ON
digitalWrite(digitPins[pos], LOW); // active LOW
delayMicroseconds(1000); // short hold time
digitalWrite(digitPins[pos], HIGH);
}
void updateDigits(unsigned int value) {
digits[0] = value / 1000;
digits[1] = (value / 100) % 10;
digits[2] = (value / 10) % 10;
digits[3] = value % 10;
}
void refreshDisplay() {
for (int i = 0; i < 4; i++) {
showDigit(digits[i], i);
}
}
// ---------------- IR HANDLER ----------------
void handleIR() { // Function to handl IR input
// int code = receiver.decodedIRData.command;
int code = IrReceiver.decodedIRData.command;
Serial.print("Received Button Code:");
Serial.println(code);
// Check if user press a button from 1-9 then set that as delay and set the state as IDLE
if (code == IR_0) timerValue = timerValue * 10 + 0;
else if (code == IR_1) timerValue = timerValue * 10 + 1;
else if (code == IR_2) timerValue = timerValue * 10 + 2;
else if (code == IR_3) timerValue = timerValue * 10 + 3;
else if (code == IR_4) timerValue = timerValue * 10 + 4;
else if (code == IR_5) timerValue = timerValue * 10 + 5;
else if (code == IR_6) timerValue = timerValue * 10 + 6;
else if (code == IR_7) timerValue = timerValue * 10 + 7;
else if (code == IR_8) timerValue = timerValue * 10 + 8;
else if (code == IR_9) timerValue = timerValue * 10 + 9;
else if (code == IR_POWER) { // Check for Power button to pause/start the couting
if (state == IDLE && timerValue > 0) state = RUNNING;
else if (state == RUNNING) state = IDLE;
} else if (code == IR_RESET) {
timerValue = 0;
state = IDLE;
digitalWrite(BUZZER_PIN, LOW);
}
if (timerValue > 9999) timerValue = 9999; // limit to 4 digits
updateDigits(timerValue);
}
// ---------------- SETUP / LOOP ----------------
void setup() {
pinMode(latch, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(data, OUTPUT);
// Buzzer
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
for (int i = 0; i < 4; i++) {
pinMode(digitPins[i], OUTPUT);
digitalWrite(digitPins[i], HIGH);
}
IrReceiver.begin(receiverPin, ENABLE_LED_FEEDBACK);
updateDigits(timerValue);
}
void loop() {
// Handle IR input
if (IrReceiver.decode()) {
handleIR();
IrReceiver.resume();
}
// Countdown logic
if (state == RUNNING && millis() - lastSecond >= 1000) {
lastSecond = millis();
if (timerValue > 0) {
timerValue--;
updateDigits(timerValue);
}
if (timerValue == 0) {
state = FINISHED;
digitalWrite(BUZZER_PIN, HIGH);
delay(500);
digitalWrite(BUZZER_PIN, LOW);
timerValue = 0;
state = IDLE;
}
}
// Refresh display quickly
refreshDisplay();
}