-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArduinoMemory.ino
More file actions
231 lines (199 loc) · 5.84 KB
/
Copy pathArduinoMemory.ino
File metadata and controls
231 lines (199 loc) · 5.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Storage of the sequence
const int maxRounds = 7; // Maximum rounds
int currentLength = 0;
int sequence[maxRounds+1];
int currentGuess = 0;
int guess[maxRounds+1];
#define MODE_SHOWING_SEQUENCE 0
#define MODE_ACQUIRE_INPUT 1
#define MODE_CALCULATE_RESULT 2
#define MODE_RESET 3
#define MODE_WON 4
int mode; // The current state of the state machine
int shortDelay = 250; // These values define how fast the red LED should flash
int longDelay = 1000;
int ledPin = 30;
int buzzerPin = 32;
int readyInput = 34;
int buttonPin = 2; // Pins in the 30 range are OUTPUT only but the button requires INPUT
#define LONG_PRESS_LENGTH 500
#define NOTE_C4 262
#define NOTE_G4 392
#define NOTE_B4 494
#define NOTE_E4 330
#define NOTE_C5 523
#define NOTE_E3 165
#define NOTE_C3 131
// Music for start of game
void playStart() {
int toneLength = 500;
tone(buzzerPin, NOTE_E4, 1000/4);
delay(toneLength);
tone(buzzerPin, NOTE_E4, 1000/4);
delay(toneLength);
tone(buzzerPin, NOTE_E4, 1000/4);
delay(toneLength);
tone(buzzerPin, NOTE_B4, 1000/2);
delay(toneLength);
}
// Music for losing the game
void playFail() {
tone(buzzerPin, NOTE_E3, 1000/4);
delay(200);
tone(buzzerPin, NOTE_C3, 1000/4);
}
// Sound effect confirming success
void playSuccess() {
tone(buzzerPin, NOTE_C4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_E4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_G4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_C5, 1000/4);
}
// Music for winning the game
void playWon() {
for (int i=0; i<3; i++) {
tone(buzzerPin, NOTE_C4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_E4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_C4, 1000/4);
delay(100);
tone(buzzerPin, NOTE_C5, 1000/4);
}
}
// Checks if the user guessed the proper sequence
bool compare() {
for ( int i = 0; i < currentLength; i++ ) {
if (guess[i] != sequence[i]) {
return false;
}
}
return true;
}
// Add a random item to the sequence, thereby extending it by 1 in length
// 0 = short, 1 = long
void createSequence() {
sequence[currentLength] = random(0,2);
}
// Play the sequence to be guessed
void showSequence() {
Serial.println("Play");
for (int i = 0; i < currentLength; i++ ) {
Serial.print(sequence[i]);
digitalWrite(ledPin, HIGH);
if ( sequence[i] == 0 ) {
delay(shortDelay);
} else { // Long
delay(longDelay);
}
digitalWrite(ledPin, LOW);
delay(500);
}
Serial.println();
}
unsigned long timeButton = 0;
// Reset the state of the game to its starting position
void reset() {
currentLength = 0;
createSequence();
currentLength = 1;
playStart();
}
// Initialization on first run
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(readyInput, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
randomSeed(analogRead(0)); // Initialize the random generator
mode = MODE_RESET; // Initialise the state machine to (re)set the game to its starting position
}
bool isPressed;
bool isLong = false;
void loop() {
// Should we reset the game? Happens on first startup, when losing the game or winning the game
if ( mode == MODE_RESET) {
reset();
mode = MODE_SHOWING_SEQUENCE; // After reset, immediately show the generated sequence
}
// We should extend the sequence and display it to the user
if ( mode == MODE_SHOWING_SEQUENCE) {
digitalWrite(readyInput, LOW);
createSequence();
showSequence();
// Set mode to user input
currentGuess = 0;
digitalWrite(readyInput, HIGH);
mode = MODE_ACQUIRE_INPUT;
}
// User input handler
if ( mode == MODE_ACQUIRE_INPUT ) {
int state = digitalRead(buttonPin); // Get the state of the button
if (state == LOW) { // If the button is depressed, turn off the red led
digitalWrite(ledPin, LOW);
if (!isPressed) { // If the buttons was not pressed down earlier, then only
timeButton = millis(); // record last time the button was not pressed
} else { // The buttonn was depressed after being pressed
if ( isLong ) { // Did we register a long press?
guess[currentGuess] = 1;
} else {
guess[currentGuess] = 0;
}
currentGuess += 1;
// Log the guess to serial (debugging code)
Serial.println("Current Guess:");
for ( int i = 0; i < currentGuess; i++ ) {
Serial.print(guess[i]);
}
Serial.println();
// If the user guessed all items in sequence, switch to checking the result of the input
if (currentGuess == currentLength) {
mode = MODE_CALCULATE_RESULT;
}
isPressed = false;
isLong = false;
}
} else {
// The button is depressed
isPressed = true;
long result = millis()-timeButton; // The button was pressed this long
// Register as long press if it was pressed longer than 500ms pressed
if (result > LONG_PRESS_LENGTH) {
isLong = true;
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
}
}
if ( mode == MODE_CALCULATE_RESULT) { // Check if we should advance to next level or end the game due to win or loss
digitalWrite(readyInput, LOW);
delay(1000);
if (!compare()) { // User guessed incorrectly
playFail();
delay(1000);
mode = MODE_RESET;
} else {
playSuccess();
}
delay(1000);
if ( mode != MODE_RESET) { // If the user did not fail before the last round
if ( currentLength == maxRounds ) { // Check if we just did the last round
mode = MODE_WON; // Game is over and won
} else {
mode = MODE_SHOWING_SEQUENCE; // Continue gaming with the next round!
currentLength += 1;
}
}
}
// The user won, so play glorious music and start over
if ( mode == MODE_WON ) {
playWon();
delay(1000);
mode = MODE_RESET;
}
}