Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

keypad interfacing with PIC18F4520

Status
Not open for further replies.

knull

Newbie level 3
Newbie level 3
Joined
Jul 26, 2019
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
27
Hi newbie here, i have 2 questions.
1) How do i display a 2 digit No. on keypress?
2) When I press 5 on the keypad, the LCD displays '5'. How do i then store the value ive inputted?
I want to compare the number ive pressed to a randomly generated number.

this is my existing code
what works: i can display all single digit/characters on each key press but i cant display more than 1 digit on single keypress. keypad uses 74C922 encoder
lcd.PNG-> info on the lcd im using
 

Please post code on Edaboard and place it inside code tags, not everyone has access to some external file servers.

1.
There are two options here, if you only want to display more than one digit, advance the LCD cursor to the next position, however this only stores the character in the LCD, you can't use it for anything else.
The better solution is to save the keys to memory as they are pressed, you can use a simple array to do this. For example "keysPressed[10];" would have space to store 10 digits.
If you use the memory option, consider there are some other requirements:
a. some variable to point to the position in the array the key is to be stored, you would advance this (increment it) to the next location as each key is pressed.
b. a check that stops you overflowing the array when you have reached it's capacity.
c. a way of clearing the array and moving back to the first location so it is ready for use again. For example an 'Enter',' Reset' or 'Clear' key.

2.
If you use the memory option, just compare your random number with the entries in the array, one by one and see if they match.

You can hugely simplify your code by using an array of constants instead of all those 'else if' statements. Just put the converted value in the array and use the value from the 74C922 as the index to the array.

Brian.
 

Hi,

The picture you posted seems to be a part of the HD44780 instruction set.

How does this belong to your initial question "interfacing keypad with PIC"?

...this more belongs to "interfacing display with PIC".

Thus I'm not sure whether your problem is related to keypad and it's protocol or display...

An alphanumeric display with x columns and y lines...
So on a 4 x 16 display you should be able to display 64 characters at once.
I don't see a problem to display 2 characters..

Klaus
 

Hi Brian, im a student and new to C.
Could you assist me with an example? or a guide i could follow

array of constants instead of all those 'else if' statements. Just put the converted value in the array and use the value from the 74C922 as the index to the array.

point to the position in the array the key is to be stored, you would advance this (increment it) to the next location as each key is pressed.
 

I will try to explain.

All those "else if" instructions just take a value and return a value, in your case taking the numbers 0x00 to 0x0F from the 74C922 and returning a constant according to the character to be displayed. Note that whatever the number from the 74C922 is, you still have to make 16 comparisons even though only one can match the condition. There are two ways to make it simpler and faster:
1. use a look-up table, this is like your key[] array but has the final values you want in it instead of converting some to ASCII (adding '0') and not others.
Code:
const char key[] = {'1','2','3','F','4','5','6','E','7','8','9','D','A','0','B','C'};  // 'const' makes the compiler store it in program memory to save valuable RAM
.
.
LCD_sendData(key[dataIn]);
LCD_sendCW(0b10000000);

2. use a switch and case statement. For example:
Code:
switch(dataIn)
{  
case 0: LCD_sendData('1');
           break;
case 1: LCD_sendData('2');
           break;
.
.
case 0x0F: LCD_sendData('C');
}
LCD_sendCW(0b10000000);
note that the 'break' skips the remainder of the checks if a match is found and the 'LCD_sendCW' is only needed once at the end.

To store the data, create an array to save it (note this time it has to be in RAM as it will change so we don't use 'const) for example:
Code:
#define MAX_DATA_LENGTH 10  // use the size of the biggest length of digits you will use
char DataEntered[MAX_DATA_LENGTH];  //  create an array of that size
char DataPointer = 0;  // this is to point to the place in the array the number will be stored (its index)
then as you get each digit you store it like this:
Code:
DataEntered[DataPointer] = digit;
if(DataPointer < MAX_DATA_LENGTH) DataPointer++;
That last line prevents you overflowing the array if you add more digits, basically it just keeps overwriting the previous digit.
Note that by defining and using MAX_DATA_LENGTH like that, if you change the size you need, it will take effect in all the instructions using that definition. It's much easier than hard coding the sizes then finding you need to change them later!
You also need a way to store a new set of digits, it is very easy, just reset DataPointer to zero!
The digits you enter will be in consecutive locations in the 'DataEntered[]' array.

Brian.
 
I will try to explain.
Code:
DataEntered[DataPointer] = digit;
if(DataPointer < MAX_DATA_LENGTH) DataPointer++;

The digits you enter will be in consecutive locations in the 'DataEntered[]' array.
Brian.

How will the value of the key that ive pressed, be read and stored into the array DataEntered[]?

The variable "digit" in my case refers to value of the key? Which would be key[dataIn]?

digit = key[dataIn] ?

If not then do i have to modify the way i read the switch to return values?


from my understanding
Code:
//store max 2 digits
int num[2];
printf("Enter number");
scanf_s("%d",num);
printf("The number you entered is: %d",num);

this is essentially what im trying to do but displayed on a LCD using keypad
 

"dataIn" is the value read from the 74C922 so its value (after masking the top PORTA bits) is 0x00 to 0x0F.
"key[..]" is an array, a look up table. So key[dataIn] will be the value in the array at position dataIn. Using the example in post #5, if the 74C944 returned 0011 (3 in decimal) it would return 'F' from the table because key[3] = 'F'.

It is your choice whether to store the value directly from the 74C922 in memory then convert it to real key number afterwards or to convert it first and store the converted value, it works equally well both ways.
How will the value of the key that ive pressed, be read and stored into the array DataEntered[]?
To store the digit, all you do is load the value into your store array. DataEntered[] in my example is where the values are stored but being an array it has more than one address so you need the pointer to tell it which position is to be used.

I think you should restructure your code, how you do it is your own choice of course but I would do it this way:
Code:
.
.
while(1)
{
  if(DA == 1)
  {
      LCD_sendData(key[PORTA & 0x0F]);
      LCD_sendCW(0x80);

      // put extra code to store digits if needed here
  }
}
.
.
so you only enter your key reading routine at all when DA is active. Note that this doesn't need the 'dataIn' variable at all and that code replaces your entire readKey() routine!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top