Poll
Question: .
. - 3 (75%)
. - 1 (25%)
Total Voters: 4

Pages: [1]   Go Down
Author Topic: sparkfun 4x4 keypad matrix  (Read 2905 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 41
I love YaBB 1G - SP1!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was looking through the  sparkfun website and found these keypad matrices....



which allow each button to be individually lit by an led. i've decided to use a keypad encoder to limit the number of pins i need to use to run it, so i have a couple of 74C922 keypad encoders on order from Farnell. heres the data sheet http://www.elexp.com/tips/74C922.pdf

the idea is that the 74C922 ic reads the key pad matrix, and when a button is pressed, it sends a logic signal via the data pin to the arduino, which tells the arduino to read the four input pins from the 74C922 and to save these inputs as a 4 digit binary number. this 4 digit binary number relates to one of the 16 buttons on the keypad.


so far i have written this code, that reads the data pin, and if its HIGH, then it switches on an led on pin 13, and then reads the input pins and prints the data to the serial connection.

Code:
int dataPin = 2; // data pin
int in1Pin = 3; // input pin 1
int in2Pin = 4; // input pin 2
int in3Pin = 5; // input pin 3
int in4Pin = 6; // input pin 4
int ledPin = 13; // led pin
int val = 0;

void setup() {
  pinMode(dataPin, INPUT); // declare pins as input or output
  pinMode(in1Pin, INPUT);
  pinMode(in2Pin, INPUT);
  pinMode(in3Pin, INPUT);
  pinMode(in4Pin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600); // begin serial
}

void loop() {
   val = digitalRead(dataPin);  // read data pin value
  if (val == HIGH) {  // if HIGH
  digitalWrite(ledPin, HIGH);     // switch on led pin  
    digitalRead(in1Pin); // read inputs
    digitalRead(in2Pin);
    digitalRead(in3Pin);
    digitalRead(in4Pin);
    Serial.print(in1Pin, BYTE); // print inputs to serial connection
    Serial.print(in2Pin, BYTE);
    Serial.print(in3Pin, BYTE);
    Serial.print(in4Pin, BYTE);
  } else {
    digitalWrite(ledPin, LOW); // if data pin LOW, switch off led pin, and do nothing.
  }
}


it complies fine, but is so far untested as i dont have the parts yet. what i would like to do is to hold the 4 digit binary number as a string, then print to the serial port. at the moment i think this code will print each input byte individually, but i dont really understand how to store it as a string just yet.

so, any comments or ideas to make it run smoother?


cheers,

bod.
Logged

Amsterdam
Offline Offline
Full Member
***
Karma: 1
Posts: 138
he's looking at you, kiddy...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

may I suggest that you give the result of the digitalRead action to some variable in the main loop?

quote:

void loop() {
   val = digitalRead(dataPin);  // read data pin value
  if (val == HIGH) {  // if HIGH
  digitalWrite(ledPin, HIGH);     // switch on led pin  
    digitalRead(in1Pin); // read inputs
    digitalRead(in2Pin);
    digitalRead(in3Pin);
    digitalRead(in4Pin);

/quote

like:
 tempVar1 = digitalRead(in1Pin);
tempVar2 = digitalRead(in2Pin);

etc.

so that the read values are somewhere to get.
Logged

--
"We're all in this together..."

Montréal, Qc
Offline Offline
Full Member
***
Karma: 0
Posts: 185
Practice safe hex!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have just done this using a Parallax 4x4 Keypad and the 74C922. It's a little tricky because you need to pool for changes on data available from LOW to HIGH, and then stop pooling until DA is back to LOW, otherwise it will send the key's value until you release it. There is also some issues with timing. Below is what I came up with (it also includes a little password example... just for fun). Improvements could be made, such as using a "soft delay" with millis() instead of using delay() (if you make it work, can you post an update?).

Code:
/* Parallax 4x4 Keypad using 74C922 16 Keys Encoder
 * ---------------
 *
 * Comments
 *
 * (cleft) 2005 by Matthieu Lalonde
 * <http://smurfturf.net/>
 * <mailto:mlalonde(at)smurfturf(dot)net>
 *
 */
#define BAUD_RATE 9600
#define statusLED 12

// Inputs from the 74C922 16 Keys Encoder
#define inputKey1 8
#define inputKey2 9
#define inputKey3 10
#define inputKey4 11

// The key encoder will provide HIGH on this pin when new data is available
#define dataAvailable 7

// Needed to manage inputs in a proper fashion (one entry per push)
int dataAvail      = LOW;
int lastDataAvail  = LOW;
byte keyValue      = 0;

// We need to slow down things a little, otherwise the 74C922 misbehaves
int interval       = 15;

char passwdValue[5] = {
  15, 3, 13, 1};
char passwdEntry[5];
int  entryNbr   = 0;
int  badTries   = 0;

void setup(void) {
  // initialize inputs/outputs
  pinMode(dataAvailable, INPUT);

  pinMode(inputKey1, INPUT);
  pinMode(inputKey2, INPUT);
  pinMode(inputKey3, INPUT);
  pinMode(inputKey4, INPUT);

  // start serial
  Serial.begin(BAUD_RATE);

  reportAVRState(3,1);
}

void loop(void) {
  dataAvail = digitalRead(dataAvailable);

  // Do we have a change in the state of dataAvailable or was the key just never released?
  if (dataAvail == HIGH && lastDataAvail == LOW) {
    lastDataAvail = dataAvail;
    delay(interval);

    // We do our business here
    keyValue = 0;
    keyValue = (digitalRead(inputKey1) << 3) + (digitalRead(inputKey2) << 2) + (digitalRead(inputKey3) << 1) + digitalRead(inputKey4);

    passwdEntry[entryNbr] = keyValue;

    Serial.print(keyValue, HEX);
    //Serial.println();
    entryNbr++;
    if (entryNbr == 4) {
      Serial.println();
      if (!strCompare(passwdValue, passwdEntry)) {
        Serial.print("We have a winner after ");
        Serial.print(++badTries);
        Serial.println(" times!");
        entryNbr = 0;
        badTries = 0;
      }
      else {
        badTries++;
        Serial.print("We have a loser that tried ");
        Serial.print(badTries);
        Serial.println(" times!");
        entryNbr = 0;
      }
    }
  }
  // We need to reset the state of dataAvailable
  if (dataAvail == LOW && lastDataAvail == HIGH) {
    lastDataAvail = dataAvail;
    delay(interval);
  }
}

int strCompare(char *a, char *b) {
  while (a[0] && b[0]) {
    if (a[0] != b[0]) return 1;
    *a++;
    *b++;
  }

  if (a[0] != 0 || b[0] != 0) return 1;

  return 0; //they are the SAME
}

// Reports the state of the controller via pin 13's led and serial
void reportAVRState(int howManyTimes, int leaveOn) {
  int i;

  pinMode(statusLED, OUTPUT);

  for (i=0; i< howManyTimes; i++) {
    digitalWrite(statusLED, HIGH);
    delay(200);
    digitalWrite(statusLED, LOW);
    delay(200);  
  }

  if (leaveOn) {
    digitalWrite(statusLED, HIGH);
  }

  Serial.println("AVR Initialized");
}

Here is a picture of the circuit (using SparkFun's protoshield):


You can see a video example .
« Last Edit: December 15, 2006, 03:57:52 pm by xSmurf » Logged

"Pilots believe in a clean living... they never drink wisky from a dirty glass."

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

Arduino w / Keypad and feedback.
Goodnight
I'm doing a one pcb, which contains LCD 16x2 74LS164, 4x4 Keypad with PCF8574A / 74C922 for Arduino. You have an Eagle plane - Schematics - as are the connections?
Logged

Pages: [1]   Go Up
Jump to: