Pir sensor and keypad

Hello Folks,

I am trying to get this working but no matter what i try its not what i want. hopesome one could point me in te good direction.

What i want:

I press pincode on Keypad. When pincode is correct we wait for input from pir sensor.
If pir sensor pin is High a buzzer will go on.

If the Pir sensor is high for 10 seconds i want my relay to switch on. And in the mean time the buzzer is stil on.

When pir is triggert i have 10 seconds to turn alarm off by enter Off pincode.

My problem is that while counting down to 10 seconds i can not control keypad. So i can not deactivate the alarm.

My Code is very messy with loads of test and copy paste. So dont laugh please.

I hope soembody can give me a pointer in the right direction.

#include <Keypad.h>

#define Password_Length 5
//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 1500;  
boolean alarmState;
boolean lockLow = true;
boolean takeLowTime; 
boolean Counter = false; 
boolean Start = false;
char Data[Password_Length];
char Master[Password_Length] = "12A3";
char MasterUit[Password_Length] = "12B3";
int powerPin = 4;
int SolarPin = 12;
int pirSensorPin = 5; // Pir sensor input signaal
int pirState = LOW; // Start zonder beweging detectie
int val = 0;
byte data_count = 0;
char customKey;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {11,10,9,8};
byte colPins[COLS] = {7,6,3,2};
 
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


int Tijd = 10;
int calibrationTime = 10;

void setup()   {
   Serial.begin(9600);
   pinMode(pirSensorPin,INPUT);
   pinMode(powerPin,OUTPUT);
   pinMode(SolarPin,OUTPUT);
   digitalWrite(powerPin, LOW);
   alarmState = false;
   
}


void loop() {
  
  if (alarmState == true) {   
   alarmIn();
   KeyUit();
  
  } 
  else {
   Key();
    
   
  }

}





void clearData() {
  // Go through array and clear data
  while (data_count != 0) {
    Data[data_count--] = 0;
  }
  return;
}

void alarmIn() {

 
     val = digitalRead(pirSensorPin);
    if(val == HIGH){
      //digitalWrite(SolarPin, HIGH);            
       if(lockLow){ 
         lockLow = false;       
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         Serial.println(Tijd);                
         Start = true;
         }
         takeLowTime = true;
        
         }
         Timer();
         Relay();
      

        
        if(digitalRead(pirSensorPin) == LOW){       
       digitalWrite(powerPin, LOW);  //the led visualizes the sensors output pin state
      
       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           Serial.print(Tijd);
          
           digitalWrite(SolarPin, LOW);  
           delay(10);
           Tijd=10;
           Start = false;
           }
       }
}




// ---  Alarm aan 
void Key() {
   pinMode(pirSensorPin, INPUT);
  // Wacht op keypad invoer
  customKey = customKeypad.getKey();
  if (customKey) {       
    // Enter keypress into array and increment counter
    Data[data_count] = customKey;
    Serial.print(Data[data_count]);
    digitalWrite(SolarPin, HIGH);
         delay(100);
    digitalWrite(SolarPin, LOW); 
    data_count++; 
    }
 
// lengte paswoord
  if (data_count == Password_Length - 1) {
    
  
//// Alarm Aan
    if (!strcmp(Data, Master)) {
      // Password is correct
   
     Serial.print("OK!");
     for(int i = 0; i < calibrationTime; i++){
     Serial.print(".");
     digitalWrite(SolarPin, HIGH);
     delay(200);
     digitalWrite(SolarPin, LOW);
     delay(500);         
     }
     digitalWrite(SolarPin, HIGH);
     delay(500);
     digitalWrite(SolarPin, LOW);
     Serial.println("Sensor active");
     alarmState = true;
     Timer();
    



  
  }
  // Foute code
    else {
      // Password is incorrect  
     Serial.print("FOUT!");
     digitalWrite(SolarPin, HIGH);
     delay(200);
     digitalWrite(SolarPin, LOW);
     delay(500);  
    
     
  }

  // Clear data

   clearData();

}
}

// ---  Alarm off
void KeyUit() {
  // Wacht op keypad invoer
  customKey = customKeypad.getKey();
  if (customKey) {       
    // Enter keypress into array and increment counter
    Data[data_count] = customKey;
    Serial.print(Data[data_count]);
    digitalWrite(SolarPin, HIGH);
         delay(100);
    digitalWrite(SolarPin, LOW); 
    data_count++; 
    }
 

  if (data_count == Password_Length - 1) {
    
  

    if (!strcmp(Data, MasterUit)) {
      // Password is correct
     
     pinMode(pirSensorPin, OUTPUT);  
     Serial.println("Alarm Uit");
    digitalWrite(SolarPin, HIGH);
    delay(100);
    digitalWrite(SolarPin, LOW); 
    delay(100);
    digitalWrite(SolarPin, HIGH);
    delay(100);
    digitalWrite(SolarPin, LOW); 
     alarmState = false;
  }

    else {
      // Password is incorrect  
     Serial.print("Error!");
     digitalWrite(SolarPin, HIGH);
     delay(200);
     digitalWrite(SolarPin, LOW);
     delay(500);  
     
  }
   clearData();
}
}

void alarm(long duration, int freq) {
  tone(SolarPin, freq);
  delay(duration);
  noTone(SolarPin);

}

void Timer(){
        val = digitalRead(pirSensorPin);
       if (val == HIGH) {
        Tijd--;
        delay(1000);            
      }
      
}

void Relay() {

   if (Start = true && Tijd==0) {
        digitalWrite(powerPin, HIGH);
   }
}

Hi wolfray,

The description you have given is detailed yet not best structured and detailed to get everything clear.

Your code is pretty long. This is not a problem in general.
The names of the functions are not self-descriptive. This means you force the other users to analyse the functionality of your functions through reading it line by line to understand what the code is doing.
This is a lot of work.

So here are some rules I invite you to check if following these rules makes sense to you.

write your code consequently segmented into functional parts.
Each functional part does one senseful unit of commands
give this function a self-descriptive name that nails down the functionality to the point.

This has multiple positive effects:

  • you did analyse your code very carefully
  • each senseful unit can be tested on its own
  • the self-descriptive name of the functions makes it easy to understand what this part of the code is doing

which in summary results in easy to understand and easy to maintain code.

Your function AlarmIn() does a lot of things that are scattered over many lines of code.

One solution - among others - to achieve your desired functionality is to use a state-machine.
State-machines reduce the number of if-conditions and flag-variables you have to check.
The cost is to learn the principle how state-machines work.
Once you have mastered understanding state-machines coding such functionalities becomes much easier

best regards Stefan

Hello Stefan,

Is this what you mean by state-machine?
It is not the complete code but am i on the right track?

//  Sensor alarm code:
// - Enter Pincode and alarm will be activated
// - Pir sensor is on standby and on start we have set it to no motion dectected
// - When motion is detected a buzzer wil be activated and we have 10 seconds to turn off alarm by entering secondary pincode.
// - If input secondary pincode is failed, a relay wil be switched on and a external alarm wil be triggerd.
// ------------------------------------------------------------------

#include <Keypad.h>
#define Password_Length 5  

boolean alarmState;
boolean TimerOn;
boolean TimerOff;
boolean StartOn;
boolean StartOff;

 // Keypad----
char Data[Password_Length];
char Master[Password_Length] = "12A3";
char MasterUit[Password_Length] = "12B3";
char customKey;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {11,10,9,8};
byte colPins[COLS] = {7,6,3,2};
byte data_count = 0;
const byte ROWS = 4;
const byte COLS = 4;
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

int timerStart = 10;
int calibrationTime = 10;
int relayPin = 4; // Relay Pin
int buzzerPin = 12; 
int pirSensorPin = 5; // Pir sensor input signal
int pirState = LOW; // Start pirsensor without movement.
int val = digitalRead(pirSensorPin);

void clearData() {  // Go through array and clear data keypad
  while (data_count != 0) {
    Data[data_count--] = 0;
  }
  return;
}


void TimerOn() { // Start timer count back from int timerstart = 10
  timerStart--;
  delay(1000);
}

void TimerOff() { // If timerstart = 0 then switch on relay
  if (timerStart==0) {
     digitalWrite(relayPin, HIGH);
  }
}

void Key() {
  customKey = customKeypad.getKey();
  if (customKey) {  // Enter keypress into array and increment counter
    Data[data_count] = customKey;
    buzzerkeyPad();
    data_count++; 
    }
}

void buzzerkeyPad() {
    Serial.print(Data[data_count]);
    digitalWrite(SolarPin, HIGH);
         delay(100);
    digitalWrite(SolarPin, LOW); 
}




void setup()   {
   Serial.begin(9600);
   pinMode(pirSensorPin,INPUT);
   pinMode(relayPin,OUTPUT);
   pinMode(buzzerPin,OUTPUT);
   digitalWrite(relayPin, LOW);
   alarmState = false;  
}


void loop() { 
    key();
    while (val == HIGH) {
    timerOn();
    timerOff();
   } 
}

Regards,

Wolf