Greetings everyone!
I am very new to the forum - pleased to meet you!
So please excuse my (probably) very stupid question.
I am also new to using Ardsuino's and sketches.
Anyway, here comes the question:
I have been building a Geocache that incorporates a Simon Says game that you need to overcome in order to open the compartment where the log is held in.
I downloaded the sketch I needed from a website that tells you how to build one of these caches.
His cache was made to work with a 9v battery that a cacher needs to bring.
However I decided to install an adapter that provides continues power to the Arduino/cache.
This presents me with a problem as the game will present the player with 4 tones and some flashing lights behind the buttons to initiate play.
Since my version of the cache is connected to continuous power the cache keeps playing those 4 sounds over and over.
This will drive me and the neighbours crazy since the cache is hanging on the side of my garage.
I could install a refridgerator light switch to provide the cache with power as soon as the player opens the case but I was wondering if the issue could be tackled in the code?
Perhaps someone has a nice solution as to how I could solve the issue of the flashing lights and the beeping of the speaker untill the player starts to play.
Maybe just remove that aspect of the game, but I am afraid I am not knowledgeable enough to know what exactly to remove.
Any help would be greatly appreciated - thank you very much for taking the time to read my question and possibly help me solve this issue.
To give you an understanding of the workings of the cache, a Youtube movie about it can be found here: https://www.youtube.com/watch?v=fp8XLRejD4g
The website where the idea was taken from can be found here:
Here's the actual code:
/**
* GC9GNKE - "Tens boa memoria ??
* Algum codigo foi tirado (exemplos) do tutorial da Sparkfun:
*
*/
#include <Servo.h>
#include "pitches.h"
//trocar para 0 para desativar debugging
//trocar para 1 para ativar debugging
#define DEBUG 0
#define BUZZER 12
#define SERVO 3
Servo myservo;
#define soundButtonTop 262
#define soundButtonLeft 330
#define soundButtonBottom 392
#define soundButtonRight 494
int soundsArray[4] = {soundButtonTop,soundButtonLeft, soundButtonBottom,soundButtonRight};
/*
* Definitions for buttons and leds
*/
#define ledTop 11
#define ledLeft 10
#define ledBottom 9
#define ledRight 8
int ledsArray[4] = {ledTop, ledLeft, ledBottom, ledRight};
//buttons definitions
#define buttonTop 7
#define buttonLeft 6
#define buttonBottom 5
#define buttonRight 4
#define NO_BUTTON 0
int buttonsArray[4] = {buttonTop, buttonLeft, buttonBottom, buttonRight};
/**
* Program variables
*/
// Numero de nivels que o utilizador tem que fazer
// para ganhar
// vamos apenas usar 5 dos 6 que temos definidos
#define NUM_LEVELS 5
//tempo (milisegundos - 3 segundos) que o geocacher tem para pressionar o botao
#define BUTTON_TIMEOUT 3000
#define ledReady 13
//current level
int curLevel = 0;
/**
* definicao de tempos para os LEDs acenderem e desligaram
* Nivel mais altos, menos tempo para mostrar
* 2s, 1,5s, 900ms, 700ms, 600ms, 500ms -
*/
//Para 6 niveis
//int timeLevels[NUM_LEVELS] = {1000, 900, 750, 650, 600, 500};
//Para 5 niveis
int timeLevels[NUM_LEVELS] = {1000, 900, 750, 650, 600};
/**
* Tamanho das sequencias para memorizar e repetir
* Mais alto o nivel, maior a sequencia a memorizar
* Primeiro nivel acende 4 botoes
* Segundo nivel, acende 5 botoes e assim sucessivamente.
* 4, 5, 6, 7, 8, 10
*/
//Para 6 niveis
//int sequences[NUM_LEVELS] = {4, 5, 5, 6, 7, 8};
// Para 5 niveis
int sequences[NUM_LEVELS] = {4, 5, 5, 6, 7};
long debounceDelay = 200; // tempo para "deixar de saltar". aumentar se botao regista mais que uma vez
void setup() {
// put your setup code here, to run once:
//LED PINS
for (int i = 0; i < 4; i++)
pinMode (ledsArray[i], OUTPUT);
//led Ready
pinMode (ledReady, OUTPUT);
//Button PINS
for (int i = 0; i < 4; i++)
pinMode (buttonsArray[i], INPUT_PULLUP);
// Servo
myservo.attach(SERVO);
//Serial port
Serial.begin(115200);
initializeLeds();
delay(3000);
}
/*
* Just show off a animation for startup
*/
void initializeLeds() {
int delay_timer = 100;
for (int i = 0; i < 4; i++) {
digitalWrite (ledsArray[i], HIGH);
delay(delay_timer);
digitalWrite (ledsArray[i], LOW);
}
}
void loop() {
//play something a do something
//until user presses a key to start the game.
flashLevelWaiting();
delay(2000); //esperar 2s ate comecar o jogo
//when ready, if return 0 is not ok
//return 1, win and play sound
if (playMemoryGame()) {
//play vitory
if (DEBUG) Serial.println("A tocar vitoria...");
playVencedor();
delay(1000);
//open door
if (DEBUG) Serial.println ("Opening logbook door");
myservo.write(170);
//indicar que ja podem abrir a porta
showOpenLogBook();
//wait 5s
delay(5000);
//put in normal position
if (DEBUG) Serial.println ("Closing logbook door");
myservo.write(90);
//wait until a button is pressed
do {} while (!getButton());
delay(100);
}
else {
//play gameover
if (DEBUG) Serial.println("Perdeu....");
playGameOver();
delay (1000);
}
//reset game levels
curLevel = 0;
}
boolean playMemoryGame () {
//lets randomize
for (int z = 0; z < NUM_LEVELS; z++) {
Serial.println("Current Level: " + String(curLevel));
/*
* create array with current level sequences
* Just create an array -
* Sequences is the number of buttons to press from memory
* curLevel is current level - current level will
* be the index in the sequences array - the more high in the level
* the more button presses will have to remember
*/
int flashArray[sequences[curLevel]];
/*
//fill the array with random Leds
for (int y = 0; y < sequences[curLevel]; y++)
flashArray[y] = ledsArray[random(0,3)];
*/
randomizeGame (flashArray, sequences[curLevel]);
//call the function that will light up the leds
showLevel (flashArray);
readyLevel(); //mostrar ao jogador que pode pressionar botoes
if (DEBUG) Serial.println ("Waiting for user");
//now, let's match the pressed buttons with the game
if (!parseUserLevel(flashArray)) {
//User missed something, ending game
if (DEBUG) Serial.println(" Gameover");
return 0;
}
//Estamos aqui, o utilizador acertou todos os botoes
//esperar 1s ate ao proximo nivel
delay(1000);
curLevel += 1;
if (DEBUG) Serial.println("Next Level: " + String(curLevel));
}
//if we got here, winner
return 1;
}
void randomizeGame (int flashArray[], int arraySize) {
//make sure this is really random
randomSeed(analogRead(A0));
//fill the array with random Leds
for (int y = 0; y < arraySize; y++)
flashArray[y] = ledsArray[random(0,4)];
}
/**
* Function show the random LEDs according with the Arrays
* playLevel - show what buttons user must press
*
*/
void showLevel (int flashArray[]) {
//lets light up some leds
for (int x = 0; x < sequences[curLevel]; x ++) {
Serial.print(String(flashArray[x]) + " ");
//digitalWrite (flashArray[x], HIGH);
tonner (flashArray[x]);
delay(timeLevels[curLevel]);
//digitalWrite (flashArray[x], LOW);
delay(timeLevels[curLevel]);
}
}
/*
* Function to get what button was pressed
*/
int getButton () {
long startTime = millis();
//get what button was pressed and return it
// we return the pin number - it's the same on the array
while ( (millis() - startTime) < BUTTON_TIMEOUT) {
if (digitalRead(buttonTop) == 0) return (ledTop);
else if (digitalRead(buttonLeft) == 0) return (ledLeft);
else if (digitalRead(buttonRight) == 0) return (ledRight);
else if (digitalRead(buttonBottom) == 0) return (ledBottom);
}
return 0;
}
/*
* parse user input for current level
* Every button in presses, we will check if is the same on the array
* If it fails, return 0
*/
int parseUserLevel (int flashArray[]) {
int numPressButtons = 0;
while (numPressButtons < sequences[curLevel]) {
long startTime = millis();
int button = getButton();
if (DEBUG) Serial.println("Button pressed: " + String(button));
if (button != NO_BUTTON) {
//play music
tonner (button);
if (DEBUG) Serial.println("Button pressed inside: " + String(button));
delay (debounceDelay); //debounce to prevent multiple presses
//check if button pressed is the same as in the array
if (button == flashArray[numPressButtons]) {
if (DEBUG) Serial.println ("corret button");
//next button
numPressButtons++;
if (DEBUG) Serial.println("numPress: " + String(numPressButtons));
setLedsPressed (NO_BUTTON);
continue; //advance next
}
if (DEBUG) Serial.println("Error button");
return 0;
} //end if button
if (DEBUG) Serial.println("TIMEOUT");
return 0;
}
//we got here, user got them right
return 1;
}
//light up the LED of the button pressed
void setLedsPressed(int buttonPressed) {
if (buttonPressed == ledTop)
digitalWrite (ledTop, HIGH);
else
digitalWrite (ledTop, LOW);
if (buttonPressed == ledLeft)
digitalWrite (ledLeft, HIGH);
else
digitalWrite (ledLeft, LOW);
if (buttonPressed == ledBottom)
digitalWrite (ledBottom, HIGH);
else
digitalWrite (ledBottom, LOW);
if (buttonPressed == ledRight)
digitalWrite (ledRight, HIGH);
else
digitalWrite (ledRight, LOW);
}
void play (long note, int duration = 150) {
tone (BUZZER,note,duration);
delay (1+duration);
}
void tonner (int buttonPressed) {
//light leds
setLedsPressed (buttonPressed);
switch (buttonPressed) {
case ledTop:
play (soundButtonTop);
break;
case ledLeft:
play (soundButtonLeft);
break;
case ledBottom:
play (soundButtonBottom);
break;
case ledRight:
play (soundButtonRight);
break;
}
setLedsPressed(0);
}
// Mostra um modo descontraido ate que estejam prontos a jogar.
void modoDistrair(void) {
while(1) {
setLedsPressed(ledTop);
delay(10);
if (getButton() != NO_BUTTON) break;
setLedsPressed(ledLeft);
delay(10);
if (getButton() != NO_BUTTON) break;
setLedsPressed(ledBottom);
delay(10);
if (getButton() != NO_BUTTON) break;
setLedsPressed(ledRight);
delay(10);
if (getButton() != NO_BUTTON) break;
}
setLedsPressed(0); //desliga os LEDs
}
//GameOver
void playGameOver() {
int pressedButton;
//turn all the LEDs on
for (int j = 0; j <= 3; j++) {
digitalWrite(ledsArray[j], HIGH);
}
tone(BUZZER, 130, 250); //E6
delay(275);
tone(BUZZER, 73, 250); //G6
delay(275);
tone(BUZZER, 65, 150); //E7
delay(175);
tone(BUZZER, 98, 500); //C7
delay(500);
delay(200);
setLedsPressed(0);
}
//
void playVencedor() {
//turn all the LEDs on
for (int j = 0; j <= 3; j++) {
digitalWrite(ledsArray[j], HIGH);
}
for (int d = 0; d < 3; d++) {
//play the 1Up noise
tone(BUZZER, 1318, 150); //E6
delay(175);
tone(BUZZER, 1567, 150); //G6
delay(175);
tone(BUZZER, 2637, 150); //E7
delay(175);
tone(BUZZER, 2093, 150); //C7
delay(175);
tone(BUZZER, 2349, 150); //D7
delay(175);
tone(BUZZER, 3135, 500); //G7
delay(500);
}
delay(100);
}
/*
* Esta funcao vai acender todos os leds
* para indicar que esta a espera
*/
void flashLevelWaiting () {
while (1) {
//flash all of the LEDs when the game starts
for (int i = 0; i <= 3; i++) {
tone(BUZZER, soundsArray[i], 200); //play one of the 4 tones
//turn all of the leds on
digitalWrite(ledsArray[0], HIGH);
digitalWrite(ledsArray[1], HIGH);
digitalWrite(ledsArray[2], HIGH);
digitalWrite(ledsArray[3], HIGH);
delay(100); //wait for a moment
//turn all of the leds off
digitalWrite(ledsArray[0], LOW);
digitalWrite(ledsArray[1], LOW);
digitalWrite(ledsArray[2], LOW);
digitalWrite(ledsArray[3], LOW);
delay(100); //wait for a moment
}//this will repeat 4 times
if (getButton() != NO_BUTTON) return;
}
}
/*
* Funcao para mostrar ao utilizador
* que estamos prontos para aceitar os inputs
*/
void readyLevel () {
digitalWrite (ledReady, HIGH);
tone (BUZZER, NOTE_CS6, 150);
delay(100);
digitalWrite (ledReady, LOW);
}
/*
* Funcao que mostra que podemos abrir o logbook
*/
void showOpenLogBook() {
for (int z=0; z < 10; z++) {
digitalWrite (ledReady, HIGH);
tone (BUZZER, NOTE_DS5, 100);
delay(50);
digitalWrite (ledReady, LOW);
delay(50);
}
}