/**
Vision Coach for Arduino.
Select the button asigned to the lit LED:
After starting the simulation, click anywhere in the diagram to focus it.
Copyright (C) 2024, Mark Fogliani. Released under the MIT License.
*/
#include "pitches.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(53, 52, 51, 50, 49, 48);
#define SPEAKER_PIN 7
const unsigned long timeout = 5000; // Timeout period in milliseconds (10 seconds);
bool answerReceived = false;
const uint8_t ledPins[] = {13, 12, 11, 10, 9, 8};
const uint8_t buttonPin = 2;
const int buttonTones[] = {
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4,
NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};
const int numTones = sizeof(ledPins) / sizeof(ledPins[0]);
void setup() {
Serial.begin(9600);
for (uint8_t i = 0; i < 6; i++) {
pinMode(ledPins[i], OUTPUT);
}
pinMode(SPEAKER_PIN, OUTPUT);
lcd.begin(16, 2);
// you can now interact with the LCD, e.g.:
lcd.print("Hello World!");
}
/* Digit table for the 7-segment display */
const uint8_t digitTable[] = {
0b11000000,
0b11111001,
0b10100100,
0b10110000,
0b10011001,
0b10010010,
0b10000010,
0b11111000,
0b10000000,
0b10010000,
};
const uint8_t DASH = 0b10111111;
/**
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);
};
/**
Lights the given LED and plays a suitable tone
*/
void lightLedAndPlayTone(byte ledIndex) {
digitalWrite(ledPins[ledIndex], HIGH);
tone(SPEAKER_PIN, buttonTones[ledIndex]);
delay(500);
noTone(SPEAKER_PIN);
};
/**
Waits until the user pressed one of the buttons,
and returns the index of that button
*/
void readButtons(byte ledOn) {
while (true) {
if (digitalRead(buttonPin) == HIGH) {
digitalWrite(ledPins[ledOn], LOW);
return;
}
}
delay(1);
};
/**
Set the string pattern and timer and then wait for button to start the game
*/
void selectPattern() {
digitalWrite(8, HIGH);
tone(SPEAKER_PIN, NOTE_E4);
delay(150);
noTone(SPEAKER_PIN);
tone(SPEAKER_PIN, NOTE_F5);
delay(150);
noTone(SPEAKER_PIN);
}
void waitforStart() {
while (true) {
if (digitalRead(2) == HIGH) {
Serial.println("Game is started");
lcd.begin(16, 2);
lcd.print("Game Started");
digitalWrite(8, LOW);
tone(SPEAKER_PIN, NOTE_E4);
delay(150);
tone(SPEAKER_PIN, NOTE_G4);
delay(150);
tone(SPEAKER_PIN, NOTE_E5);
delay(150);
noTone(SPEAKER_PIN);
delay(2000);
return;
}
}
delay(1);
};
void acceptInputs() {
lcd.begin(16, 2);
lcd.print("Select pattern");
selectPattern();
waitforStart(); /** Waits for Start button to be pressed */
}
/**
The main loop
*/
void loop() {
acceptInputs();
for (uint8_t i = 0; i < 6; i++) {
byte ledOn = i;
lightLedAndPlayTone(ledOn); /** Turns on light and plays a tone */
unsigned long startTime = millis();
while (millis() - startTime < timeout) {
if (digitalRead(buttonPin) == HIGH) {
digitalWrite(ledPins[ledOn], LOW);
Serial.print("Button "); Serial.print(ledOn + 1); Serial.println(" is the Correct Button");
lcd.begin(16, 2); lcd.print("Correct!!!");
playLevelUpSound();
answerReceived = true;
break;
} else {
lcd.begin(16, 2);
lcd.print(int(5-(millis() - startTime)/1000));
}
}
// Turn off the LED after timeout
digitalWrite(ledPins[ledOn], LOW);
if (answerReceived) {
break;
}
}
if (!answerReceived) {
Serial.println("Cycle completed without correct answer.");
lcd.begin(16, 2);
lcd.print("Time Expired");
tone(SPEAKER_PIN, NOTE_F5);
delay(300);
noTone(SPEAKER_PIN);
tone(SPEAKER_PIN, NOTE_E4);
delay(300);
noTone(SPEAKER_PIN);
}
Serial.println("Reset for next round");
answerReceived = false;
delay(2000);
}