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