#include <Arduino.h>
// Define pins for LEDs
const int led1Pin = 2;
const int led2Pin = 3;
// Define pins for the shift register driving the 7-segment display
const int dsPin = 8; // serial data input
const int shcpPin = 9; // shift register clock pin
const int stcpPin = 10; // storage register (latch) clock pin
// Timing intervals in milliseconds
const unsigned long ledInterval = 2000; // 2 seconds for LED blink
const unsigned long countInterval = 4000; // 4 seconds for countdown update
// Variables to hold the previous event times
unsigned long previousLedMillis = 0;
unsigned long previousCountMillis = 0;
// Keeps track of which LED should be on next (true means led1, false means led2)
bool ledToggle = true;
// We are using a common anode 7-seg display. In a common anode display a segment lights
// when its pin is LOW. Thus we use active LOW patterns.
// The following digitPatterns are standard patterns for a common anode 7-seg with segments order:
// bit0: A, bit1: B, bit2: C, bit3: D, bit4: E, bit5: F, bit6: G, bit7: DP (we keep DP off).
// Patterns taken from many common examples:
// 0 -> 0xC0, 1 -> 0xF9, 2 -> 0xA4, 3 -> 0xB0, 4 -> 0x99,
// 5 -> 0x92, 6 -> 0x82, 7 -> 0xF8, 8 -> 0x80, 9 -> 0x90
byte digitPatterns[10] = {
0xC0, // 0: A B C D E F on, G off, DP off
0xF9, // 1: B C on
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// The current number to display on the 7-seg countdown
int currentDigit = 9;
void setup() {
// Initialize LED pins as outputs
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
// Initialize shift register pins as outputs
pinMode(dsPin, OUTPUT);
pinMode(shcpPin, OUTPUT);
pinMode(stcpPin, OUTPUT);
// Set initial states:
// - LED off
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
// Set initial display to 9
updateDisplay(digitPatterns[currentDigit]);
}
void loop() {
unsigned long currentMillis = millis();
// LED blinking every 2 seconds (alternate between led1 and led2)
if (currentMillis - previousLedMillis >= ledInterval) {
previousLedMillis = currentMillis;
if (ledToggle) {
digitalWrite(led1Pin, HIGH); // turn led1 ON
digitalWrite(led2Pin, LOW); // turn led2 OFF
} else {
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, HIGH);
}
ledToggle = !ledToggle;
}
// 7-segment countdown update every 4 seconds
if (currentMillis - previousCountMillis >= countInterval) {
previousCountMillis = currentMillis;
// Decrement the displayed digit; if 0 then restart at 9.
currentDigit = (currentDigit == 0) ? 9 : currentDigit - 1;
// Update the display with the new digit's pattern by shifting out the byte.
updateDisplay(digitPatterns[currentDigit]);
}
}
// Function to update the 7-segment display through the shift register
// by shifting out a byte representing the segments (active LOW).
void updateDisplay(byte segPattern) {
// Begin by setting latch low
digitalWrite(stcpPin, LOW);
// Use Arduino's shiftOut: by default, it shifts out MSB first.
// Our connections assume that Q0 gets bit0 (segment A) etc.
shiftOut(dsPin, shcpPin, MSBFIRST, segPattern);
// Latch the output: setting stcpPin high copies the data to the outputs.
digitalWrite(stcpPin, HIGH);
}