Go Down

Topic: Keypad Lock (reinventing the wheel) (Read 1 time) previous topic - next topic

zabouth

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: [Select]

/*
* 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;
}






P_Wood

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: [Select]
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.

zabouth

#2
Aug 13, 2010, 10:02 am Last Edit: Aug 13, 2010, 12:04 pm by zabouth Reason: 1
I see your code is a tiny bit more efficient than mine.  :P

I will try your approach as it will be a lot easer to maintain in the future.  

P_Wood

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: [Select]
#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

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy