View previous topic :: View next topic |
Author |
Message |
ercarlitosg
Joined: 08 Sep 2014 Posts: 20
|
Problem with 3x4 keypad |
Posted: Fri Jun 26, 2015 7:48 pm |
|
|
Hello,
I am having trouble with a 3x4 keypad. I am using the flex_kbd driver inverted by me, because I am using pull down resistors instead of pull ups.
Here is the code of flex_kbd:
Code: |
///////////////////////////////////////////////////////////////////////////
//// Flex_KBD.C ////
//// Generic keypad scan driver ////
//// ////
//// kbd_init() Must be called before any other function. ////
//// ////
//// c = kbd_getc(c) Will return a key value if pressed or /0 if not ////
//// This function should be called frequently so as ////
//// not to miss a key press. ////
//// ////
///////////////////////////////////////////////////////////////////////////
//Keypad connection:
#define COL0 PIN_A0
#define COL1 PIN_B1
#define COL2 PIN_B0
#define ROW0 PIN_A1
#define ROW1 PIN_A2
#define ROW2 PIN_A3
#define ROW3 PIN_A4
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (1);
else
return (0);
}
char kbd_getc( ) {
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : output_high(col0);
output_low(col1);
output_low(col2);
break;
case 1 : output_low(col0);
output_high(col1);
output_low(col2);
break;
case 2 : output_low(col0);
output_low(col1);
output_high(col2);
break;
}
if(kbd_down) {
if(!ALL_ROWS()) {
kbd_down=false;
kchar=last_key;
last_key='\0';
}
} else {
if(ALL_ROWS()) {
if(input (row0))
row=0;
else if(input (row1))
row=1;
else if(input (row2))
row=2;
else if(input (row3))
row=3;
last_key =KEYS[row][col];
kbd_down = true;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
|
I am always getting 0 when calling kbd_getc.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 26, 2015 9:01 pm |
|
|
Put 10K pullup resistors on all the row pins.
This circuit is what you need on each of the row pins:
Code: |
+5v
|
<
> 10K
<
|
PIC pin -------o-------- Keypad row pin
|
If your PIC is running at +3.3v, then use that for the pullup voltage. |
|
|
ercarlitosg
Joined: 08 Sep 2014 Posts: 20
|
|
Posted: Sat Jun 27, 2015 4:31 am |
|
|
PCM programmer wrote: | Put 10K pullup resistors on all the row pins.
This circuit is what you need on each of the row pins:
Code: |
+5v
|
<
> 10K
<
|
PIC pin -------o-------- Keypad row pin
|
If your PIC is running at +3.3v, then use that for the pullup voltage. |
No I can't, instead of pull-up I must use pull down. I can't modify the board |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jun 27, 2015 4:52 am |
|
|
Please post a 'link' to the KPD schematic or mfr/make/model....
Jay |
|
|
ercarlitosg
Joined: 08 Sep 2014 Posts: 20
|
|
Posted: Sun Jun 28, 2015 3:30 am |
|
|
temtronic wrote: | Please post a 'link' to the KPD schematic or mfr/make/model....
Jay |
It's a standard black keypad. I don't have the model |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Sun Jun 28, 2015 4:23 am |
|
|
The problem is that your 'premise' is wrong.
You are starting from the flexible driver, so (say):
Code: |
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (0);
else
return (1);
}
|
and then reversing the 'output' of this:
Code: |
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (1);
else
return (0);
}
|
This is not what you have to do, to work with the signals using the other polarity.
You need to reverse the _input_ of the tests. So (for instance):
Code: |
short int ALL_ROWS (void)
{
if (!input (row0)) & (!input (row1)) & (!input (row2)) & (!input (row3)))
return (1);
else
return (0);
}
|
Note the negation of the inputs.
It is your input levels that have changed, not the logic of the tests.....
You need to re-think how the driver works, and reverse every actual output signal, and the input tests.
Last edited by Ttelmah on Sun Jun 28, 2015 9:29 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Jun 28, 2015 4:51 am |
|
|
re: ...It's a standard black keypad..
Hopefully you've 'rung out' AKA decoded which pins do what function. There is NO 'standard' for keyboards. I have 4 'standard black keyboards' in a drawer here ALL have different matrices for the 3x4 layout ! One is actually a 2x6 layout, arrgh !!
So please don't get caught by the 'standard black keyboard' idea. Same holds true for 2x16 LCD modules.....
Jay |
|
|
ercarlitosg
Joined: 08 Sep 2014 Posts: 20
|
|
Posted: Tue Jun 30, 2015 6:48 am |
|
|
temtronic wrote: | re: ...It's a standard black keypad..
Hopefully you've 'rung out' AKA decoded which pins do what function. There is NO 'standard' for keyboards. I have 4 'standard black keyboards' in a drawer here ALL have different matrices for the 3x4 layout ! One is actually a 2x6 layout, arrgh !!
So please don't get caught by the 'standard black keyboard' idea. Same holds true for 2x16 LCD modules.....
Jay |
OK, thanks I am almost new to electronics dveloping. |
|
|
ercarlitosg
Joined: 08 Sep 2014 Posts: 20
|
|
Posted: Tue Jun 30, 2015 7:16 am |
|
|
Ttelmah wrote: | The problem is that your 'premise' is wrong.
You are starting from the flexible driver, so (say):
Code: |
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (0);
else
return (1);
}
|
and then reversing the 'output' of this:
Code: |
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (1);
else
return (0);
}
|
This is not what you have to do, to work with the signals using the other polarity.
You need to reverse the _input_ of the tests. So (for instance):
Code: |
short int ALL_ROWS (void)
{
if (!input (row0)) & (!input (row1)) & (!input (row2)) & (!input (row3)))
return (1);
else
return (0);
}
|
Note the negation of the inputs.
It is your input levels that have changed, not the logic of the tests.....
You need to re-think how the driver works, and reverse every actual output signal, and the input tests. |
Thanks for your tip. I tought inverting the function return value would work, but no.
Finally solved, you wouldn't expect what happened. Some days ago, I moved the project to my bitbucket git repository. No problem, all fine, except that the ccs ide was opening the flex_kbd.c from the old location so any modification I did was to the old file, not to the new file in the git repository.
Also, here I post the code if anyone wants the flex_kbd driver for pull down resistors
Code: |
///////////////////////////////////////////////////////////////////////////
//// Flex_KBD.C ////
//// Generic keypad scan driver ////
//// ////
//// kbd_init() Must be called before any other function. ////
//// ////
//// c = kbd_getc(c) Will return a key value if pressed or /0 if not ////
//// This function should be called frequently so as ////
//// not to miss a key press. ////
//// ////
///////////////////////////////////////////////////////////////////////////
static uint8_t kbd_call_count;
static short int kbd_down;
static char last_key;
static uint8_t col;
//Keypad connection:
#define COL0 PIN_A0
#define COL1 PIN_B1
#define COL2 PIN_B0
#define ROW0 PIN_A4
#define ROW1 PIN_A3
#define ROW2 PIN_A2
#define ROW3 PIN_A1
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
short int ALL_ROWS (void)
{
if (!input (row0) & !input (row1) & !input (row2) & !input (row3))
return (0);
else
return (1);
}
char kbd_getc( ) {
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : output_high(col0);
output_low(col1);
output_low(col2);
break;
case 1 : output_low(col0);
output_high(col1);
output_low(col2);
break;
case 2 : output_low(col0);
output_low(col1);
output_high(col2);
break;
}
if(kbd_down) {
if(!ALL_ROWS()) {
kbd_down=false;
kchar=last_key;
last_key='\0';
}
} else {
if(ALL_ROWS()) {
if(input (row0)) {
row=0;
puts("ROW 0");
} else if(input (row1)) {
row=1;
puts("ROW 1");
} else if(input (row2)) {
row=2;
puts("ROW 2");
} else if(input (row3)) {
row=3;
puts("ROW 3");
}
last_key =KEYS[row][col];
kbd_down = true;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
|
|
|
|
|