#include <Key.h>
#include <Keypad.h>
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
#define REST 0
int buzzer = 8;
const int startingTempo = 50;
int currentTempo = startingTempo;
// const int availableNotes[] = {
// NOTE_C3, NOTE_D3, NOTE_E3, NOTE_F3, NOTE_G3, NOTE_A3, NOTE_B3,
// NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4,
// NOTE_C5, NOTE_D5
// };
// const int AvailableNotesMax = 15;
const int maxMelodySize = 8;
const byte ROWS = 4;
const byte COLS = 4;
// this will be converted into a keymap
const char buttons[ROWS][COLS] = {
{'0', '1', '2', '3'},
{'4', '5', '6', '7'},
{'8', '9', 'a', 'b'},
{'c', 'd', 'e', 'f'},
};
const int tones[ROWS][COLS] = {
{NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4},
{NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5},
{NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5},
{NOTE_A5, NOTE_B5, NOTE_C6, NOTE_D6}
};
// indicates the hardware pins connected to the keypad
// these correspond to the digital pins the keypad is connected to
const byte rowPins[ROWS] = {5, 4, 3, 2};
const byte colPins[COLS] = {6, 7, 12, 13};
const int redPin = 11;
const int greenPin = 10;
const int bluePin = 9;
Keypad keyPad = Keypad(makeKeymap(buttons), rowPins, colPins, ROWS, COLS);
void setup() {
Serial.begin(9600);
pinMode(redPin, OUTPUT); // designate pins for PWM LED output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
redLight();
delay(500);
greenLight();
delay(500);
blueLight();
delay(500);
noLight();
randomSeed(analogRead(0));
}
int melody[maxMelodySize];
int melodyLength = 0;
void loop() {
if (melodyLength > 0) {
playMelody(melody, melodyLength);
if (userAttempt(melody, melodyLength)) {
melody[melodyLength] = generateNote();
melodyLength++;
if (melodyLength == maxMelodySize) {
celebrate();
melodyLength = 0;
}
}
else {
melodyLength = 0;
}
}
else {
Serial.println("Press Any Key to Start");
keyPad.waitForKey();
giveInitialPitch();
melody[0] = generateNote();
melodyLength++;
}
}
void celebrate() {
Serial.println("WINNER!!!");
greenLight();
playNote(NOTE_C5, 500);
blueLight();
playNote(NOTE_E5, 500);
whiteLight();
playNote(NOTE_G4, 500);
greenLight();
playNote(NOTE_E5, 1000);
}
void giveInitialPitch() {
Serial.println("This is keypad note upper left");
playNote(tones[0][0], 3000);
}
bool userAttempt(int melody[], int length) {
char lastPress;
int note;
bool succeeded;
logVar("userAttempt length", length);
for (byte i = 0; i < length; i++) {
whiteLight(); // shows waiting
Serial.print("cheat ");
for(int r=0;r<ROWS;r++)
for(int c=0;c<COLS;c++)
if(tones[c][r]==melody[i])
{ Serial.print(r); Serial.print(',');Serial.println(c); }
lastPress = keyPad.waitForKey();
note = noteForKey(lastPress);
if (melody[i] == note) {
greenLight();
playNote(note, 800);
succeeded = true;
}
else {
redLight();
Serial.println("Wrong");
playNote(NOTE_C2, 1000);
succeeded = false;
logVar("expected note:", melody[i]);
logVar("entered note:", note);
break;
};
}
delay(1000);
return succeeded;
}
void logVar(String pre, int val) {
Serial.print(pre);
Serial.print(" ");
Serial.println(val);
}
int noteForKey(char key) {
int answer = 0;
for (byte row=0; row < ROWS; row++) {
for (byte col=0; col < COLS; col++) {
if (key == buttons[row][col]) {
answer=tones[row][col];
}
}
}
return answer;
}
void playMelody(int melody[], int length) {
const int noteDuration = 60000 / currentTempo;
blueLight();
for (byte i = 0; i < length; i++) {
playNote(melody[i], noteDuration);
}
noLight();
}
void playNote(int note, int duration) {
tone(buzzer, note, duration * 0.9);
delay(duration);
noTone(buzzer);
}
void redLight() {
analogWrite(redPin, 0);
analogWrite(greenPin, 255);
analogWrite(bluePin, 255);
}
void greenLight() {
analogWrite(redPin, 255);
analogWrite(greenPin, 0);
analogWrite(bluePin, 255);
}
void blueLight() {
analogWrite(redPin, 255);
analogWrite(greenPin, 255);
analogWrite(bluePin, 0);
}
void noLight() {
analogWrite(redPin, 255);
analogWrite(greenPin, 255);
analogWrite(bluePin, 255);
}
void whiteLight() {
analogWrite(redPin, 0);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
}
int generateNote() {
int note = tones[random(0, ROWS - 1)][random(0,COLS - 1)];
return note;
}