-1

so I have a project which is to make a simple memory game using Arduino where the LEDs have to blink in a certain pattern and the player has to imitate the same pattern but unfortunately I'm having so much trouble with the code I want to make an if statement to check whether the button was pressed or not if it was it continues to check on the second button and if it wasn't the red led (which means wrong) has to turn on this is how i started:

enter code here


const int button1 = 2;          // 1st button controls Blue LED 
const int button2 = 3;          // 2nd button controls Yellow LED
const int button3 = 4;          // 3rd button controls Green LED
const int button4 = 5;          // 4th button controls Red LED
const int led1 = 7;             // Blue LED
const int led2 = 8;             // Yellow LED
const int led3 = 9;             // Green LED
const int led4 = 10;            // Red LED
const int correctLED = 6;
const int wrongLED = 11;
int val = 0;

// Variables
int buttonState[] = {0,0,0,0};         // current state of the button
int lastButtonState[] = {0,0,0,0};     // previous state of the button
int buttonPushCounter[] = {0,0,0,0}; 



void setup() {
  // initialize inputs :
  randomSeed(analogRead(0));
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);

  // initialize outputs:
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  // initialize serial communication for debugging:
  Serial.begin(9600); 
        }
  }

 void loop() {
       digitalWrite(7, HIGH);
       digitalWrite(8, HIGH);
       digitalWrite(9, HIGH);
       digitalWrite(10, HIGH);
       digitalWrite(7, LOW);
       digitalWrite(8, LOW);
       digitalWrite(9, LOW);
       digitalWrite(10, LOW);

       digitalWrite(7, HIGH);
       delay(500);
       digitalWrite(7,LOW);
       delay(500);
       digitalWrite(8, HIGH);
       delay(500);
       digitalWrite(8,LOW);
       delay(500);
       digitalWrite(9, HIGH);
       delay(500);
       digitalWrite(9,LOW);
       delay(500);
       digitalWrite(10, HIGH);
       delay(500);
       digitalWrite(10,LOW);
       delay(500);


       val = digitalRead(2);  // read input value
       if (val == HIGH) {         // check if the input is HIGH            (button released)
       digitalWrite(wrongLED, LOW);  // turn LED OFF
       } else {
       digitalWrite(wrongLED, HIGH);  // turn LED ON
       }
       val = digitalRead(3);  // read input value
       if (val == HIGH) {         // check if the input is HIGH           (button released)
       digitalWrite(wrongLED, LOW);  // turn LED OFF
       } else {
        digitalWrite(wrongLED, HIGH);  // turn LED ON
       }
       val = digitalRead(4);  // read input value
         if (val == HIGH) {         // check if the input is HIGH (button released)
       digitalWrite(wrongLED, LOW);  // turn LED OFF
       } else {
       digitalWrite(wrongLED, HIGH);  // turn LED ON
       }
       val = digitalRead(5);  // read input value
       if (val == HIGH) {         // check if the input is HIGH (button released)
       digitalWrite(wrongLED, LOW);  // turn LED OFF
       } else {
         digitalWrite(wrongLED, HIGH);  // turn LED ON
       }
       digitalWrite(correctLED, HIGH);

       }
       }
5
  • Do yourself a favour and learn how to indent your code properly.
    – Majenko
    Apr 27, 2016 at 9:29
  • As for your problem: think passwords.
    – Majenko
    Apr 27, 2016 at 9:29
  • 1
    You can automatically format your code in the Arduino IDE by going into the "Tools" menu and selecting "Auto Format."
    – sa_leinad
    Apr 27, 2016 at 10:34
  • You have too many closing braces.
    – sa_leinad
    Apr 27, 2016 at 10:36
  • Downvoted because you didn't say what problem you're having.
    – per1234
    Dec 24, 2016 at 4:58

3 Answers 3

2

For this kind of thing you don't really want to be worrying about "is this button and then this button pressed" etc. That thinking is very much "of the moment" in that it is all about what is happening now - not what has gone on in the past.

You need to be thinking about the sequence of button presses that you have seen so far - not what is happening right now.

Say you have three buttons. Let's assign a number to each of them - say they are buttons 1, 2 and 3.

And you have 3 LEDs - let's call them A, B and C.

So you light and extinguish the LEDs in a specific order, say BAC, and you expect the buttons to be pressed in the same order - 213.

You can't be checking all the time for "If 2 is pressed then 1 is pressed then 3 is pressed" because, basically, where are you in that sequence at any one instance in time? Instead you need to go: "A button has been pressed. I'll store that fact." And then: "Have three buttons been pressed? Yes. Do their numbers match?"

Basically like a PIN code for your bank card, or a password for your computer. It's not what you are pressing now, it's what it remembers you pressing in the past.

And the simplest way of doing that is to literally allocate numbers to the buttons. When a button is pressed you assign a number representing that button to a variable. Then append that number to the list of numbers you have seen recently. When that list is the right length you compare it. Just like entering a password.

You can even compare what you have so far with a portion of what you expect to catch incorrect presses early.

So say you have an expected value of "213" stored in a string. You also have an empty string. When you press a button you append that number to the string - so say you press "212" you could then append and compare the string like this:

Button  Input  Expected
2       2      2         Correct
1       21     21        Correct
2       212    213       Incorrect - erase input content
2       2      2         Correct
1       21     21        Correct
3       213    213       Correct - next round please.
2

Format and extra braces aside there are other issues with your code, too many to fit in a comment.

  1. You have used led1, led2 etc in the setup routine and the resorted to numbers in the loop function.

  2. At the start of loop() you turn the leds high then low, you won't see this because the processor is faster than your eye, you need a delay statement after the last high and last low.

  3. You can make you code more elegant by writing a function that takes the pin as a parameter and toggles the led high then low and call this rather than repeating 4 lines of code.
void togglePin(int pinNumber, int interval)
{ 
   digitalWrite(pin, HIGH);
   delay(interval);
   digitalWrite(pin, LOW);
   delay(interval);
}
  1. When it comes to reading values you have blocks of repeated code, again these could be a separate function, which will make your code easier to read and understand.

When you have done that you might want to so a bit of research on 'switch debouncing' because I'm guessing you might have issues with that too.

1

Your code as written will have both the wrongLED and correctLED on. It will also continuously loop showing the sequence.

Showing the Sequence

To show the sequence once at the start, put it in the setup function. Read more about the setup function here: http://www.arduino.cc/en/Reference/Setup

Detecting the Button Presses

You want to detect each press of the buttons. For this you will need edge detection code. There is an Arduino example built into the IDE and information describing the function here: http://www.arduino.cc/en/Tutorial/StateChangeDetection
To add to the Arduino explanation, you can either detect the rising edge (ie. the transition from a LOW to a HIGH) or the falling edge (ie. the transition from a HIGH to a LOW). I personally prefer the following code to detect a rising edge:

if ( (lastButtonState == LOW) && (buttonState == HIGH) )

where buttonState would be assigned by a digitalRead and lastButtonState would record the value of buttonState at the end of the loop function (ie. just before it reads in the button states again).

Using your global arrays you could write:

buttonState[0] = digitalRead(button1);
buttonState[1] = digitalRead(button2);
buttonState[2] = digitalRead(button3);
buttonState[3] = digitalRead(button4);

if ( (lastButtonState[i] == LOW) && (buttonState[i] == HIGH) )

where i is a number between 0 and 3. You could use a for loop to cycle through the 4 available buttons.

Recording the Button Presses

The StateChangeDetection example above counts the number of button presses. Instead, you want to record 4 button presses. To do this create a global variable called pressNumber. Create it with the initial value of 0.

Create an integer array of 4 elements called `userSequence'.

Every time the if statement detects a rising edge, store the button number in the userSequence' at positionpressNumberand then increment thepressNumber`.

When pressNumber reaches 4, the user has entered his/her guess.

Evaluating the Guess

This only occurs once the user has entered the guess. Start off by creating a boolean variable and assign it TRUE. Cycle through the elements in the userSequence array and compare the users guess to the correct answer. If the user gets one wrong set the boolean variable to false. At the end, turn on the red LED or green LED depending on the state of the boolean variable (ie. if it is true turn on the green LED, otherwise turn on the red).

Final Notes

  • As Matt suggests, try refactoring portions of code into functions. It makes the code more readable and reduces the complexity of the code.
  • You can use the variables for the pin numbers of the buttons and LEDs in the digitalWrite and digitalRead functions. Eg:

    digitalRead(button1); digitalWrite(led1);

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.