-1

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;
    }
}
4
  • Is there any specific reason why you feel you need to use interrupts for the buttons?
    – Majenko
    Jul 16, 2015 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, 2015 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, 2015 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. Jul 16, 2015 at 18:05

1 Answer 1

0
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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