#include <LedControl.h> // Include LedControl library for MAX7219
// Define LED and button pins for 12 targets
const int numTargets = 12;
int ledPins[numTargets] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44}; // Updated LED pins
int buttonPins[numTargets] = {23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45}; // Updated button pins
int currentTarget = 0;
int score = 0;
unsigned long gameStartTime;
unsigned long gameDuration = 60000; // Game duration: 60 seconds
const int startButtonPin = 33; // Button to start the game (on pin 33)
const int startLedPin = 32; // LED to indicate the game is ready to start (on pin 32)
// MAX7219 Configuration: 4 displays (32x8 matrix, using 4 devices)
LedControl lc = LedControl(51, 52, 53, 4); // DIN=51, CLK=52, CS=53, four MAX7219 devices
void setup() {
// Initialize LED and button pins
for (int i = 0; i < numTargets; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP); // Use internal pull-up resistor
}
pinMode(startButtonPin, INPUT_PULLUP); // Button to start the game (pin 33)
pinMode(startLedPin, OUTPUT); // LED to indicate the game is ready (pin 32)
Serial.begin(9600); // Start serial communication
// Initialize MAX7219 displays (0 = score display, 1 = timer display)
for (int i = 0; i < 4; i++) {
lc.shutdown(i, false); // Wake up the display
lc.setIntensity(i, 8); // Set brightness for each display
lc.clearDisplay(i); // Clear the display
}
showStartText(); // Show "START" text on the display
digitalWrite(startLedPin, HIGH); // Turn on the LED (pin 32) to indicate readiness
// Wait for the button press to start the game
waitForGameStart();
gameStartTime = millis(); // Record the game start time
lightUpNextTarget(); // Light up the first target LED
}
void loop() {
// Check if the game timer has expired
unsigned long elapsedTime = millis() - gameStartTime;
if (elapsedTime >= gameDuration) {
endGame(); // End the game when the time is up
return;
}
// Update the timer display
unsigned long remainingTime = (gameDuration - elapsedTime) / 1000; // Convert to seconds
displayTimer(remainingTime); // Update the timer on display
// Check if the correct button is pressed
if (digitalRead(buttonPins[currentTarget]) == LOW) { // Button pressed (LOW due to pull-up)
score++; // Increment score
Serial.println("Correct! Score: " + String(score));
// Update score on MAX7219 display
displayScore(score);
delay(500); // Debounce delay to avoid multiple readings
lightUpNextTarget(); // Light up the next target
}
}
// Function to wait for the button press at pin 33 to start the game
void waitForGameStart() {
// Keep checking for the button press
while (digitalRead(startButtonPin) == HIGH) {
// Do nothing, keep waiting for button press
}
// Button pressed, turn off the start LED
digitalWrite(startLedPin, LOW);
lc.clearDisplay(0); // Clear the display once the button is pressed
}
// Function to manually show "START" text on MAX7219 display using bitmaps with proper spacing
void showStartText() {
// Clear all displays before showing text
for (int i = 0; i < 4; i++) {
lc.clearDisplay(i);
}
// Create a custom bitmap for each letter of "START"
// Properly align letters on separate matrices and ensure spacing between them
// "S" on Matrix 0
lc.setRow(0, 1, 0b01111110); // First matrix, row by row for S
lc.setRow(0, 2, 0b10010010);
lc.setRow(0, 3, 0b10000010);
lc.setRow(0, 4, 0b10010010);
lc.setRow(0, 5, 0b01100100);
// "T" on Matrix 1
lc.setRow(1, 1, 0b11111110); // Second matrix for T
lc.setRow(1, 2, 0b00010000);
lc.setRow(1, 3, 0b00010000);
lc.setRow(1, 4, 0b00010000);
lc.setRow(1, 5, 0b00010000);
// "A" on Matrix 2
lc.setRow(2, 1, 0b01111100); // Third matrix for A
lc.setRow(2, 2, 0b00010010);
lc.setRow(2, 3, 0b00010010);
lc.setRow(2, 4, 0b00010010);
lc.setRow(2, 5, 0b01111100);
// "R" on Matrix 3
lc.setRow(3, 1, 0b11111110); // Fourth matrix for R
lc.setRow(3, 2, 0b00100100);
lc.setRow(3, 3, 0b00100100);
lc.setRow(3, 4, 0b00100100);
lc.setRow(3, 5, 0b11011010);
// Add space for "T"
lc.setRow(3, 6, 0b11111110); // Reuse last matrix to display the final "T"
lc.setRow(3, 7, 0b00010000);
}
// Function to light up the next target
void lightUpNextTarget() {
// Turn off all LEDs
for (int i = 0; i < numTargets; i++) {
digitalWrite(ledPins[i], LOW);
}
// Choose the next target
currentTarget = random(numTargets);
// Light up the selected target LED
digitalWrite(ledPins[currentTarget], HIGH);
}
// Function to display score on MAX7219 dot matrix display (32x8)
void displayScore(int score) {
lc.clearDisplay(0); // Clear the score display
// Display score on the first 8x8 matrix
lc.setDigit(0, 0, score / 10, false); // Tens place
lc.setDigit(0, 1, score % 10, false); // Ones place
}
// Function to display the remaining time on MAX7219 dot matrix display (32x8)
void displayTimer(unsigned long remainingTime) {
lc.clearDisplay(1); // Clear the timer display
// Display the remaining time on the second 8x8 matrix
lc.setDigit(1, 0, remainingTime / 10, false); // Tens place of time
lc.setDigit(1, 1, remainingTime % 10, false); // Ones place of time
}
// Function to handle game over logic
void endGame() {
// Turn off all LEDs
for (int i = 0; i < numTargets; i++) {
digitalWrite(ledPins[i], LOW);
}
// Clear both displays
lc.clearDisplay(0); // Clear score display
lc.clearDisplay(1); // Clear timer display
// Display a message or final score here if needed
Serial.println("Game Over!");
while (true); // Stop the game loop
}