//##########################################################################################################################################################################################################################
//### Initialize
//##########################################################################################################################################################################################################################
//MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
#include <TM1637Display.h>
#include <Adafruit_NeoPixel.h>
#include <Encoder.h>
// Define pins for WS2812 LED ring
#define LED_PIN 50
#define LED_COUNT 12
// Define pins for 4-digit display
#define CLK_PIN 46
#define DIO_PIN 47
// Define pins for rotary encoder
#define ENC_CLK_PIN 49
#define ENC_DT_PIN 48
// Create objects for 4-digit display and LED ring
TM1637Display display(CLK_PIN, DIO_PIN);
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Create object for rotary encoder
Encoder encoder(ENC_CLK_PIN, ENC_DT_PIN);
// Variables for countdown timer
unsigned long countdownTime;
unsigned long startTime;
bool timerRunning = false;
int chosenLedConfig[0][0];
int chosenDirection;
int chosenDirectionPattern;
// LED configurations for rotary encoder positions
// Each pair of configurations corresponds to one of the four positions (up, right, down, left)
const int ledConfigurations[4][2][12] = {
{{0,0,1,0,1,1,1,1,1,1,0,1}, {1,0,1,0,1,0,0,1,1,0,1,1}}, // UP (Example configurations)
{{1,0,1,1,1,1,1,1,1,0,1,0}, {1,0,1,1,0,0,1,1,1,0,1,0}}, // RIGHT
{{0,1,1,0,0,1,1,1,1,1,0,1}, {1,0,1,0,1,0,0,1,0,0,0,1}}, // DOWN
{{0,0,0,0,1,0,1,0,0,1,1,1}, {0,0,0,0,1,0,0,0,0,1,1,0}} // LEFT
};
int configuration[12] = {};
// Position labels
const char* positionLabels[4] = {"UP", "RIGHT", "DOWN", "LEFT"};
//##########################################################################################################################################################################################################################
//### SETUP
//##########################################################################################################################################################################################################################
void setup() {
Serial.begin(9600);
}
//##########################################################################################################################################################################################################################
//### FUNCTIONS
//##########################################################################################################################################################################################################################
//#############################################################################################################
//### MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
void startGame() {
// Initialize 4-digit display and LED ring
display.setBrightness(0x0f);
strip.begin();
strip.show();
// Seed random number generator
randomSeed(analogRead(A0));
// Start random countdown timer between 30 seconds and 2 minutes
countdownTime = random(5, 10);
startTime = millis();
timerRunning = true;
// Set initial LED configuration
chosenDirection = random(0,4);
chosenDirectionPattern = random(0,2);
Serial.print("Selected config: ");
for (int i = 0; i < 12; i++) {
Serial.print(ledConfigurations[chosenDirection][chosenDirectionPattern][i]);
}
Serial.print(" Orientation: ");
Serial.print(positionLabels[chosenDirection]);
Serial.println();
setLEDConfiguration();
}
// Function to display time on 4-digit display
void displayTime(int seconds) {
int minutes = seconds / 60;
int remainingSeconds = seconds % 60;
display.showNumberDecEx(minutes * 100 + remainingSeconds, 0b01000000, true);
}
// Function to set LED configuration based on current rotary encoder position
void setLEDConfiguration() {
for (int i = 0; i < 12; i++) {
configuration[i] = ledConfigurations[chosenDirection][chosenDirectionPattern][i];
if (configuration[i] == 1) {
strip.setPixelColor(i, strip.Color(255, 255, 255)); // White color
} else {
strip.setPixelColor(i, strip.Color(0, 0, 0)); // Off
}
}
strip.show();
}
// Function to get current rotary encoder position
uint8_t getEncoderPosition() {
// The encoder emits 20 pulses per rotation. Assuming initial position is UP (0).
long position = encoder.read() / 20; // Adjust for pulses per rotation
return position % 4; // Wrap-around if necessary
}
//##########################################################################################################################################################################################################################
//### Loop
//##########################################################################################################################################################################################################################
void loop() {
//MODULE 6 - NEEDY - KNOBS
//#############################################################################################################
if (timerRunning) {
unsigned long currentTime = millis();
unsigned long elapsedTime = (currentTime - startTime) / 1000;
if (elapsedTime >= countdownTime) {
timerRunning = false;
// Get current and required positions
uint8_t currentPosition = getEncoderPosition();
// Debug messages
Serial.print("Current Position: ");
Serial.println(positionLabels[currentPosition]);
Serial.print("Required Position: ");
Serial.println(positionLabels[chosenDirection]);
// Check if rotary encoder is in the correct position
if (currentPosition == positionLabels[chosenDirection]) {
// Correct position
display.showNumberDecEx(8888, 0b01000000, true); // Display success indicator (e.g., 8888)
Serial.println("Correct Position!");
} else {
// Incorrect position
display.showNumberDecEx(1111, 0b01000000, true); // Display failure indicator (e.g., 1111)
Serial.println("Incorrect Position!");
}
} else {
// Update countdown display
displayTime(countdownTime - elapsedTime);
}
} else {
int randomStart = random(0,10000);
delay(100);
Serial.println(randomStart);
if (randomStart == 0) {
startGame();
}
}
}