Problems with interrupt SOLVED

Hi,
I’m creating (at least trying) an alarm system for my home.
The system exists of arduino uno a LCD and a keypad (4x4).

The problem I’m having is that when the alarm is activated, using a code, I would like to deactivate the alarm using a interrupt and a code again.
But when the alarm is activated and going to the loop section, checking out the zones it will not react to the interrupt anymore.
I can see in the serial monitor the it reacts to the interrupt, because the input stops, but it looks like it never levels the interrupt function. I don’t see the serial statements in the interrupt function appear in the serial monitor. And then my whole program seems to be locked.

The program is not yet finished because trying to do it one step at a time, so I fully understand what is happing and why.
I’m new to programming an arduino so copied some bits of code from every where and created someof my own.

I have attached the code I’m having until now.
When I remove the part

  previousClosedZoneCount = closedZoneCount;
  closedZoneCount = 0;

  for (int i=0; i <= 4; i++)
  {
    if (digitalRead(i+14) == HIGH)
    {
      zoneStatusArray[i] = 1;
      closedZoneCount++;
    } 
    else 
    {
      zoneStatusArray[i] = 0;
      Serial.print(i);
      Serial.print("\n");
      
    }  
  }

from the loop function then, I can activate the alarm, and deactivate the alarm using an interrupt and a code.

Maybe somebody can help me solve the problem I’m having.

Alarm_eigen.ino (7.23 KB)

I think the entire program would be a better help than a piece of code without any errors taken out of context.

The piece of code isn't the problem, it's the way how it reacts to what we don't see that is the problem.

Could your problem be the serial prints in the ISR?

bubulindo:
I think the entire program would be a better help than a piece of code without any errors taken out of context.

The piece of code isn't the problem, it's the way how it reacts to what we don't see that is the problem.

The complete code is added as an attachment to the topic.

AWOL:
Could your problem be the serial prints in the ISR?

I don't think so because when the interrupt works I also get to see the Serial.print lines in the serial monitor.

.ino?

bubulindo:
.ino?

That’s the extension from the Arduino ide.

Here is the complete code:

/*

 */

#include <Wire.h>
#include <PCFCrystal.h>
#include <i2ckeypad.h>
#include <EEPROM.h>

#define zone1Naam "Voordeur"
#define zone2Naam "Keukendeur"
#define zone3Naam "Balkondeur"
#define zone4Naam "Huiskamer oog"
#define zone5Naam "Overloop oog"

#define sirenePin 8
#define sireneDuur 5000  /* sirene duur in ms */
#define alarmlichtPin 9
#define alarmlichtDuur 5000  /* Alarmlicht duur in ms */

#define ROWS 4
#define COLS 4

//Alarm settings
int zoneStatusArray[5] = {0, 0, 0, 0, 0};

//LCD settings
byte buffer = 0;
byte data = 0;
PCFCrystal lcd(B00100000, B00010000, B00000001, B00000010, B00000100, B00001000, 0x38, &buffer);

//Keypad settings
i2ckeypad kpd = i2ckeypad(0x27, ROWS, COLS);

//pincode settings
char mastercode[] = {'#','#','#','#'};
char pincode[] = {'1','1','1','1'};

volatile boolean interrupted = 0;
volatile boolean alarmActivated = 0;
volatile boolean activateMessagePrinted = 0;
volatile boolean activatedMessagePrinted = 0;

//Overige settings
int alarmOnPin = 12;
int alarmOffPin = 13;
int interruptPin = 7;

volatile int state = LOW; 

#define BOUNCE_DURATION 20   // define an appropriate bounce time in ms for your switches
volatile unsigned long bounceTime=0; // variable to hold ms count to debounce a pressed switch

int previousClosedZoneCount = 0;
int closedZoneCount = 0;
boolean breached = 0;
unsigned long sirenOnTimestamp = 0;
boolean sirenStatus = 0;


void setup()
{
  Serial.begin(9600);
  Wire.begin();

  // Set pullup on zone input pins
  pinMode(14, INPUT);
  digitalWrite(14, HIGH);
  pinMode(15, INPUT);
  digitalWrite(15, HIGH);
  pinMode(16, INPUT);
  digitalWrite(16, HIGH);
  pinMode(17, INPUT);
  digitalWrite(17, HIGH);
  pinMode(18, INPUT);
  digitalWrite(18, HIGH);

  pinMode(alarmOffPin, OUTPUT);
  digitalWrite(alarmOffPin, HIGH);
  pinMode(alarmOnPin, OUTPUT);
  digitalWrite(alarmOnPin, LOW);

  pinMode(sirenePin, OUTPUT);
  digitalWrite(sirenePin, LOW);
  pinMode(alarmlichtPin, OUTPUT);
  digitalWrite(alarmlichtPin, LOW);

  pinMode(interruptPin, OUTPUT);
  //digitalWrite(interruptPin, LOW);

  attachInterrupt(0,interrupt,LOW);
  
  lcd.begin(16, 2);
  lcd.print("Init Alarm");
  delay(1000);
  Serial.print("Alarm geinitialiseerd\n\n");
  
}


void loop()
{
  // Determine status of each zone. 1 = closed, 0 = open

  previousClosedZoneCount = closedZoneCount;
  closedZoneCount = 0;

  for (int i=0; i <= 4; i++)
  {
    if (digitalRead(i+14) == HIGH)
    {
      zoneStatusArray[i] = 1;
      closedZoneCount++;
    } 
    else 
    {
      zoneStatusArray[i] = 0;
      Serial.print(i);
      Serial.print("\n");
    }  
  }

  if (closedZoneCount > previousClosedZoneCount)
  {
    breached = 0;
    //Serial.print("Niet ingebroken \n");
  } 
  else if (closedZoneCount == 5)
  {
    breached = 0;
    Serial.print("Alles dicht");
  }
  else  
  {
    breached = 1;   
  }

  if ((breached) && (alarmActivated)) 
  {
    sirenStatus = 1;
    lcd.clear();
    lcd.print("Inbraak in zone:");
    for (int i=0; i <= 4; i++)
    {
      if (zoneStatusArray[i] == 0)
      {
        switch (i)
        {
          case 0:
            lcd.setCursor(0,1);
            lcd.print(zone1Naam);
            break;
          case 1:
            lcd.setCursor(0,1);
            lcd.print(zone2Naam);
            break;
          case 2:
            lcd.setCursor(0,1);
            lcd.print(zone3Naam);
            break;
          case 3:
            lcd.setCursor(0,1);
            lcd.print(zone4Naam);
            break;
          case 4:
            lcd.setCursor(0,1);
            lcd.print(zone5Naam);
            break;
        }
      }
    } 
    digitalWrite(sirenePin, HIGH); 
    Serial.print ("Sirene aan\n");
    sirenOnTimestamp = millis();
    delay(500);
  } 
  else if (((sirenOnTimestamp + sireneDuur) > millis()) && (alarmActivated)) 
  {
    sirenStatus = 1;
    Serial.print ("Sirene nog steeds aan\n");
  } 
  else if (sirenStatus) 
       {
          sirenStatus = 0;
          digitalWrite(sirenePin, LOW); 
          sirenOnTimestamp = 0;
          Serial.print ("Sirene uitgezet\n");

       } 
       else {
             //Serial.print ("Sirene uit\n");
              sirenStatus = 0;
              sirenOnTimestamp = 0;
            }
               
  //Serial.print(alarmActivated);
  //Serial.print("\n");
  
  if (!alarmActivated) 
  {
    Serial.print("Activeer alarm\n");
    activateAlarm();
    Serial.print("Alarm geactiveerd\n");
  }
  if (alarmActivated && interrupted)
  {
    Serial.print("Deactiveer alarm\n");
    deActivateAlarm();
    Serial.print("Alarm gedeactiveerd\n");
  }
}

void activateAlarm()
{
  int counter = 0;
  char code[4];
  char keyPressed;
  boolean codeOK = false;
  boolean mastercodeOK = false;

  lcd.clear();
  lcd.print("Type de code in:");

  while (counter <= 3)
  {    
    keyPressed=readkey();    
    code[counter] = keyPressed;
    lcd.setCursor(counter,1);
    lcd.print(code[counter]);
    if (code[counter] != pincode[counter])
    {
      codeOK = false;
    }
    else
    {
      codeOK = true;
    }
    if (code[counter] != mastercode[counter])
    {
      mastercodeOK = false;
    }
    else
    {
      mastercodeOK = true;
    }
    counter++;
  }
  if (codeOK)
  { 
    lcd.clear();
    lcd.print("Alarm aan");
    alarmActivated = true;
    digitalWrite(alarmOffPin, LOW);
    digitalWrite(alarmOnPin, HIGH);
    delay(2000);
  }
 else
 {
    if (mastercodeOK)
    {
      lcd.clear();
      lcd.print("Mastercode gelezen");
      digitalWrite(alarmOffPin, HIGH);
      digitalWrite(alarmOnPin, LOW);
      alarmActivated = false;
      delay(500);
    }
    else
    {
      lcd.clear();
      lcd.print("Code onjuist");
      digitalWrite(alarmOffPin, HIGH);
      digitalWrite(alarmOnPin, LOW);
      alarmActivated = false;
      delay(500);
    }
 }
  interrupted = false;
}

void deActivateAlarm()
{
  int counter = 0;
  char code[4];
  char keyPressed;
  boolean codeOK = false;
  lcd.clear();
  lcd.print("Type de code in:");

  while (counter <= 3)
  {    
    keyPressed=readkey();    
    code[counter] = keyPressed;
    lcd.setCursor(counter,1);
    lcd.print(code[counter]);
    if (code[counter] != pincode[counter])
    {
      codeOK = false;
    }
    else
    {
      codeOK = true;
    }
    counter++;
  }
  //if (interrupted)
  //{
    //lcd.clear();
    //lcd.print("Interrupted!!");
    //delay(5000);
    //return;
  //}

  if (codeOK)
  { 
    lcd.clear();
    lcd.print("Alarm uit");
    alarmActivated = false;
    digitalWrite(alarmOffPin, HIGH);
    digitalWrite(alarmOnPin, LOW);
    delay(2000);
  }
  else
  {
    lcd.clear();
    lcd.print("Code onjuist");
    alarmActivated = true;
    digitalWrite(alarmOffPin, LOW);
    digitalWrite(alarmOnPin, HIGH);
    delay(1000);
  }
  interrupted = false;
}

char readkey()
{
  char key = kpd.get_key();
  while (key == '\0')
  {  
    key = kpd.get_key();
    //Serial.print(key);
    //Serial.print("\n");
  }
  return key;
}

void interrupt()
{
  // this is the interrupt handler for button presses
  // it ignores presses that occur in intervals less then the bounce time
  if(millis() > bounceTime)  
  {
      Serial.print("Interrupt\n");
      interrupted = true;
      //state = !state;
      Serial.print(interrupted);
      Serial.print("\n");

      bounceTime = millis() + BOUNCE_DURATION;  // set whatever bounce time in ms is appropriate
  }
}

Just save yourself further grief, and remove the serial prints from the ISR.

AWOL:
Just save yourself further grief, and remove the serial prints from the ISR.

Removed and it works, thanks.

Is there an explanation why this won't work?

1.0 uses interrupts for buffered serial output.
Prior to 1.0, serial output wasn't buffered and simply polled.
(it's nearly always a bad idea to do serial I/O in interrupts)

Thanks for the explanation.