//##########################################################################################################################################################################################################################
//### Initialize
//##########################################################################################################################################################################################################################
//MODULE 1 - TIMER
//#############################################################################################################
#include <TM1637Display.h>
const unsigned long COUNTDOWN_TIME = 300; // 5 minutes in seconds
#define CLK_PIN 3
#define DIO_PIN 2
TM1637Display display(CLK_PIN, DIO_PIN);
unsigned long startTime;
unsigned long currentTime;
unsigned long elapsedTime;
const int mod1LedPins[] = {4, 5}; // Pins for LEDs
const int mod1ButtonPin = 53; // Pin for error button
int mod1StrikeCount = 0;
unsigned long mod1PreviousMillis = 0;
const long mod1Interval = 100; // Interval for LED blinking in milliseconds
bool mod1LedsOn = false;
//MODULE 2 - WIRES
//#############################################################################################################
#define MOD2_NUM_WIRES 6 // Maximum number of wires
#define MOD2_SERIAL_NUMBER 12345 // Define the serial number
// Pin definitions (assuming analog pins for resistance measurement)
const int mod2WirePins[MOD2_NUM_WIRES] = {A1, A2, A3, A4, A5, A6};
// Global variables
int mod2WireColors[MOD2_NUM_WIRES] = {0}; // Array to store wire colors
int mod2NumWires = 0; // Number of wires detected
bool mod2WireCut[MOD2_NUM_WIRES] = {false}; // Array to store if a wire is cut
// Function prototypes
//void setup();
//void loop();
//void mod2ReadWireColors();
//void mod2AnalyzeAndCutWires();
int mod2GetLastSerialDigit();
// Color constants
enum WireColor {
RED,
WHITE,
BLUE,
YELLOW,
BLACK,
NONE
};
int raw = 0;
int Vin = 5;
float Vout = 0;
float R = 1000;
float buffer = 0;
int mod2Resistance = 0;
//MODULE 3 - SIMON SAYS
//#############################################################################################################
#include "pitches.h"
/* Constants - define pin numbers for LEDs,
buttons and speaker, and also the game tones: */
const byte ledPins[] = {22, 24, 26, 28};
const byte buttonPins[] = {23, 25, 27, 29};
#define SPEAKER_PIN 51
#define MAX_GAME_LENGTH 100
const int gameTones[] = { NOTE_G3, NOTE_C4, NOTE_E4, NOTE_G5};
/* Global variables - store the game state */
byte gameSequence[MAX_GAME_LENGTH] = {0};
byte gameIndex = 0;
byte userIndex = 0;
unsigned long lastActionTime = 0;
const unsigned long actionDelay = 300;
enum GameState { START_SEQUENCE, PLAY_SEQUENCE, USER_INPUT, GAME_OVER, LEVEL_UP };
GameState gameState = START_SEQUENCE;
//MODULE 4 - BIG BUTTON
//#############################################################################################################
// Constants for button colors and text
#define mod4BLUE 1
#define mod4RED 2
#define mod4YELLOW 3
#define mod4WHITE 4
#define mod4DETONATE "Detonate"
#define mod4ABORT "Abort"
#define mod4HOLD "Hold"
// Constants for conditions
#define mod4MORE_THAN_1_BATTERY true
#define mod4MORE_THAN_2_BATTERIES true
#define mod4CAR_INDICATOR true
#define mod4FRK_INDICATOR true
// Pin definitions
#define mod4BUTTON_PIN 32 // Replace with your actual button pin
#define mod4LED_PIN 13 // Replace with your actual LED pin for debugging
// Variables
int mod4buttonColor;
char mod4buttonText[10]; // To store button text
bool mod4hasMoreThan1Battery = false;
bool mod4hasMoreThan2Batteries = false;
bool mod4carIndicatorLit = false;
bool mod4frkIndicatorLit = false;
bool mod4buttonPressed = false;
bool mod4buttonReleased = false;
unsigned long mod4pressTime = 0;
//MODULE 5 - KEYPADS
//#############################################################################################################
//MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
//##########################################################################################################################################################################################################################
//### SETUP
//##########################################################################################################################################################################################################################
void setup() {
Serial.begin(9600);
//MODULE 1 - TIMER
display.setBrightness(7); // Set the brightness of the display (0-7)
display.clear(); // Clear the display
startTime = millis(); // Record the starting time
for (int i = 0; i < 2; i++) {
pinMode(mod1LedPins[i], OUTPUT);
}
pinMode(mod1ButtonPin, INPUT_PULLUP);
//MODULE 2 - WIRES
// Initialize wire pins as inputs
for (int i = 0; i < MOD2_NUM_WIRES; i++) {
pinMode(mod2WirePins[i], INPUT);
}
//MODULE 3 - SIMON SAYS
for (byte i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(SPEAKER_PIN, OUTPUT);
// The following line primes the random number generator.
// It assumes pin A0 is floating (disconnected):
randomSeed(analogRead(A0));
//MODULE 4 - BIG BUTTON
// Initialize pins
pinMode(mod4BUTTON_PIN, INPUT);
pinMode(mod4LED_PIN, OUTPUT);
// Simulate conditions (replace with actual logic to check these)
mod4hasMoreThan1Battery = mod4MORE_THAN_1_BATTERY;
mod4hasMoreThan2Batteries = mod4MORE_THAN_2_BATTERIES;
mod4carIndicatorLit = mod4CAR_INDICATOR;
mod4frkIndicatorLit = mod4FRK_INDICATOR;
//MODULE 5 - KEYPADS
//MODULE 6 - NEEDY - KNOBS
}
//##########################################################################################################################################################################################################################
//### FUNCTIONS
//##########################################################################################################################################################################################################################
//#############################################################################################################
//### MODULE 1 - TIMER
//#############################################################################################################
//#############################################################################################################
//### MODULE 2 - WIRES
//#############################################################################################################
void mod2ReadWireColors() {
// Simulate reading resistance values to determine wire colors
// This is a placeholder function. Actual implementation will depend on your sensor setup.
for (int i = 0; i < MOD2_NUM_WIRES; i++) {
raw = analogRead(mod2WirePins[i]);
if(raw){
buffer = raw * Vin;
Vout = (buffer)/1024.0;
buffer = (Vin/Vout) - 1;
mod2Resistance = R * buffer;
Serial.print("Vout: ");
Serial.println(Vout);
Serial.print("mod2Resistance: ");
Serial.println(mod2Resistance);
}
if (mod2Resistance < 200) {
mod2WireColors[i] = RED;
Serial.println("RED");
//delay(300);
} else if (mod2Resistance < 400) {
mod2WireColors[i] = WHITE;
Serial.println("WHITE");
//delay(300);
} else if (mod2Resistance < 600) {
mod2WireColors[i] = BLUE;
Serial.println("BLUE");
//delay(300);
} else if (mod2Resistance < 800) {
mod2WireColors[i] = YELLOW;
Serial.println("YELLOW");
//delay(300);
} else if (mod2Resistance < 1000) {
mod2WireColors[i] = BLACK;
Serial.println("BLACK");
//delay(300);
} else {
mod2WireColors[i] = NONE;
Serial.println("NONE");
//delay(300);
}
}
//delay(3000);
// Determine the number of wires
mod2NumWires = MOD2_NUM_WIRES;
while (mod2NumWires > 0 && mod2WireColors[mod2NumWires - 1] == NONE) {
mod2NumWires--;
}
}
void mod2AnalyzeAndCutWires() {
int mod2LastSerialDigit = mod2GetLastSerialDigit();
int mod2CutWire = -1;
if (mod2NumWires == 3) {
if (mod2CountWires(RED) == 0) {
mod2CutWire = 1; // Cut second wire
} else if (mod2WireColors[2] == WHITE) {
mod2CutWire = 2; // Cut last wire
} else if (mod2CountWires(BLUE) > 1) {
mod2CutWire = mod2FindLastWire(BLUE); // Cut last blue wire
} else {
mod2CutWire = 2; // Cut last wire
}
} else if (mod2NumWires == 4) {
if (mod2CountWires(RED) > 1 && mod2LastSerialDigit % 2 == 1) {
mod2CutWire = mod2FindLastWire(RED); // Cut last red wire
} else if (mod2WireColors[3] == YELLOW && mod2CountWires(RED) == 0) {
mod2CutWire = 0; // Cut first wire
} else if (mod2CountWires(BLUE) == 1) {
mod2CutWire = 0; // Cut first wire
} else if (mod2CountWires(YELLOW) > 1) {
mod2CutWire = 3; // Cut last wire
} else {
mod2CutWire = 1; // Cut second wire
}
} else if (mod2NumWires == 5) {
if (mod2WireColors[4] == BLACK && mod2LastSerialDigit % 2 == 1) {
mod2CutWire = 3; // Cut fourth wire
} else if (mod2CountWires(RED) == 1 && mod2CountWires(YELLOW) > 1) {
mod2CutWire = 0; // Cut first wire
} else if (mod2CountWires(BLACK) == 0) {
mod2CutWire = 1; // Cut second wire
} else {
mod2CutWire = 0; // Cut first wire
}
} else if (mod2NumWires == 6) {
if (mod2CountWires(YELLOW) == 0 && mod2LastSerialDigit % 2 == 1) {
mod2CutWire = 2; // Cut third wire
} else if (mod2CountWires(YELLOW) == 1 && mod2CountWires(WHITE) > 1) {
mod2CutWire = 3; // Cut fourth wire
} else if (mod2CountWires(RED) == 0) {
mod2CutWire = 5; // Cut last wire
} else {
mod2CutWire = 3; // Cut fourth wire
}
}
// Simulate cutting the wire
/*if (mod2CutWire >= 0) {
mod2WireCut[mod2CutWire] = true;
Serial.print("Cut wire: ");
Serial.println(mod2CutWire + 1);
}*/
}
int mod2GetLastSerialDigit() {
return MOD2_SERIAL_NUMBER % 10;
}
int mod2CountWires(WireColor color) {
int count = 0;
for (int i = 0; i < mod2NumWires; i++) {
if (mod2WireColors[i] == color) {
count++;
}
}
return count;
}
int mod2FindLastWire(WireColor color) {
for (int i = mod2NumWires - 1; i >= 0; i--) {
if (mod2WireColors[i] == color) {
return i;
}
}
return -1;
}
bool mod2CheckCorrectWireCut() {
int mod2CorrectWire = -1;
int mod2CutWire = -1;
if (mod2NumWires == 3) {
if (mod2CountWires(RED) == 0) {
mod2CorrectWire = 1;
} else if (mod2WireColors[2] == WHITE) {
mod2CorrectWire = 2;
} else if (mod2CountWires(BLUE) > 1) {
mod2CorrectWire = mod2FindLastWire(BLUE);
} else {
mod2CorrectWire = 2;
}
} else if (mod2NumWires == 4) {
if (mod2CountWires(RED) > 1 && mod2GetLastSerialDigit() % 2 == 1) {
mod2CorrectWire = mod2FindLastWire(RED);
} else if (mod2WireColors[3] == YELLOW && mod2CountWires(RED) == 0) {
mod2CorrectWire = 0;
} else if (mod2CountWires(BLUE) == 1) {
mod2CorrectWire = 0;
} else if (mod2CountWires(YELLOW) > 1) {
mod2CorrectWire = 3;
} else {
mod2CorrectWire = 1;
}
} else if (mod2NumWires == 5) {
if (mod2WireColors[4] == BLACK && mod2GetLastSerialDigit() % 2 == 1) {
mod2CorrectWire = 3;
} else if (mod2CountWires(RED) == 1 && mod2CountWires(YELLOW) > 1) {
mod2CorrectWire = 0;
} else if (mod2CountWires(BLACK) == 0) {
mod2CorrectWire = 1;
} else {
mod2CorrectWire = 0;
}
} else if (mod2NumWires == 6) {
if (mod2CountWires(YELLOW) == 0 && mod2GetLastSerialDigit() % 2 == 1) {
mod2CorrectWire = 2;
} else if (mod2CountWires(YELLOW) == 1 && mod2CountWires(WHITE) > 1) {
mod2CorrectWire = 3;
} else if (mod2CountWires(RED) == 0) {
mod2CorrectWire = 5;
} else {
mod2CorrectWire = 3;
}
}
return (mod2CutWire == mod2CorrectWire);
}
//#############################################################################################################
//### MODULE 3 - SIMON SAYS
//#############################################################################################################
// Lights the given LED and plays a suitable tone
void lightLedAndPlayTone(byte ledIndex) {
digitalWrite(ledPins[ledIndex], HIGH);
tone(SPEAKER_PIN, gameTones[ledIndex]);
delay(300);
digitalWrite(ledPins[ledIndex], LOW);
noTone(SPEAKER_PIN);
}
// Plays the current sequence of notes that the user has to repeat
void playSequence() {
static byte seqIndex = 0;
if (seqIndex < gameIndex) {
byte currentLed = gameSequence[seqIndex];
lightLedAndPlayTone(currentLed);
seqIndex++;
lastActionTime = millis();
} else {
seqIndex = 0;
gameState = USER_INPUT;
}
}
// Waits until the user pressed one of the buttons, and returns the index of that button
byte readButtons() {
for (byte i = 0; i < 4; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
return i;
}
}
return 255;
}
// Play the game over sequence, and report the game score
void gameOver() {
Serial.print("Game over! your score: ");
Serial.println(gameIndex - 1);
gameIndex = 0;
userIndex = 0;
// Play a Wah-Wah-Wah-Wah sound
tone(SPEAKER_PIN, NOTE_DS5);
delay(300);
tone(SPEAKER_PIN, NOTE_D5);
delay(300);
tone(SPEAKER_PIN, NOTE_CS5);
delay(300);
for (byte i = 0; i < 10; i++) {
for (int pitch = -10; pitch <= 10; pitch++) {
tone(SPEAKER_PIN, NOTE_C5 + pitch);
delay(5);
}
}
noTone(SPEAKER_PIN);
delay(500);
gameState = START_SEQUENCE;
}
// Plays a hooray sound whenever the user finishes a level
void playLevelUpSound() {
tone(SPEAKER_PIN, NOTE_E4);
delay(150);
tone(SPEAKER_PIN, NOTE_G4);
delay(150);
tone(SPEAKER_PIN, NOTE_E5);
delay(150);
tone(SPEAKER_PIN, NOTE_C5);
delay(150);
tone(SPEAKER_PIN, NOTE_D5);
delay(150);
tone(SPEAKER_PIN, NOTE_G5);
delay(150);
noTone(SPEAKER_PIN);
}
//#############################################################################################################
//### MODULE 4 - BIG BUTTON
//#############################################################################################################
void mod4pressAndRelease() {
digitalWrite(mod4LED_PIN, HIGH); // Debugging LED ON
Serial.println("Pressing and immediately releasing the button.");
// Simulate pressing and releasing the button
// Replace with actual code to press and release the button
delay(1000); // Simulate button press time
// Button release code here
digitalWrite(mod4LED_PIN, LOW); // Debugging LED OFF
}
void mod4holdButton() {
digitalWrite(mod4LED_PIN, HIGH); // Debugging LED ON
Serial.println("Holding the button and waiting for release instructions.");
// Simulate holding the button
// Replace with actual code to hold the button
mod4buttonPressed = true;
mod4pressTime = millis();
}
void mod4handleRelease() {
unsigned long mod4currentTime = millis();
unsigned long mod4pressDuration = mod4currentTime - mod4pressTime;
int mod4lastDigit = (millis() / 1000) % 10; // Get last digit of seconds
// Simulate strip color detection
int mod4stripColor = mod4detectStripColor(); // Replace with actual strip color detection
// Determine when to release based on strip color
if (mod4stripColor == mod4BLUE) {
if (mod4lastDigit == 4) {
Serial.println("Release on blue strip with 4 in any position.");
// Release button code here
mod4buttonReleased = true;
}
} else if (mod4stripColor == mod4WHITE) {
if (mod4lastDigit == 1) {
Serial.println("Release on white strip with 1 in any position.");
// Release button code here
mod4buttonReleased = true;
}
} else if (mod4stripColor == mod4YELLOW) {
if (mod4lastDigit == 5) {
Serial.println("Release on yellow strip with 5 in any position.");
// Release button code here
mod4buttonReleased = true;
}
} else {
if (mod4lastDigit == 1) {
Serial.println("Release on any other color strip with 1 in any position.");
// Release button code here
mod4buttonReleased = true;
}
}
if (mod4buttonReleased) {
digitalWrite(mod4LED_PIN, LOW); // Debugging LED OFF
mod4buttonPressed = false;
mod4buttonReleased = false;
}
}
// Function to simulate reading button color (replace with actual implementation)
int mod4readButtonColor() {
return mod4BLUE; // Simulating blue button
}
// Function to simulate reading button text (replace with actual implementation)
char* mod4readButtonText() {
return mod4ABORT; // Simulating button text "Abort"
}
// Function to simulate strip color detection (replace with actual implementation)
int mod4detectStripColor() {
return mod4BLUE; // Simulating blue strip
}
//#############################################################################################################
//### MODULE 5 - KEYPADS
//#############################################################################################################
//#############################################################################################################
//### MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
//##########################################################################################################################################################################################################################
//### Loop
//##########################################################################################################################################################################################################################
void loop() {
//MODULE 1 - TIMER
//#############################################################################################################
currentTime = millis(); // Get the current time
elapsedTime = (currentTime - startTime) / 1000; // Calculate elapsed time in seconds
if (elapsedTime <= COUNTDOWN_TIME) {
unsigned long remainingTime = COUNTDOWN_TIME - elapsedTime;
// Display remaining time in Minutes:Seconds format
unsigned int minutes = remainingTime / 60;
unsigned int seconds = remainingTime % 60;
display.showNumberDecEx(minutes * 100 + seconds, 0b01000000, true);
if (remainingTime == 0) {
// Start blinking when countdown reaches 00:00
while (true) {
display.showNumberDecEx(0, 0b01000000, true); // Display "00:00"
delay(500);
display.clear(); // Clear the display
delay(500);
}
}
}
if (digitalRead(mod1ButtonPin) == LOW) {
delay(50); // Debounce delay
if (digitalRead(mod1ButtonPin) == LOW) {
mod1StrikeCount++;
Serial.println("Strike added!");
tone(SPEAKER_PIN, NOTE_E4);
delay(150);
noTone(SPEAKER_PIN);
delay(50); // Short delay to avoid multiple increments
}
}
if (mod1StrikeCount >= 3) {
unsigned long mod1CurrentMillis = millis();
if (mod1CurrentMillis - mod1PreviousMillis >= mod1Interval) {
mod1PreviousMillis = mod1CurrentMillis;
mod1LedsOn = !mod1LedsOn;
for (int i = 0; i < 2; i++) {
digitalWrite(mod1LedPins[i], mod1LedsOn ? HIGH : LOW);
}
}
tone(SPEAKER_PIN, NOTE_E4);
delay(150);
noTone(SPEAKER_PIN);
Serial.println("BOOOOM!");
mod1StrikeCount = 0;
} else {
for (int i = 0; i < 2; i++) {
digitalWrite(mod1LedPins[i], i < mod1StrikeCount ? HIGH : LOW);
}
//tone(SPEAKER_PIN, NOTE_E4);
}
//MODULE 2 - WIRES
//#############################################################################################################
// Read wire colors
mod2ReadWireColors();
// Analyze wires and decide which to cut
mod2AnalyzeAndCutWires();
// Add a small delay to avoid excessive looping
delay(100);
//MODULE 3 - SIMON SAYS
//#############################################################################################################
// Add a random color to the end of the sequence
switch (gameState) {
case START_SEQUENCE:
// Add a random color to the end of the sequence
gameSequence[gameIndex] = random(0, 4);
gameIndex++;
if (gameIndex >= MAX_GAME_LENGTH) {
gameIndex = MAX_GAME_LENGTH - 1;
}
gameState = PLAY_SEQUENCE;
break;
case PLAY_SEQUENCE:
if (millis() - lastActionTime >= actionDelay) {
playSequence();
}
break;
case USER_INPUT:
if (userIndex < gameIndex) {
byte button = readButtons();
if (button != 255) {
lightLedAndPlayTone(button);
if (gameSequence[userIndex] != button) {
gameState = GAME_OVER;
} else {
userIndex++;
}
}
} else {
gameState = LEVEL_UP;
}
break;
case GAME_OVER:
gameOver();
break;
case LEVEL_UP:
playLevelUpSound();
delay(300);
userIndex = 0;
gameState = START_SEQUENCE;
break;
}
//MODULE 4 - BIG BUTTON
//#############################################################################################################
// Read button color and text (simulate for now)
mod4buttonColor = mod4readButtonColor(); // Replace with actual function to read color
strcpy(mod4buttonText, mod4readButtonText()); // Replace with actual function to read text
// Check conditions based on the rules
if (mod4buttonColor == mod4BLUE && strcmp(mod4buttonText, mod4ABORT) == 0) {
// Rule 1: Blue button with text "Abort"
mod4holdButton();
} else if (mod4hasMoreThan1Battery && strcmp(mod4buttonText, mod4DETONATE) == 0) {
// Rule 2: More than 1 battery and button says "Detonate"
mod4pressAndRelease();
} else if (mod4buttonColor == mod4WHITE && mod4carIndicatorLit) {
// Rule 3: White button and lit indicator CAR
mod4holdButton();
} else if (mod4hasMoreThan2Batteries && mod4frkIndicatorLit) {
// Rule 4: More than 2 batteries and lit indicator FRK
mod4pressAndRelease();
} else if (mod4buttonColor == mod4YELLOW) {
// Rule 5: Yellow button
mod4holdButton();
} else if (mod4buttonColor == mod4RED && strcmp(mod4buttonText, mod4HOLD) == 0) {
// Rule 6: Red button with text "Hold"
mod4pressAndRelease();
} else {
// Rule 7: None of the above
mod4holdButton();
}
// Handle button release timing if button is held
if (mod4buttonPressed && !mod4buttonReleased) {
mod4handleRelease();
}
//MODULE 5 - KEYPADS
//#############################################################################################################
//MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
}
Loading
grove-oled-sh1107
grove-oled-sh1107