Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a group project where we are trying to make a user enter a password that we have pre-selected for them. They enter the password using tactile buttons, and they have 5 tries to enter the password correctly. If they enter the password incorrectly, one of 5 LED's will light up to indicate that they have entered it wrong. If they get it right, one LED will light up.

We are using timers to time out the attempt if the users take too long to enter the entire password, or if they take too long between pressing buttons. Also, if they use all 5 tries, we are trying to make the LED's that were on turn off one by one.

Right now the code doesn't get past Serial.print("done").

This is our code:

int input_pin_blue = 5;
int input_pin_yellow = 6;
volatile int state_button_red = LOW;
volatile int state_button_blue = LOW;
volatile int state_button_yellow = LOW;
int num_wrong = 0;
double time_between_buttons = 0;
double time_since_first_button = 0;
const int max_time_between_buttons = 10000;
const int max_time_since_first_button = 30000;
int reset = 4;
void setup() {
    pinMode(input_pin_blue, INPUT);
    pinMode(input_pin_yellow, INPUT);
    pinMode(4, INPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
    attachInterrupt(0, handler_red, CHANGE);
    attachInterrupt(1, handler_blue_yellow, CHANGE);
    Serial.begin(9600);
}
void loop() {
    Serial.print("bhi"); //wait for button press

    for (num_wrong = 0; num_wrong < 5; num_wrong++) {
        Serial.print("blah"); //wait for button press

        while (state_button_red == LOW && state_button_blue == LOW && state_button_yellow == LOW) {
            Serial.print("waiting"); //wait for button press
        }

        Serial.print("DOne");

        if (state_button_red == LOW) {                  //check if first button pressed is incorrect
            digitalWrite(num_wrong + 8, HIGH);
        } else if (state_button_red == HIGH) {
            time_between_buttons = millis();
            time_since_first_button = millis();

            while (state_button_red == LOW && state_button_blue == LOW && state_button_yellow == LOW
                    && time_between_buttons < max_time_between_buttons && time_since_first_button < max_time_since_first_button) {
                //wait for button press
            }

            if (state_button_yellow == LOW || time_between_buttons < max_time_between_buttons || time_since_first_button < max_time_since_first_button)
//check if second button pressed is incorrect or time has run out
            {
                digitalWrite(num_wrong + 8, HIGH);
            } else if (state_button_yellow == HIGH) {
                time_between_buttons = millis();

                while (state_button_red == LOW && state_button_blue == LOW && state_button_yellow == LOW
                        && time_between_buttons < max_time_between_buttons && time_since_first_button < max_time_since_first_button) {
                    //wait for button press
                }

                if (state_button_blue == LOW || time_between_buttons < max_time_between_buttons || time_since_first_button < max_time_since_first_button)
//check if third button pressed is incorrect or time has run out
                {
                    digitalWrite(num_wrong + 8, HIGH);
                } else if (state_button_blue == HIGH) {
                    time_between_buttons = millis();

                    while (state_button_red == LOW && state_button_blue == LOW && state_button_yellow == LOW
                            && time_between_buttons < max_time_between_buttons && time_since_first_button < max_time_since_first_button) {
                        //wait for button press
                    }

                    if (state_button_yellow == LOW || time_between_buttons < max_time_between_buttons || time_since_first_button < max_time_since_first_button)
//check if fourth(last) button pressed is incorrect or time has run out
                    {
                        digitalWrite(num_wrong + 8, HIGH);
                    } else if (state_button_yellow == HIGH) {
                        digitalWrite(13, HIGH);
                        num_wrong = 10;
                    }
                }
            }
        }
    }

    if (num_wrong == 10) {
        while (digitalRead(reset) == LOW) {
            //wait for reset
        }
    } else if (num_wrong == 5) {
        while (digitalRead(reset) == LOW) {
            digitalWrite(8, LOW);
            delay(100);
            digitalWrite(8, HIGH);
            digitalWrite(9, LOW);
            delay(100);
            digitalWrite(9, HIGH);
            digitalWrite(10, LOW);
            delay(100);
            digitalWrite(10, HIGH);
            digitalWrite(11, LOW);
            delay(100);
            digitalWrite(11, HIGH);
            digitalWrite(12, LOW);
            delay(100);
            digitalWrite(12, HIGH);
        }
    }

    if (digitalRead(reset) == HIGH) {
        digitalWrite(13, LOW);
        delay(100);
        digitalWrite(12, LOW);
        delay(100);
        digitalWrite(11, LOW);
        delay(100);
        digitalWrite(10, LOW);
        delay(100);
        digitalWrite(9, LOW);
        delay(100);
        digitalWrite(8, LOW);
    }
}
// interrupt handler function
void handler_red() {
    state_button_red = !state_button_red;
}
void handler_blue_yellow() {
    if (digitalRead(input_pin_blue) == HIGH) {
        state_button_blue = !state_button_blue;
    }

    if (digitalRead(input_pin_yellow) == HIGH) {
        state_button_yellow = !state_button_yellow;
    }
}
share|improve this question
    
Is there any specific reason why you feel you need to use interrupts for the buttons? – Majenko Jul 16 '15 at 9:23
    
@Majenko it's just one of the requirements for the project that we use 3 interrupts and 2 timers – EmilyF Jul 16 '15 at 15:12
    
Ok, that's fair enough. So it's for the purpose of learning how they work, which is good. – Majenko Jul 16 '15 at 15:13
    
I understand that you have to use timers, however, just as comment, if you didn't have such constraint, I think it would be far simpler (and efficient) to define a state machine which reacts exclusively to button presses. When a button is pressed, it checks the time elapsed from the previous button event and acts accordingly. – Igor Stoppa Jul 16 '15 at 18:05
int input_pin_blue = 5;
int input_pin_yellow = 6;
volatile int state_button_red = LOW;
volatile int state_button_blue = LOW;
volatile int state_button_yellow = LOW;
...
pinMode(input_pin_blue, INPUT);
pinMode(input_pin_yellow, INPUT);
...
attachInterrupt(0, handler_red, CHANGE);
attachInterrupt(1, handler_blue_yellow, CHANGE);


// interrupt handler function
void handler_red() {
    state_button_red = !state_button_red;
}
void handler_blue_yellow() {
    if (digitalRead(input_pin_blue) == HIGH) {
        state_button_blue = !state_button_blue;
    }

    if (digitalRead(input_pin_yellow) == HIGH) {
        state_button_yellow = !state_button_yellow;
    }
}

On the Uno external interrupt 0 is pin D2 not D5, and interrupt 1 is pin D3, not D6.

Hence you are not testing the correct pins.

Also I would use INPUT_PULLUP instead of INPUT mode for those pins, unless you have external pull-up or pull-down resistors on them.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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