Home Alarm with a 3 wire 4x3 analog keypad nearly done but need some help please

Hi Liudr I would appreciate some code if you have some for the password. But as for the phi-panel serial lcd backpack. I would love one but I have no funds at the moment because I am on what you call welfare since my injury. I will make do with what I have in the way of hardware. my alarm when it is finally done will not have a display just some indicator led's. I will have to do something about my keypad though it is just 12 buttons soldered onto a piece of protoboard. But that may just confuse a Burglar.
Regards
Jeremy

Have you ever felt that you are in a real life
void loop(){
try this;
did it work y/n;
n;
try that;
did it work y/n
n;
}
Sorry but it is driving me nuts. Maybe I could learn to make cakes :slight_smile:

I found some time today and wrote this code for you:

#include <phi_interfaces.h>

#define buttons_per_column 6 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

byte keypad_type=Analog_keypad;
char mapping[]={'1','2','3','4','5','6'}; // This is an analog keypad.
byte pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={14, 378, 563, 618, 656, 704}; //These numbers need to increase monotonically.
phi_analog_keypads panel_keypad(mapping, pins, values, buttons_per_row, buttons_per_column);
multiple_button_input* pad1=&panel_keypad;

char password[]="13531";
char buffer[20];
int pointer=0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Phi_interfaces library analog keypad test code: password");
  digitalWrite(A0,HIGH); // DO this only if you are using phi-3 shield.
}

void loop()
{
  byte temp;
  Serial.println("Enter 5-digit password:");
  while(1)
  {
    temp=panel_keypad.getKey(); // Use phi_keypads object to access the keypad
  //  byte temp=pad1->getKey(); // Use the generic multiple_button_interface to access the same keypad
    if (temp!=NO_KEY)
    {
      Serial.write(temp);
      buffer[pointer++]=temp;
      if (pointer==5)
      {
        buffer[pointer]=0;
        pointer=0;
        if (!strcmp(buffer,password))
        {
          Serial.println("Authenticated!");
        }
        
        else
        {
          Serial.println("Unauthorized!");
        }
        return;
      }
    }
  }
}

It works on my phi-3 shield (experimental) so if you modify it to work on your keypad it should work too.

Hi Liudr. Thank you so much for the code. It works !!!! I cannot believe that after all this time I have a working analog keypad with a password function. It is coming together now and I am going to add a bit to it to get my PIR sensor working and buzzer and I will be there.
Thanks again
Jeremy

I have been at it all evening trying to get my PIR sensor to work. The only way I have found is to do away with the while statement. I had to turn off the Serial.println('Enter 5 digit password') line but I can not get the siren pin to go high, once switched on the sensor goes high before settling down.
The sensor once tripped stays HIGH for five seconds before it goes LOW again. I need the siren to wait for that amount of time before going off or it will trip as soon as you power on the system.
And I thought getting the keypad done was the hard bit. I think I may have bitten off more than I can chew here. I am not sure how to get the siren to wait but maybe the answer is using the millis function. I am not sure if that will influence the code I am using? Should i look at the blink without delay sketch or just use a switch case with a delay to wait for the sensor;
I think I will sleep on it as it is 1:30 am
Jeremy

jezza103:
Hi Liudr. Thank you so much for the code. It works !!!! I cannot believe that after all this time I have a working analog keypad with a password function. It is coming together now and I am going to add a bit to it to get my PIR sensor working and buzzer and I will be there.
Thanks again
Jeremy

Jeremy,

You are welcome. I will include this example in my next library release.

Yeah, the blink without delay example will help you multitask instead of just reading the keypad. Give it a try.

Hi again. My brain aches and I still cannot get this to work. I have tried this way and that but nothing seem to work. The thing is that I know too little about programming to understand what I am doing wrong. This evening my computer crashed and I lost what I have been doing all day(I was an idiot and didn't save it) but then again it was not working anyway. If I use the millis function to time the amount of time the alarm sounds when it is triggered the keypad will not respond until the time millis function has completed. I had the siren sounding for 30 seconds and in that time the keypad will not function.
Regards
Jeremy

Read about state machines. If you use delay, you won't be able to anything while delaying. If you want to use the keypad while the alarm is sounding for 30 seconds, you can't use delay, use state machine and timers instead.

I didn't check on an arduino but it compiles.

#include <phi_interfaces.h>

#define buttons_per_column 6 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

byte keypad_type=Analog_keypad;
char mapping[]={'1','2','3','4','5','6'}; // This is an analog keypad.
byte pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={14, 378, 563, 618, 656, 704}; //These numbers need to increase monotonically.
phi_analog_keypads panel_keypad(mapping, pins, values, buttons_per_row, buttons_per_column);
multiple_button_input* pad1=&panel_keypad;

#define alarm_pin 10
enum States {get_password, alarm, cleared};
States system_state=get_password;

unsigned long alarm_starting, cleared_starting;
char password[]="13531";
char buffer[20];
int pointer=0;

void setup()
{
}

void loop()
{
  byte temp;
  switch (system_state)
  {
    case get_password:
    // do get password stuff
    temp=panel_keypad.getKey(); // Use phi_keypads object to access the keypad
    if (temp!=NO_KEY)
    {
      Serial.write(temp);
      buffer[pointer++]=temp;
      if (pointer==5)
      {
        buffer[pointer]=0;
        pointer=0;
        if (!strcmp(buffer,password))
        {
          Serial.println("Authenticated!");
          system_state=cleared;
          cleared_starting=millis();
          // Open a door or something
        }
        
        else
        {
          Serial.println("Unauthorized!");
          system_state=alarm;
          alarm_starting=millis();
          tone(alarm_pin,550);
        }
      }
    }
    break;
    
    case alarm:
    if ((!panel_keypad.getKey())||(millis()-alarm_starting>=30000))
    {
      system_state=get_password;
      noTone(alarm_pin);
    }
    break;
    
    case cleared:
    if ((!panel_keypad.getKey())||(millis()-cleared_starting>=30000))
    {
      system_state=get_password;
      // Close the door or something.
    }
    break;
  }
}

Thank you liudr. I have had a quick look at your code. Before i even try to use it I will have a read about state machines. I will get back to you and let you know how I get on.
regards
Jeremy

jezza103:
Thank you liudr. I have had a quick look at your code. Before i even try to use it I will have a read about state machines. I will get back to you and let you know how I get on.
regards
Jeremy

You are welcome.

Add the following in setup():

  Serial.begin(9600);
  pinMode(alarm_pin,OUTPUT);
  digitalWrite(alarm_pin,LOW);

The original code was close to work. Here is code after I tested on my phi-3 shield:

#include <phi_interfaces.h>

#define buttons_per_column 6 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

byte keypad_type=Analog_keypad;
char mapping[]={'1','2','3','4','5','6'}; // This is an analog keypad.
byte pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={14, 378, 563, 618, 656, 704}; //These numbers need to increase monotonically.
phi_analog_keypads panel_keypad(mapping, pins, values, buttons_per_row, buttons_per_column);
multiple_button_input* pad1=&panel_keypad;

#define alarm_pin 13
enum States {get_password, alarm, cleared};
States system_state=get_password;

unsigned long alarm_starting, cleared_starting;
char password[]="13531";
char buffer[20];
int pointer=0;

void setup()
{
  Serial.begin(9600);
  pinMode(alarm_pin,OUTPUT);
  digitalWrite(alarm_pin,LOW);
  digitalWrite(A0,HIGH); // DO this only if you are using phi-3 shield.
}

void loop()
{
  byte temp;
  switch (system_state)
  {
    case get_password:
    // do get password stuff
    temp=panel_keypad.getKey(); // Use phi_keypads object to access the keypad
    if (temp!=NO_KEY)
    {
      Serial.write(temp);
      buffer[pointer++]=temp;
      if (pointer==5)
      {
        buffer[pointer]=0;
        pointer=0;
        if (!strcmp(buffer,password))
        {
          Serial.println("Authenticated!");
          system_state=cleared;
          cleared_starting=millis();
          // Open a door or something
        }
        
        else
        {
          Serial.println("Unauthorized!");
          system_state=alarm;
          alarm_starting=millis();
          digitalWrite(alarm_pin,HIGH);
        }
      }
    }
    break;
    
    case alarm:
    if ((panel_keypad.getKey()!=NO_KEY)||(millis()-alarm_starting>=30000))
    {
      system_state=get_password;
      digitalWrite(alarm_pin,LOW);
    }
    break;
    
    case cleared:
    if ((!panel_keypad.getKey())||(millis()-cleared_starting>=30000))
    {
      system_state=get_password;
      // Close the door or something.
    }
    break;
  }
}

Hi liudr. Thank you for the revised code. This does work but when the alarm is tripped any keypad press turns the alarm off. I tried it this morning. I am reading all I can find about state machines too.
Perhaps I should leave it today as I have had more injections into my spine and they hurt badly. I may have a look later if I feel better. I hope I am not taking up too much of your time on this.
Regards
Jeremy

jezza103:
Hi liudr. Thank you for the revised code. This does work but when the alarm is tripped any keypad press turns the alarm off. I tried it this morning. I am reading all I can find about state machines too.
Perhaps I should leave it today as I have had more injections into my spine and they hurt badly. I may have a look later if I feel better. I hope I am not taking up too much of your time on this.
Regards
Jeremy

Good! Yes, that feature can be turned on and off inside the alarm case. I don't kow what you exactly wanted.

HazardsMind:
There is a problem with this code, in your get_password case. Once you get the 5th number, your telling the program to put a zero in the arrays 5th place.

Yeah right, so what's the problem?

Edit: Removed

Good! Yes, that feature can be turned on and off inside the alarm case. I don't kow what you exactly wanted.

Hi liudr. What I wanted is to attach a PIR sensor and have the value it senses for movement set the alarm buzzer off for say 30 seconds. The keypad needs the correct code to disarm the alarm buzzer and ignore the PIR sensing or turn off the PIR sensor using a transistor. If i use a PNP transistor setting a digital pin HIGH via a resistor to the base of the transistor would cut the power to the PIR sensor.

 if (pointer==5)
      {
        buffer[pointer]=0;
        pointer=0;
        if (!strcmp(buffer,password))
        {
          Serial.println("Authenticated!");
          system_state=cleared;
          cleared_starting=millis();
II hope this is a help
Jeremy
          // Open a door or something
          digitalWrite (tripped,LOW);
          digitalWrite(alarmOff,HIGH);
        }
   
        }
        
        else
        {
          Serial.println("Unauthorized!");
          system_state=alarm;
          alarm_starting=millis();
          digitalWrite(alarm_pin,HIGH);
          digitalWrite(tripped,HIGH);
          digitalWrite (alarmOff,LOW);
        }
      }
    }[code]

[/code]

HazardsMind:

Yeah right, so what's the problem?

Well any number you put in for the 5th digit, will be changed to zero, thats not a problem?
You enter 12345, the code after that part sees 123450. I can't test it myself, but thats what I see from this.

Again I can't test it, but if it works then it works.

No. Reread the code. More importantly, get the C from ground up by the author I recommended you.

I don't have a PIR sensor so I can't help with that. I recommend you read my code a few times, find out how it is able to sound alarm/LED for 30 seconds while monitoring keypad input. Then you can change it to do your PIR logic. I imagine if someone walks up to the PIR sensor, it sounds the alarm. then they type in the code to disarm it? It's all your call how to do this.

liudr:

HazardsMind:

Yeah right, so what's the problem?

Well any number you put in for the 5th digit, will be changed to zero, thats not a problem?
You enter 12345, the code after that part sees 123450. I can't test it myself, but thats what I see from this.

Again I can't test it, but if it works then it works.

No. Reread the code. More importantly, get the C from ground up by the author I recommended you.

HazardsMind,

Sorry I issued the RTFM on this. I should have pointed out what the code does:

  1. It fills the buffer with up to 5 characters from the keypad (password).
  2. It then terminates the string in the buffer with \0
  3. It then performs a string comparison with the password using strcmp(), which requires a zero terminated C-string, thus step 2.
  4. It then decides whether to sound the alarm or to clear the alarm.

My step 2 was not necessary if I set the C-string's 5th location to zero in setup like buffer[5]=0 or have char buffer[10]=" ". But if I move the code to a different project, that line is very likely to be left out (forget to move) and this wouldn't work (buffer[5] is just a random value). The initial value of the buffer is also wasting 6 bytes of arduino SRAM, which is only 2K long.