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

Hi I am new to Arduino and I have been working on an Alarm system using a home made analog keypad . I have used some code from a 7 pin keypad that I was using in a different project and have adapted it to my needs. The trouble is that it keeps resetting and I am out of ideas. Please help if you can. I know that the code is a bit of a mess (sorry)
Thanks for taking the time to look.
Jezza

int NOKEY=255;
int i, k, pwcount=0;
char password[]="1234",entry[10];
int buttonPin=A0;
int val=A0;
int ldr=12;
int senseValue=0;
int led=13;
int sensePin=A1;
int buzzerPin=2;
int led2=5;
int led3=3;
int led4=4;


void setup() {
  // put your setup code here, to run once:
pinMode (buttonPin,INPUT);
pinMode (sensePin,INPUT);
pinMode(ldr,OUTPUT);
pinMode (led,OUTPUT);
pinMode (led2,OUTPUT);
pinMode (led3,OUTPUT);
pinMode (led4,OUTPUT);
pinMode (buzzerPin,OUTPUT);
Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly: 
   for(i=6; i<=8; i++){
  reset();
  
  
  val=analogRead(buttonPin);
  val = map(val, 0, 1023, 0, 255);
 // Serial.print("Button Value   ");//used for debugging
//Serial.println(val);
  
senseValue=analogRead(sensePin);
senseValue = map(senseValue, 0, 1023, 0, 255);
Serial.print("     Sensor Value   ");//used for debugging
 Serial.println(senseValue);
    if (senseValue >100)triggered();
    
    if (val==0)(val==255);//I cannot stop the program looping
  
  if ((val >10)&&(val<18)){
   entry[pwcount]='1' ;
   pwcount++;
   delay(250);
Serial.println('1');
  }
 if ((val >19)&&(val<28)){
   entry[pwcount]='2' ;
   pwcount++;
   delay(250);
Serial.println('2');
  } 
  
   if ((val >30)&&(val<40)){
   entry[pwcount]='3' ;
   pwcount++;
   delay(250);
Serial.println('3');
  }
 if ((val >50)&&(val<60)){
   entry[pwcount]='4' ;
   pwcount++;
   delay(250);
Serial.println('4');
  }  
  
   if ((val >75)&&(val<90)){
   entry[pwcount]='5' ;
   pwcount++;
   delay(250);
Serial.println('5');
  }
 if ((val >100)&&(val<120)){
   entry[pwcount]='6' ;
   pwcount++;
   delay(250);
Serial.println('6');
  } 
  
   if ((val >135)&&(val<155)){
   entry[pwcount]='7' ;
   pwcount++;
   delay(250);
Serial.println('7');
  }
 if ((val >170)&&(val<180)){
   entry[pwcount]='8' ;
   pwcount++;
   delay(250);
Serial.println('8');
  }  
    if ((val >190)&&(val<205)){
   entry[pwcount]='9' ;
   pwcount++;
   delay(250);
Serial.println('9');
  }
 if ((val >218)&&(val<227)){
   entry[pwcount]='*' ;
   pwcount++;
   delay(250);
Serial.println('*');
  } 
  
   if ((val >227)&&(val<236)){
   entry[pwcount]='0' ;
   pwcount++;
   delay(250);
Serial.println('0');
  }
 if ((val >237)&&(val<250)){
   entry[pwcount]='#' ;
   pwcount++;
   delay(250);
Serial.println('#');
  }  
  
  
  
   pwcount=0;
  for(k=0; k<=5; k++){
   if(k==5){
   Serial.println("Alarm Disabled");
   digitalWrite(3, HIGH);
   digitalWrite (4, LOW);
   digitalWrite (13,LOW);
   digitalWrite(ldr,LOW);
   
   
   break;
   }
   if(password[k] != entry[k]){
     digitalWrite (4, HIGH);
     Serial.println("Alarm ON 2 Seconds Until Armed");
     digitalWrite(3,LOW);
     armed();
     //delay(2000);
     //digitalWrite (13,HIGH);
     Serial.println("Alarm Enabled");
     printing();
     Serial.println("Callibrating System Please wait..");
     printing();
     Serial.println("System Activating...");
     printing();
     Serial.println("All Systems Functioning Correctly");
      printing();
       delay(500);
     Serial.println("Alarm On");
     break; 
   }
  }
  // k<10
  for(k=0; k<10; k++)
  entry[k]=0;
  }  
}

void reset(){
   int j;
   for(j=6; j<=8; j++)
   digitalWrite(j, LOW);
}

void blinker(){
  digitalWrite(3, HIGH);
  delay(15);
  digitalWrite(3, LOW);
  
  
}
void printing(){
delay(200);



}
void armed (){
  delay(100);
  digitalWrite(13,HIGH);
  digitalWrite(ldr,HIGH);
}

void triggered(){
  digitalWrite(buzzerPin,HIGH);
  digitalWrite(13,LOW);
  delay(30);
  digitalWrite(buzzerPin,LOW);
  digitalWrite(13,HIGH);
  delay(30);
}

Could you auto format your code please, "CTRL-T"

which part "keeps resetting"? Is it the arduino or just the connection to the keypad?

Seeing the program is useless unless you provide connection diagram.

jezza103:
The trouble is that it keeps resetting and I am out of ideas.

I'm not sure what you mean by 'resetting', but could it relate to this part of your code?

void loop() {
  // put your main code here, to run repeatedly: 
   for(i=6; i<=8; i++){
  reset();

If not, what do you mean by 'resetting'?

Hi I am sorry I have not got to you all. I have re written the code to make it easier to read and have made a diagram or the keypad. I have just made the code for the basic reading of the keypad but i do not know what to do now to make the password function work.
Thank you
Jeremy

int i, k, pwcount=0;
char password[]="1234",entry[10];// password that is stored



int buttonPin=0;// keypad pin
int val;// value of key pressed
int PIR=12;//PIR sensor power pin
int senseValue;// value of PIR sensor pin
int nos;// variable for number of the keypad
int sensePin=1;//Pin PIR is connected to
int buzzerPin=2;// buzzer connected here

int led3=3;// leds for testing
int led4=4;
int led5=5;
int led=13;

void setup() {
  pinMode (buttonPin,INPUT);
  pinMode (sensePin,INPUT);
  pinMode(PIR,OUTPUT);
  pinMode (led,OUTPUT);
  pinMode (led3,OUTPUT);
  pinMode (led4,OUTPUT);
  pinMode (led5,OUTPUT);
  pinMode (buzzerPin,OUTPUT);
  Serial.begin(9600);

}

void loop() {



  val=analogRead(buttonPin);
  val = map(val, 0, 1023, 0, 255);
  // Serial.print("Button Value   ");//used for debugging
  //Serial.println(val);


  senseValue=analogRead(sensePin);
  senseValue = map(senseValue, 0, 1023, 0, 255);
  //Serial.print("     Sensor Value   ");
  //Serial.println(senseValue);

  //delay(200); 



  if((val>10&&val<17)){
    (nos=1);//read the keypad
    blinker();


    if( nos==1){
      entry[pwcount]='1' ;//returns the button press
      pwcount++;
      delay(250);
      Serial.print('1');//prints the key value for debugging


    }
  }

  if((val>20&&val<29)){
    (nos=2);
    blinker();
    if( nos==2){
      entry[pwcount]='2' ;
      pwcount++;
      delay(250);
      Serial.print('2');


    }
  }

  if((val>31&&val<38)){
    (nos=3);
    blinker();


    if( nos==3){
      entry[pwcount]='3' ;
      pwcount++;
      delay(250);
      Serial.print('3');




    }
  }

  if((val>50&&val<58)){
    (nos=4);
    blinker();


    if( nos==4){
      entry[pwcount]='4' ;
      pwcount++;
      delay(250);
      Serial.print('4');




    }
  }

  if((val>75&&val<88)){
    (nos=5);
    blinker();


    if( nos==5){
      entry[pwcount]='5' ;
      pwcount++;
      delay(250);
      Serial.print('5');




    }
  }
  if((val>101&&val<115)){
    (nos=6);
    blinker();


    if( nos==6){
      entry[pwcount]='6' ;
      pwcount++;
      delay(250);
      Serial.print('6');




    }
  }
  if((val>138&&val<150)){
    (nos=7);
    blinker();


    if( nos==7){
      entry[pwcount]='7' ;
      pwcount++;
      delay(250);
      Serial.print('7');




    }
  }
  if((val>170&&val<180)){
    (nos=8);
    blinker();


    if( nos==8){
      entry[pwcount]='8' ;
      pwcount++;
      delay(250);
      Serial.print('8');




    }
  }
  if((val>195&&val<202)){
    (nos=9);
    blinker();


    if( nos==9){
      entry[pwcount]='9' ;
      pwcount++;
      delay(250);
      Serial.print('9');




    }
  }
  if((val>219&&val<226)){
    (nos=10);
    blinker();


    if( nos==10){
      entry[pwcount]='*' ;
      pwcount++;
      delay(250);
      Serial.print('*');




    }
  }
  if((val>230&&val<238)){
    (nos=11);
    blinker();


    if( nos==11){
      entry[pwcount]='0' ;
      pwcount++;
      delay(250);
      Serial.print('0');




    }
  }
  if((val>238&&val<245)){
    (nos=12);
    blinker();


    if( nos==12){
      entry[pwcount]='#' ;
      pwcount++;
      delay(250);
      Serial.print('#');
      pwcount=0;
    }
  }
}


void blinker(){// blinks the led for confirmation of button press
  digitalWrite(13, HIGH);
  delay(15);
  digitalWrite(13, LOW);


}

If you press the button on the top right corner, what happens?

That setup is not good to use. As liudr pointed out, that top right button will short out your arduino, possibly destroying it. You should rewire your keypad based on something like this.

[V+]---+---WWW--+---WWW--+---WWW--+---WWW--+---WWW--//+----[GND]
| | | | | |
| | | | | |
===(1) ===(2) ===(3) ===(4) ===(5) //===(N)
| | | | | |
| | | | | |
L------------L-----------L-----------L----------L--------//----L-------------[Arduino Pin]

Hi I am sorry but my drawing isn't great. There is no short on key 1. When you press the keys this is the outcome.
When you press 1 you get a 1 on the serial monitor,2 you get a 2 and so on. It works great. every number and symbol are reproduced. the delay is a like a debounce in a way because unless you hold down the button you always get the correct key press.
the values produced from the keys is :-
1=58, 2=96, 3=145, 4=228, 5=335, 6=447, 7=598, 8=720, 9=809, *=890, 0=941, #=970,
I have tried to get a password to work but I am completely stumped by my lack of programming ability.
Jeremy

Ok everything displays correctly, so now you just need to get those numbers into an array. Its just a little code to check if a key is pressed, and update a counter to change the array, to store a new value. There are plenty on the forum, just do a search for keypads, and you should get something. The more specific your description is, the better the results.

What you can do is make a new function, and everytime a key is pressed it goes to the function and adds it to the array. You may need an if statement to keep track of how many numbers are being inputted, and reset to zero once everything is done. You could even add some error messages to show on the LCD or serial monitor, "Incorrect Password"

Good thing you have the keypad working on a single analog pin. Now you tantalized me. Please provide an exact diagram!

Now that your code is working, we can talk software. Here is always the key to interacting with buttons: detect change of state, not just detecting the current state. If you detect a state of no buttons, you save it to a state variable. Then you detect the state again until it changes into say button 1 down. So the change of state no-buttons -> button 1 down, will be recognized as a button 1 press. What you are doing now is detecting current state, not change of state.

If you want an easy way out, use my phi_interfaces library. All you need to do is to create an analog_keypad instance and type in all the key press analog reading values in ascending order, and their buttons face value, such as '1', '2', '*' etc in another array.

Sample code is with the download. Debounce is done in the library. You will put keypad.getKey() in a while loop. If it returns a key instead of NOKEY, you have some things to do, such as storing a digit or compare password (if enter is pressed).

Thank you all for your input so far. Thank you Liudr for the link. I will be looking at that. I am finding this project very frustrating and am very grateful for your help. I am just starting out in programming so i need a little help.
Jeremy

Hey, I will post some sample code for you after dinner. Once you are through with the setup, you are ready to fly through a lot of stuff. That is the promise of my library.

#include <phi_interfaces.h>

#define buttons_per_column 12 // 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','7','8','9','*','0','#'}; // This is an analog keypad.
byte pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={0, 58, 96, 145, 228, 335, 447, 598, 720, 809, 890, 941, 970}; //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;

void setup()
{
  Serial.begin(9600);
  Serial.println("Phi_interfaces library analog keypad test code");
}

void loop()
{
  byte 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);
}

Hi Liudr. Thank you for the sketch and the link which I have downloaded and installed the phi_interfaces_V100 folder in the libraries folder. I have tried to upload the sketch but there is an error which stops at this line

byte keypad_type=Analog_keypad;

the error message is
Analog_keypad was not declared in this scope.
I must be missing something.
Thank you
Jeremy

This has one too many values.

int values[]={0, 58, 96, 145, 228, 335, 447, 598, 720, 809, 890, 941, 970};

Get rid of the first 0, to make it match,char mapping[]={'1','2','3','4','5','6','7','8','9','*','0','#'};

Hi HazardsMind. Thank you. Well done it compiles now and works. I have a few buttons on my keypad that give inconsistent readings though. Take button 4 for example it returns anything from 220-229 so I tried to adapt the "values" array to

int values[12][3] = {{1, 50, 65}, // button 1
                       {2, 90, 110}, // button 2
                     {3, 137, 160}, // button 3
                     {4, 200, 245}, // button 4
                     {5, 300, 350}, // button 5
                     {6, 420, 470}, // button 6
                     {7, 500, 620}, // button 7
                     {8, 700, 745}, // button 8
                     {9, 780, 820}, // button 9
                     {10, 844, 900}, // button *
                     {11, 930, 955}, // button 0
                     {12, 956, 999}}; // button #

The trouble is it didn't work so I am back to square 1 on this but I have learned quite a bit over the last few days.I will have to try again on this.
I have a 7 pin 4x3 keypad which is working fine on my project but, I just need to get this to work now,if nothing else just to show that it can be done. It is a wonder that more of you guys are not using a keypad like this to free up those digital pins. unless of course you are all using "Mega's"
Regards
Jeremy

Jeremy,

Just use the center value between the max and min for each button in that sample code (sorry about the zero) and then look at the range of these values. There are 12 (effectively 13 values with the 0) so you are cutting the whole 1024 range into small sub-ranges. In the phi_interfaces library, there is a factor to decide the threshold of a match. Change that to maybe 20 so you will get more hits. The 2D array will not work with my library.

Open phi_interfaces.cpp and look for this line: if (diff<10)

Change 10 to 20. I should have defined a sensitivity=10 but didn't.

Yes It works now. Thanks Liudr. Right now for the password part. I think I am getting there. It has taken me ages to get this idea working. I knew it could be done I just couldn't figure it out on my own.
No problem about the "0" I should have spotted that myself.
Have you made your own keypad yet?
Jeremy

I might be able to find you some code to enter password but if you want some simplicity, get my phi-panel serial lcd backpack with matrix keypad connection.