Pages: [1]   Go Down
Author Topic: Keypad Lock (reinventing the wheel)  (Read 1193 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
This is my first arduino project. It's a simple keypad lock using a 3x4 matrix keypad. As this is a learning experience for me (c++ and electronics) I decided not to use the keypad or password libraries because copying pasting and editing a few lines of code is not a good way to learn in my opinion. The code is messy and uncommented but it works perfectly. I plan to tidy up the code a bit and add comments soon.  Also I am going to move the passkey into the EEPROM and add some way of setting it without burning a new sketch.


Code:
/*
 * Zabouth Keypad Lock 2010
 * Pin    Color
 * 10  |  Green
 *  9  |  Yellow
 *  8  |  Pink
 *  7  |  White
 *  6  |  Purple
 *  5  |  Blue
 *  4  |  Brown
*/
long lastDebounceTime = 0;  
long debounceDelay = 50;
int debouce = 0;
int colpress = 0;
int rowpress = 0;
int ledPin = 13;
char PassCode[5] = "1234";
char EntCode[5]  = "AAAA";
const byte ROWS = 4;
const byte COLS = 3;
byte rowPins[ROWS] = {7,6,5,4};
byte colPins[COLS] = {8,9,10};
int PressCount = 0;
char customKey;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};




void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}

void loop()
{
customKey = keypress();
if (customKey){
  Serial.println(customKey);
    if (customKey == 42) {
resetcode();
    }
    else{
      EntCode[PressCount] = customKey;
      PressCount = PressCount + 1;
    }
    
    if (PressCount == 4 && EntCode[0] == PassCode[0] && EntCode[1] == PassCode[1] && EntCode[2] == PassCode[2] && EntCode[3] == PassCode[3]){
      digitalWrite(ledPin, HIGH);  
      delay(5000);                  
      digitalWrite(ledPin, LOW);  
resetcode();
    }
    
    if (PressCount == 4 && EntCode[0] != PassCode[0] || PressCount == 4 && EntCode[1] != PassCode[1] || PressCount == 4 && EntCode[2] != PassCode[2] || PressCount == 4 && EntCode[3] != PassCode[3]){
resetcode();
    }
  }
}

int keypress()
{
  int r,c,x = 0;
  char ret;
  
r = ScanRow();
if (r) { rowpress = r; }
c = ScanCol ();
if (c) { colpress = c; }

if (c && r)
{
c = c - 1;
r = r - 1;

if (debouce == 0 && (millis() - lastDebounceTime) > debounceDelay){
debouce = 1;
return  hexaKeys[r][c];
}else{ return 0; }
}else{
 debouce = 0;
 lastDebounceTime = millis();
return 0;

}
}

int ScanRow() {
  pinMode(7, INPUT);    
  digitalWrite(7, HIGH);
  pinMode(6, INPUT);      
  digitalWrite(6, HIGH);
  pinMode(5, INPUT);  
  digitalWrite(5, HIGH);
  pinMode(4, INPUT);
  digitalWrite(4, HIGH);
  pinMode(8,OUTPUT);
  digitalWrite(8, LOW);  
  pinMode(9,OUTPUT);
  digitalWrite(9, LOW);  
  pinMode(10,OUTPUT);
  digitalWrite(10, LOW);

  if (digitalRead(7) == LOW)
  {
    return 1;
  }
  else if (digitalRead(6) == LOW)
  {
    return 2;
  }
  else if (digitalRead(5) == LOW)
  {
    return 3;
  }
  else if (digitalRead(4) == LOW)
  {
    return 4;
  }
  else
  {
    return 0;
  }
}

int ScanCol () {

  pinMode(7, OUTPUT);  
  digitalWrite(7, LOW);
  pinMode(6, OUTPUT);      
  digitalWrite(6, LOW);
  pinMode(5, OUTPUT);  
  digitalWrite(5, LOW);
  pinMode(4, OUTPUT);    
  digitalWrite(4, LOW);
  pinMode(8,INPUT);
  digitalWrite(8, HIGH);  
  pinMode(9,INPUT);
  digitalWrite(9, HIGH);  
  pinMode(10,INPUT);
  digitalWrite(10, HIGH);
  
  
   if (digitalRead(8) == LOW)
  {
    return 1;
  }
  else if (digitalRead(9) == LOW)
  {
    return 2;
  }
  else if (digitalRead(10) == LOW)
  {
    return 3;
  }
  else
  {
    return 0;
  }
}


void resetcode()
{
      Serial.println("reset");
      PressCount = 0;
      EntCode[0] = 32;
      EntCode[1] = 32;
      EntCode[2] = 32;
      EntCode[3] = 32;
}




Logged

Vermont, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 170
ElectroMech
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I actually just finished reinventing this particular wheel today!



My sketch didn't need password stuff, though. I press "*" then type a 3 to 4 digit time then press "#" and it sets the clock to that time pressing the buttons at 30Hz. VERY FAST.

My code for scanning the keypad(in case you were wondering).
Code:
void getKey() {
  
  for(int col = 0; col < 3; col++) {
    
    digitalWrite(colPin[col], LOW);
    
    for(int row = 0; row < 4; row++) {
      if(!digitalRead(rowPin[row])) {
        lastPressed = key[row][col];
        pressCount++;                       //for telling if a new key was pressed
        delay(debounceTime);
      }
    }
    
    digitalWrite(colPin[col], HIGH);
    
  }
}


Pretty straight forward. There is more to it obviously. For instance the code that makes it so it will only take the time input when the "*" has been pressed first and so on..

Oh.. I can also set my alarm from my cell phone.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see your code is a tiny bit more efficient than mine.  smiley-razz

I will try your approach as it will be a lot easer to maintain in the future.  
« Last Edit: August 13, 2010, 05:04:24 am by zabouth » Logged

Vermont, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 170
ElectroMech
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I wrote my own code as a learning experience.. I have since tried using the Keypad library and I have to say, it is very difficult to work with a keypad when you don't know what's happening in the background. I found that my sketch along with Serial.print functions everywhere is smaller in size than the basic example(below) for the library...(compiles to 3,492 bytes)
Code:
#include <Keypad.h>

const byte rows = 4; //four rows
const byte cols = 3; //three columns
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};
byte rowPins[rows] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[cols] = {3, 4, 5}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

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

void loop(){
  char key = keypad.getKey();
  //boolean state = keypad.getState();
  
  if (key != NO_KEY){
    Serial.println(key);
  }
}
I don't, however, have the ability to use multiple keypads. I suppose I could theoretically add the extra keypads by giving them different names(IO pins might be scarce). I have functions that tell me things like "new_key_pressed()" since getKey (or whatever) may not tell you if a new key was pressed if the same one was pressed. I suppose that "KeypadState getState()" might be used, but I could not figure it out.

My sketch also involves the functionality to generate the button presses(for setting the alarm clock), but when compiled is about half the size:
Quote
Binary sketch size: 1742 bytes (of a 30720 byte maximum)
So where does all of the extra usage of memory come from?

pat
Logged

Pages: [1]   Go Up
Jump to: