#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define LCD_I2C_ADDRESS 0x27
LiquidCrystal_I2C lcd (LCD_I2C_ADDRESS, LCD_COLUMNS, LCD_ROWS);
// Arduino Whack-A-Mole - www.101computing.net/arduino-whack-a-mole
int red = 0;
int green = 0;
int blue = 0;
int redButton = 5;
int redLed = 11;
int greenButton = 6;
int greenLed = 12;
int blueButton = 7;
int blueLed = 13;
int buzzerPin = 10;
int incorrectOut = 10;
int correctOut = 9;
int mole = -1;
int prevMole = -1;
int totalMoles = 0;
int caughtMoles = 0;
boolean counting;
boolean pushButton;
boolean ledStatusRed;
boolean ledStatusGreen;
boolean ledStatusBlue;
boolean ledChange;
boolean enableSound = true;
int lastState = HIGH; // to track last button state
long period1 = 2000; // period at which led1 blinks in ms
unsigned long previousMillis1 = 0; //store last time LED1 was blinked
unsigned long previousMillisRed;
unsigned long previousMillisGreen;
unsigned long previousMillisBlue;
bool buttonPushed = false;
unsigned long currentMillis;
int debouncePeriod = 20; // debounce delay of 20ms
int debounceMillis = 0; // similar to previousMillis
void setup()
{
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(redButton, INPUT);
pinMode(greenButton, INPUT);
pinMode(blueButton, INPUT);
counting = true;
//LCD
lcd.begin(16, 2);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Start Game");
pulseTheBuzzer();
pulseTheLED();
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Total:");
//lcd.setCursor(0,1);
//lcd.print("Caught:");
displayMole();
prevMole=mole;
}
// Randomly decide which LED to turn on
void displayMole() {
mole = rand() % 3 + 1;
if(mole==prevMole)
{
period1 = 1000;
}
else
{
period1 = 4000;
}
}
void playFreq(double freqHz, int durationMs){
//Calculate the period in microseconds
int periodMicro = int((1/freqHz)*1000000);
int halfPeriod = periodMicro/2;
//store start time
int startTime = millis();
//(millis() - startTime) is elapsed play time
while((millis() - startTime) < durationMs){
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(halfPeriod);
digitalWrite(buzzerPin, LOW);
delayMicroseconds(halfPeriod);
}
}
// If the user presses a button corresponding to the right LED (Whack a mole) > High pitch noise
// If the user presses the wrong button > Low pitch noise
void whackMole() {
if (digitalRead(redButton) == HIGH)
{
pushButton = true;
}
if (digitalRead(greenButton) == HIGH)
{
pushButton = true;
}
if (digitalRead(blueButton) == HIGH)
{
pushButton = true;
}
}
//If there is no game going on, pulse the LED on/off
//If the user ever presses the button then return immediately
//This function takes approximately 6 seconds to complete
void pulseTheLED(void)
{
for (int i = 0; i < 3; i++)
{
digitalWrite(redLed, HIGH);
digitalWrite(blueLed, HIGH);
digitalWrite(greenLed, HIGH);
delay(250);
digitalWrite(redLed, LOW);
digitalWrite(blueLed, LOW);
digitalWrite(greenLed, LOW);
delay(250);
}
}
void pulseTheBuzzer(void)
{
int melody[] = {
262, 196, 196, 220, 196, 0, 247, 262
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4, 4, 4, 4, 4
};
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(buzzerPin);
}
if(enableSound == true){
delay(400);
//wah wah wah wahwahwahwahwahwah
for(double wah=0; wah<4; wah+=6.541){
playFreq(440+wah, 50);
}
playFreq(466.164, 100);
delay(80);
for(double wah=0; wah<5; wah+=4.939){
playFreq(415.305+wah, 50);
}
playFreq(440.000, 100);
delay(80);
for(double wah=0; wah<5; wah+=4.662){
playFreq(391.995+wah, 50);
}
playFreq(415.305, 100);
delay(80);
for(int j=0; j<7; j++){
playFreq(391.995, 70);
playFreq(415.305, 70);
}
delay(400);
}
else{
delay(1000);
}
}
void loop() {
currentMillis = millis(); //get the current time (number of milliseconds since program started
whackMole();
if (currentMillis - previousMillisRed >= period1 && mole==1) { // check if 1000ms passed
previousMillisRed = currentMillis; // save the last time you blinked the LED
if (ledStatusRed == LOW) { // if the LED is off turn it on and vice-versa
ledStatusRed = HIGH; //change led state for next iteration
} else {
ledStatusRed = LOW;
displayMole();
}
digitalWrite(redLed, ledStatusRed);
previousMillisRed = currentMillis;
prevMole = mole;
}
if (currentMillis - previousMillisGreen >= period1 && mole==2) { // check if 1000ms passed
previousMillisGreen = currentMillis; // save the last time you blinked the LED
if (ledStatusGreen == LOW) { // if the LED is off turn it on and vice-versa
ledStatusGreen = HIGH; //change led state for next iteration
} else {
ledStatusGreen = LOW;
displayMole();
}
digitalWrite(greenLed, ledStatusGreen);
previousMillisGreen = currentMillis;
prevMole = mole;
}
if (currentMillis - previousMillisBlue >= period1 && mole==3) { // check if 1000ms passed
previousMillisBlue = currentMillis; // save the last time you blinked the LED
if (ledStatusBlue == LOW) { // if the LED is off turn it on and vice-versa
ledStatusBlue = HIGH; //change led state for next iteration
} else {
ledStatusBlue = LOW;
displayMole();
}
digitalWrite(blueLed, ledStatusBlue);
previousMillisBlue = currentMillis;
prevMole = mole;
}
/*
if (buttonPushed = true) // check if ISR is called
{
if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed) // generate 20ms debounce delay to avoid multiple presses
{
debounceMillis = currentMillis; // save the last debounce delay time
if (digitalRead(redButton) == HIGH && ledStatusRed == HIGH) // change the led after push button is pressed
{
caughtMoles++;
lcd.setCursor(7,0);
lcd.print(caughtMoles);
ledStatusRed=LOW;
digitalWrite(redLed, ledStatusRed);
buttonPushed = false;
}
}
}
*/
}