#include <Servo.h>
const byte RED_BUTTON = 5;
const byte GREEN_BUTTON = 4;
const byte BLUE_BUTTON = 3;
const byte YELLOW_BUTTON = 2;
const byte RED_LED = 12;
const byte GREEN_LED = 11;
const byte BLUE_LED = 10;
const byte YELLOW_LED = 9;
#define SPEAKER 8
#define RED_TONE 310
#define GREEN_TONE 415
#define BLUE_TONE 209
#define YELLOW_TONE 252
#define GAME_OVER 100
#define TONE_DURATION 500
#define DELAY_TIME 300
int GameOver = 0;
int GameMode = 0;
int Sequence[50];
int SequenceLength;
byte Buttons[4] = {RED_BUTTON, GREEN_BUTTON, BLUE_BUTTON, YELLOW_BUTTON};
byte Leds[4] = {RED_LED, GREEN_LED, BLUE_LED, YELLOW_LED};
int Tones[4] = {RED_TONE, GREEN_TONE, BLUE_TONE, YELLOW_TONE};
Servo servoMotor; // Create a servo object to control the servo motor
void RunSequence();
void ReadSequence();
void PlayTone(int value, int duration);
void RotateServo();
void setup()
{
pinMode(SPEAKER, OUTPUT);
for (byte i = 0; i < 4; i++)
{
pinMode(Buttons[i], INPUT_PULLUP);
pinMode(Leds[i], OUTPUT);
}
for (byte i = 0; i < 4; i++)
{
digitalWrite(Leds[i], HIGH);
PlayTone(Tones[i], 100);
digitalWrite(Leds[i], LOW);
}
for (int8_t i = 2; i >= 0; i--)
{
digitalWrite(Leds[i], HIGH);
PlayTone(Tones[i], 100);
digitalWrite(Leds[i], LOW);
}
delay((1000));
GameMode = 0;
GameOver = 0;
SequenceLength = 0;
randomSeed(analogRead(A0));
servoMotor.attach(7); // Attaching the servo motor to pin 7
}
void loop() {
while (GameOver == 0) {
if (GameMode == 0) {
// Play back sequence
RunSequence();
} else {
// Read Sequence
ReadSequence();
}
}
delay(DELAY_TIME); // Delay a little bit to improve simulation performance
}
void RunSequence() {
// Run through the current sequence
if (SequenceLength > 0) {
for (int index = 0; index < SequenceLength; ++index) {
digitalWrite(Leds[Sequence[index]], HIGH);
PlayTone(Tones[Sequence[index]], TONE_DURATION);
digitalWrite(Leds[Sequence[index]], LOW);
delay(DELAY_TIME);
}
}
// Add a new item to sequence
int newValue = random(0, 4);
Sequence[SequenceLength++] = newValue;
digitalWrite(Leds[newValue], HIGH);
PlayTone(Tones[newValue], TONE_DURATION);
digitalWrite(Leds[newValue], LOW);
delay(DELAY_TIME);
GameMode = 1;
// Check for score of 3 and activate the servo motor
if (SequenceLength >= 3) {
RotateServo();
}
}
void ReadSequence()
{
int inputButtonIndex = -1; // Purposefully initialise to a bogus button index.
byte expectedButtonIndex;
for (byte index = 0; index < SequenceLength; ++index)
{
expectedButtonIndex = Sequence[index];
while (inputButtonIndex == -1)
{
for (byte i = 0; i < 4; ++i)
{
if (digitalRead(Buttons[i]) == LOW) // Test for the button being LOW when pressed.
{
inputButtonIndex = i; // Use button index instead of button pin number.
break;
}
}
delay(50); // Add a small delay for stability
}
if (inputButtonIndex == expectedButtonIndex)
{
digitalWrite(Leds[inputButtonIndex], HIGH);
PlayTone(Tones[inputButtonIndex], TONE_DURATION);
digitalWrite(Leds[inputButtonIndex], LOW);
}
else
{
GameOver = 1;
PlayTone(GAME_OVER, TONE_DURATION * 3);
break;
}
inputButtonIndex = -1; // Reset input for the next iteration
delay(300); // Pause between button presses for stability
}
if (!GameOver) {
delay(1000); // Delay before adding a new item to the sequence
GameMode = 0;
}
}
void PlayTone(int value, int duration) {
tone(SPEAKER, value, duration);
delay(duration);
}
void RotateServo() {
for (int angle = 0; angle <= 180; angle += 2) {
servoMotor.write(angle);
delay(10); // Smaller delay for smoother movement
}
delay(500); // Wait for half a second at 180 degrees
for (int angle = 180; angle >= 0; angle -= 2) {
servoMotor.write(angle);
delay(10); // Smaller delay for smoother movement
}
delay(500); // Wait for half a second at 0 degrees
}