I got the following code from Github, and have been playing with it for the last couple months. The loop ALWAYS begins with the same LED as long as you do a complete reset to the board or power it up. If I press the start button (I added) after running the loop previously, a different LED typically will fire. I want to have the same led to start every loop, ALL the time (reset, power up, AND start button).
My current breadboard setup is an Arduino Mega, using a 4x4 matrix for the buttons and the LEDS to some digital outs. I currently am using 6 LEDS but plan to expand to several more when I get everything working where I want it.
A quick rundown of how this functions... At power up the LCD read out says Kyndras reaction timer. If the start button is pressed a countdown begins and the first led lights up (LED 2), when the corresponding button is pressed another led lights until that corresponding button is pressed, etc. The game runs for 30 seconds, at the end of the game your score is shown. At that point you can simply press start to do it again. My current issue is, I want LED "2" to be the first one to fire when the next game starts. I know there is something retaining memory, because when you watch the last light power on a second before the timer ends, it lights the same light for a fraction of a second on the next game.
I suspect (old_butn = 0;) is my issue. I have tried moving it all over the sketch and tried changing the digit after it, but I haven't had much luck.
I'm hoping someone can point me in the right direction.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Utility.h>
#include "tones.h" // file music, lies in the folder firmware
#define GAMETIME 30000
#define LAMP 6
#define RES_KEY 15
#define BUZZER_PIN 19
#define BLINK 40
LiquidCrystal_I2C lcd(0x3F, 20, 4);
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'<', '8', '4', '0'},
{'=', '9', '5', '1'},
{'>', ':', '6', '2'},
{'?', ';', '7', '3'}
};
byte colPins[ROWS] = {39, 37, 35, 33};
byte rowPins[COLS] = {41, 43, 45, 47};
boolean lamp_on[6];
boolean steps = true, go_game = true;
int lamp_pin[15] = {2, 3, 4, 5, 6, 7};
unsigned long startTime [12] = { 0, 0, 0, 0 };
unsigned long duration [12] ;
const int buttonPin = 14;
const int startPin = 8;
long last_pressed = 0;
long nowMillis = 0;
long toSec = 0;
long gameStart = 0;
long toBlink = 0;
int score = 0;
int dlay = 1000;
int butn = 0;
int old_butn = 100;
char customKey;
int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 };
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
//=====================================
void(* resetFunc) (void) = 0;
//=====================================
void setup()
{
randomSeed(analogRead(0));
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(startPin, OUTPUT);
tone(BUZZER_PIN, 5000, 500);
foreach (lamp_pin, LAMP, pinMode, OUTPUT);
foreach (lamp_pin, LAMP, digitalWrite, HIGH);
foreach (lamp_pin, LAMP, digitalWrite, LOW);
delay(500);
lcd.init();
lcd.backlight();
lcd.setCursor(4, 0);
lcd.print("ver 3.5");
lcd.setCursor(0, 2);
lcd.print("KYNDRAS REACTION");
lcd.setCursor(6, 3);
lcd.print("GAME");
}
//=====================================
void loop()
{
//******* allows a reset at anytime within the loop
customKey = customKeypad.getKey();
if (customKey - 48 == RES_KEY) {
go_game = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RESTART!");
delay(500);
resetFunc();
}
//******* shit gets real
if (digitalRead(startPin) == HIGH)
{
foreach (lamp_pin, LAMP, digitalWrite, LOW);//makes all leds go LOW after randomBlink
countDown();
//-------
gameStart = millis();
nowMillis = gameStart;
score = 0;
steps = true;
go_game = true; //this line allows you to start w/o reset
while ((nowMillis - gameStart < GAMETIME) and (go_game)) {
nowMillis = millis();
//**********
if (nowMillis - toSec > 1000) {
lcd_print();
toSec = nowMillis;
}
//**********
if (nowMillis - toBlink > BLINK) {
if (lamp_on[old_butn]) {
sw_led_off(old_butn);
}
else {
sw_led_on(old_butn);
}
toBlink = nowMillis;
}
//**********
if (steps) {
while (old_butn == butn) {
butn = random(LAMP);
}
sw_led_off(old_butn);
old_butn = butn;
sw_led_on(butn);
steps = false;
}
//**********
customKey = customKeypad.getKey();
if (customKey) Serial.println((int)customKey);
if (customKey - 48 == butn) {
sw_led_off(customKey - 48);
score++;
steps = true;
lcd_print();
} else if (customKey - 48 == RES_KEY) {
gameStart = millis();
foreach (lamp_pin, LAMP, digitalWrite, LOW);
score = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RESTART!");
delay(500);
resetFunc();
}
}
if (go_game) game_over(); // the game is over
go_game = false;
}
//******** random blink
for (int i = 0; i < 6; i++)
{
randomBlink(i);
}
}
//=====================================
void lcd_print() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TIME:");
int time = GAMETIME / 1000 - (nowMillis - gameStart) / 1000;
lcd.print(time);
if (time < 11) {
tone(BUZZER_PIN, 3500 + time * 300, 150);
}
lcd.setCursor(11, 0);
lcd.print("BTN:");
lcd.print(customKey);
lcd.setCursor(0, 2);
lcd.print("SCORE:");
lcd.print(score);
}
//=====================================
void game_over() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" END");
lcd.setCursor(0, 2);
lcd.print(" SCORE: ");
lcd.print(score);
foreach (lamp_pin, LAMP, digitalWrite, HIGH);//all lamps light for 2sec at end of game
delay (2000);
for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000 / noteDurations[thisNote];
tone(BUZZER_PIN, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(BUZZER_PIN);
}
}
//=====================================
void sw_led_on(int num) {
digitalWrite(lamp_pin[num], 1);
lamp_on[num] = 1;
}
//=====================================
void sw_led_off(int num) {
digitalWrite(lamp_pin[num], 0);
lamp_on[num] = 0;
}
//=====================================
void randomBlink(int pin)
{
if (millis() - startTime[pin] >= duration[pin])
{
digitalWrite(lamp_pin[pin], !digitalRead(lamp_pin[pin]));
duration[pin] = random(150, 1500); //smallest and longest ON/OFF times.
startTime[pin] = millis();
}
}
//=======================================
void countDown() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" GET READY");
delay(500);
lcd.setCursor(0, 2);
lcd.print(" START IN 3...");
tone(BUZZER_PIN, 4000, 200);
delay(500);
lcd.setCursor(0, 2);
lcd.print(" START IN 2...");
tone(BUZZER_PIN, 4500, 200);
delay(500);
lcd.setCursor(0, 2);
lcd.print(" START IN 1...");
tone(BUZZER_PIN, 5000, 200);
delay(500);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" GO!");
delay(250);
for (int i = 0; i < 5; i++) {
int frequency = 4000 + i * 300;
tone(BUZZER_PIN, frequency, 150);
delay(130);
}
}
foreach
in that library? I'm not sure what you want and I don't know if that is possible.