0

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);
 }
}
asked Sep 12, 2018 at 21:22
2
  • 1
    Can you give a link to where you found it on Github? What is <Utility.h>? Is that the game library? Is the function foreach in that library? I'm not sure what you want and I don't know if that is possible. Commented Sep 12, 2018 at 21:52
  • look at all the commands that have anything to do with random numbers ... one of them may be the cause Commented Sep 13, 2018 at 5:30

1 Answer 1

0

The variables butn and old_butn are set to 0 and 100 before the game starts. It's not clear to me what these value represents. But re-assigning the variables back to 0 and 100 whenever the game restarts or resets should fix it.

Maybe at the end of the function game_over(). However it should probably also be done before the call to resetFunc() - whatever that does, its definition is not included.

answered Sep 13, 2018 at 7:17
1
  • Thankyou. I tried that with each one. You were right, both needed to be done. Commented Sep 13, 2018 at 22:38

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.