How to read input buttons during two frequencies tone loop.

Hi!

This is my first message on this forum. I hope to do it right...

I'm trying to do an alarm that should trigger a buzzer when a wire is cut or disconnected.

The alarm is connected and disconnected introducing a password with two push buttons. There is a green LED to indicate that the alarm is activated and a red LED to indicate that the password is not correct. The schematic of the wiring is attached.

It works fine, but I can't make that the buzzer to iterate alternatively with two frequencies with the tone() function. If I do so with a while, the processor is trapped in the while loop and can't listen to the inputs of the push buttons. I tried to call a digitalRead() inside the loop and also to use pointers, but I can't make it work.

The code is the following. It's based on a code posted here.

const int button1 = 2; //pushbutton1 on pin 3
const int button2 = 3; //pushbutton2 on pin 2
const int connector = 4; //pushbutton3 on pin 4 (this is going to be a connector in the future)

const int Red = 11; //red LED is on pin 11
const int greenLed = 10; //green LED is pin 10
const int buzzer = 13; //buzzer pin is 13
void checkEntered1(int button);
void activateAlarm(int * alarmActive);

int code[] = {1, 2, 2, 1, 1, 1}; //the desired code is entered in this array,
//separated by commas

int entered[7]; //create a new empty array for the code entered by
//the user (has 4 elements)

int alarmActive = 0; //variable to check if the alarm is activated

void setup() { //run once at sketch startup
  Serial.begin(9600); //begin Serial

  pinMode(button1, INPUT_PULLUP); //button 1 is an input
  pinMode(button2, INPUT_PULLUP); //button 2 is an input
  pinMode(connector, INPUT_PULLUP); //button 3 is an input
  pinMode(Red, OUTPUT); //the red LED is an output
  pinMode(greenLed, OUTPUT); // the green LED is an output
  pinMode(buzzer, OUTPUT); //initialize the buzzer pin as an output

}

void loop() { //run repeatedly

  //en cas que l'alarma estigui
  if (alarmActive == 1) {

    if (digitalRead(connector) == HIGH) {
      Serial.println("Buzzer activated");
      activateAlarm(alarmActive);
    }

  }
  if (digitalRead(button1) == LOW) { //if button1 is pressed
    checkEntered1(1); //call checkEntered and pass it a 1

    delay(250);//wait, needed for correct functioning, otherwise
    //buttons are deemed to be pressed more than once

  }
  else if (digitalRead(button2) == LOW) { //if button2 is pressed
    checkEntered1(2); //call checkEntered1 and pass it a 2

    delay(250); //wait

  }


}

void checkEntered1(int button) { //check the first element of the entered[] array
  if (entered[0] != 0) { //if it is not a zero, i.e. it has already been inputted
    checkEntered2(button); //move on to checkEntered2, passing it "button"
  }

  else if (entered[0] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[0] = button; //set the first element as the button that has been pressed
    Serial.print("1: "); Serial.println(entered[0]); //for debugging
  }

}

void checkEntered2(int button) { //check the second element of the entered[] array
  if (entered[1] != 0) { //if it is not a zero, i.e. it has already been inputted
    checkEntered3(button); //move on to checkEntered3, passing it "button"
  }

  else if (entered[1] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[1] = button; //set the second element as the button that has been pressed
    Serial.print("2: "); Serial.println(entered[1]); //for debugging
  }

}

void checkEntered3(int button) { //check the third element of the entered[] array
  if (entered[2] != 0) { //if it is not a zero, i.e. it has already been inputted
    checkEntered4(button); //move on to checkEntered4, passing it "button"
  }

  else if (entered[2] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[2] = button; //set the third element as the button that has been pressed
    Serial.print("3: "); Serial.println(entered[2]); //for debugging
  }

}

void checkEntered4(int button) { //check the third element of the entered[] array
  if (entered[3] != 0) { //if it is not a zero, i.e. it has already been inputted
    checkEntered5(button); //move on to checkEntered4, passing it "button"
  }

  else if (entered[3] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[3] = button; //set the third element as the button that has been pressed
    Serial.print("4: "); Serial.println(entered[3]); //for debugging
  }

}


void checkEntered5(int button) { //check the third element of the entered[] array
  if (entered[4] != 0) { //if it is not a zero, i.e. it has already been inputted
    checkEntered6(button); //move on to checkEntered4, passing it "button"
  }

  else if (entered[4] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[4] = button; //set the third element as the button that has been pressed
    Serial.print("5: "); Serial.println(entered[4]); //for debugging
  }

}

void checkEntered6(int button) { //check the fourth element of the entered[] array
  if (entered[5] == 0) { //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[5] = button; //set the final element as the button that has been pressed
    Serial.print("6: "); Serial.println(entered[5]); //for debugging
    delay(100); //allow time for processing
    compareCode(); //call the compareCode function
  }
}
void activateAlarm(int alarmActive) {
int periodo = 1000;
unsigned long TiempoAhora = 0;

    tone(buzzer, 2000);
    delay(1000);
    tone(buzzer, 500);
    delay(1000);
  }
void compareCode() { //checks if the code entered is correct by comparing the code[] array with the entered[] array

  if ((entered[0] == code[0]) && (entered[1] == code[1]) && (entered[2] == code[2]) && (entered[3] == code[3]) && (entered[4] == code[4]) && (entered[5] == code[5])) { //if all the elements of each array are equal

    if (alarmActive == 1) { //Check if alarm is activated
      digitalWrite(greenLed, LOW); // turn the gren LED off
      alarmActive = 0;
      noTone(buzzer); 
      Serial.println("Alarm Deactivated");
      delay(250);
    }
    else {
      digitalWrite(greenLed, HIGH); //turn the green LED on
      Serial.println("Alarm Activated");
      alarmActive = 1;
      delay(250);
    }





    for (int i = 0; i < 7; i++) { //this next loop is for debugging
      entered[i] = 0;

    }

    loop(); //return to loop() (not really necessary)
  }

  else { //if you (or the intruder) get the code wrong

    digitalWrite(Red, HIGH);
    delay(1000);
    Serial.println("Wrong PassWord");
    digitalWrite(Red, LOW);

    for (int i = 0; i < 7; i++) { //this next loop is for debugging
      entered[i] = 0;

    }

  }
}

Hi!

After thinking further, I reply to myself: Nil, you should try a diferent programing approach taking into account that the processor is already looping. Try something like this....Hehe

I'm going to upload the code as soon as I finish it, as well as the full project. Maybe it can help someone.

Cheers!

Hello Nilsuria, welcome to the forum.

I hope to do it right...

I wish all new folk here were as diligent! You did it right, ++Karma; for using code tags on your first post and generally getting it right.

After thinking further, I reply to myself: Nil, you should try a different programming approach taking into account that the processor is already looping.

Correct. while(); should be used very carefully; generally only for things where you can be sure the processor will not get stuck in the while() loop for ages.
To a lesser extent the same precaution should be taken with for(), although that usually has a natural end time built in to the conditions (but not always).

Good luck.