while() break; trouble

I'm having trouble getting my while() loop to break. It's a basic countdown timer that should break when an input goes LOW.

const int zone2 = 7; 
const int keyswitch = 9;
const int relay = 2;
const int green = 3;
const int red = 4;

int zone2State = 0;   
int keyswitchState = 0;
int lastkeyswitchState = 0;
int lastzone2State = 0;
int alarmcountdown = 30;

void setup() {
  pinMode(relay, OUTPUT);    
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);  
  pinMode(zone2, INPUT_PULLUP);   
  pinMode(keyswitch, INPUT_PULLUP);  

void loop(){
  zone2State = digitalRead(zone2);
  keyswitchState = digitalRead(keyswitch);

if(zone2State == HIGH && keyswitchState == HIGH) { 
    digitalWrite(red, HIGH);
      while(keyswitchState == HIGH && alarmcountdown > 0){
        Serial.println("Alarm Count Down");
        keyswitchState = digitalRead(keyswitch);
        Serial.println("Keyswitch State");
        if(keyswitchState == LOW){
          alarmcountdown = 30;
        if(alarmcountdown == 0){
          digitalWrite(relay, LOW);  
    if(keyswitchState == LOW){
     digitalWrite(relay, HIGH);
      digitalWrite(red, LOW); 
      alarmcountdown = 30;
  alarmcountdown = 30;  

I included the Serial.println commands to try to assess what is going wrong, and in spite of the "keyswitchState = digitalRead(keyswitch)" command inside the while() loop, it doesn't update the state until after the countdown is completed.

I know there are a few redundancies that can be cleaned up once I've figured out how to make it work, but streamlining comes after functionality!

At this point I'm ready for someone to point out the obvious flaw in my code and make me slap my forehead and say "Doh!" :)

The amount of time the instructions take to execute is very short. You are delaying for 1 second. During that 1 second, button presses will be ignored.

Try pressing and holding your button for 1 second to see if the behavior changes.

"keyswitch" is an actual switch so the circuit goes from open to closed and stays there until the switch is manually changed again. Even if it misses it on the first iteration, it should get it on the next go around. The one second delay is to facilitate the 30 second count down with the possibility of it being cancelled by the switch.

I think that break will break immediately, and not continue with the rest of the code in the while-loop.

A better program control can be achieved with a variable. That variable is to stop the while-loop.

int stoploop = false;
while ( !stoploop)
  if (...)
     stoploop = true;

Krodal - even if I rewrite it using a variable, the "if(...)" condition that would trigger the variable would still fail. The serial monitor still reports that the keyswitchState is "1" even after the circuit is closed. Then once the countdown finishes and the relay trips and the lights flash it finally gets out of the loop and reads the keyswitch and turns it all off again. My problem is that during the while( ) loop it's not looking at or registering a change in the keyswitch.

Are you sure your hardware is working like you think?

I just tried your code and it looks like it works to me. When I attach a jumper from pin 9 (keyswitch) to GND, the countdown stops within 1 iteration. It restarts if I remove the connection.

There it is! My "doh!" moment! I reloaded just the bit that I posted and tried it and that's when I realized that I had my zones backwards! The loop for the zone that I was editing was not the zone that I was testing. I don't want to talk about how many hours I just spent rewriting one section of code over and over again and then testing a different non-working section of code every time. Thanks for the assist!