CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem with 4x4 Keypad Scan (Without Pull-up)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest101
Guest







Problem with 4x4 Keypad Scan (Without Pull-up)
PostPosted: Tue Feb 12, 2008 10:28 pm     Reply with quote

Hi all,
i did some modification to the codes which i found here but i cant seem to get it to work on hardware. I've successfully simulated it using proteus. Can someone help me out with this? Thanks in advance

Quote:

#include <18F2680.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
// =============================

//Keypad connection:
#define row0 PIN_A0
#define row1 PIN_A1
#define row2 PIN_A2
#define row3 PIN_A3
#define col0 PIN_C0
#define col1 PIN_C1
#define col2 PIN_C2
#define col3 PIN_C3

// Keypad layout:
int const KEYS[4][4] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};

#define KBD_DEBOUNCE_FACTOR 33

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);
output_low(col3);
break;

case 1:
output_low(col0);
output_high(col1);
output_low(col2);
output_low(col3);
break;

case 2:
output_low(col0);
output_low(col1);
output_high(col2);
output_low(col3);
break;

case 3:
output_low(col0);
output_low(col1);
output_low(col2);
output_high(col3);
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==4)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}

//===========================
void main()
{
char k;

printf("\r\Starting ...");

while(TRUE)
{
k=kbd_getc();
if(k!=0)
{
if(k=='*')
printf("%c", '*');
else
printf("%c", k);
}
}

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 12, 2008 10:40 pm     Reply with quote

Add pull-up resistors on the row pins. You can use 10K resistors.
fms



Joined: 12 Feb 2008
Posts: 4

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 2:14 am     Reply with quote

This would result changes in the hardware design. There are many design which uses this concept (without pullup). but why it wouldn't work using PIC C?
Ttelmah
Guest







PostPosted: Wed Feb 13, 2008 6:06 am     Reply with quote

Row scanning like this, should work fine with CCS. I do it on several keyboards OK.
So, there has to be something wrong in the code, or approach...
The code as written, does make it quite hard to follow the sequence being used.
Comments:
You seem to only change the column addressed, when the debounce factor is met. It is reset, whenever the routine exits, so will never go true...
Before testing all rows, you really want to initially set all columns, then this will say if any key is pressed. At present, because of the comment above, _no_ column will be set...
The code failing, is not because of CCS.

Best Wishes
fms



Joined: 12 Feb 2008
Posts: 4

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 7:11 am     Reply with quote

Ttelmah wrote:
Row scanning like this, should work fine with CCS. I do it on several keyboards OK.

Dear Ttelmah,
Thanks for the explanation. mind if u share us your codes? This would help me alot.
fms



Joined: 12 Feb 2008
Posts: 4

View user's profile Send private message

4x4 Keypad Scan (Without Pull-up) (SOLVED)
PostPosted: Thu Feb 14, 2008 12:12 pm     Reply with quote

Dear ALL,
I've retested and reconfirmed that my code is just fine and working perfectly. The problem is with the floating of my row input pins. Pull them low and everything works beautifully. Hope this will help many out there.

Code:

//Code Edited by AdrianKhoo from CCS forum (www.ccsinfo.com).
//Keypad connection:
#define ROW0 PIN_A0
#define ROW1 PIN_A1
#define ROW2 PIN_A2
#define ROW3 PIN_A3
#define COL0 PIN_C0
#define COL1 PIN_C1
#define COL2 PIN_C2
#define COL3 PIN_C3

// Keypad layout:
int const KEYS[4][4] =
{{'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'}};
 
#define KBD_DEBOUNCE_FACTOR 33

short int ROW_HIGH()
{
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);
         output_low(col3);
         break;
         
         case 1:
         output_low(col0);
         output_high(col1);
         output_low(col2);
         output_low(col3);
         break;
         
         case 2:
         output_low(col0);
         output_low(col1);
         output_high(col2);
         output_low(col3);
         break;
         
         case 3:
         output_low(col0);
         output_low(col1);
         output_low(col2);
         output_high(col3);
         break;
      }

   if(kbd_down)
   {
      if(!ROW_HIGH())
         {
            kbd_down=false;
            kchar=last_key;
            last_key='\0';
         }
   }
   else
   {
      if(ROW_HIGH())
      {
         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==4)
            col=0;
         }
     }
   kbd_call_count=0;
  }
return(kchar);
}

//===========================
void main()
{
char k;

printf("\r\Starting ...");

while(TRUE)
  {
   k=kbd_getc();
   if(k!=0)
     {
      if(k=='*')
         printf("%c", '*');
      else
         printf("%c", k);
     }
  }
}


Last edited by fms on Wed Apr 02, 2008 11:12 am; edited 1 time in total
D-Kens



Joined: 09 May 2005
Posts: 35
Location: Toulouse (France)

View user's profile Send private message MSN Messenger

PostPosted: Tue Mar 25, 2008 8:34 am     Reply with quote

Thanks a lot for your code : I just began working on a project where I have to use a 4x3 keypad, and couldn't lose much time on writing code to handle it with my PIC. You made me save lots of time... Wink
fms



Joined: 12 Feb 2008
Posts: 4

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 11:11 am     Reply with quote

Really glad it did helped someone out. Worth all the debugging effort. Thanks CCS Forum and PCM programmer for the pull up version.
filjo



Joined: 29 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 10:07 am     Reply with quote

Hi

I try make one program using keypad 3x4 and I like use ports D I used for example "c = kbd_getc(c)" I used driver KBDD.c

but where I connect my keypad to PIC ports?

for example, I have col0, col1, col2 and row0, row1 ,row2 ,row3 but I dont know connect this, D0,D1,D2,D3,D4,D5,D6,D7...

some one can help me?

regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 11:22 am     Reply with quote

My post in this thread has an explanation of the keypad connections.
http://www.ccsinfo.com/forum/viewtopic.php?t=21852

Mark's post in this thread explains how to interpret the CCS #define
statements for the pin connections in kbd.c.
http://www.ccsinfo.com/forum/viewtopic.php?t=25488

Another thread with helpful information on the keypad connections:
http://www.ccsinfo.com/forum/viewtopic.php?t=23467
filjo



Joined: 29 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 12:41 pm     Reply with quote

Hi PCM programmer thanks for help me ...

I configure KBDD.c in my case stay iqual because I use PIC18F452 and need connect keypad to port D.

but I my problem continue... where I connect my keypad? what is the PIN's of th e PIC?

my key pad is:

C0 | C1 | C2
_________________
R0 | 1 | 2 | 3
R1 | 4 | 5 | 6
R2 | 7 | 8 | 9
R3 | * | 0 | #

Some one can help me comple this?
C0=RD..
C1=RD..
C2=RD..
R0=RD..
R1=RD..
R2=RD..
R3=RD..

regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 2:50 pm     Reply with quote

#define COL0 (1 << 5) // Pin D5
#define COL1 (1 << 6) // Pin D6
#define COL2 (1 << 7) // Pin D7

#define ROW0 (1 << 1) // Pin D1
#define ROW1 (1 << 2) // Pin D2
#define ROW2 (1 << 3) // Pin D3
#define ROW3 (1 << 4) // Pin D4

There is no connection to Pin D0.

Pins D1, D2, D3, D4 must have a 10K pull-up resistor on each pin.
filjo



Joined: 29 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 3:13 pm     Reply with quote

Hi

I dont know how I can thanks your help.... thanks

one question:

KBD.C for my case stay:

Quote:


// Un-comment the following define to use port B
// #define use_portb_kbd TRUE

// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins


#if defined(__PCH__)
#if defined use_portb_kbd
#byte kbd = 0xF81 // This puts the entire structure
#else
#byte kbd = 0xF83 // This puts the entire structure
#endif
#else
#if defined use_portb_kbd
#byte kbd = 6 // on to port B (at address 6)
#else
#byte kbd = 8 // on to port D (at address 8)
#endif
#endif

#if defined use_portb_kbd
#define set_tris_kbd(x) set_tris_b(x)
#else
#define set_tris_kbd(x) set_tris_d(x)
#endif



//Keypad connection: (for example column 0 is B2)
// Bx:

#ifdef blue_keypad ///////////////////////////////////// For the blue keypad
#define COL0 (1 << 2)
#define COL1 (1 << 3)
#define COL2 (1 << 6)

#define ROW0 (1 << 4)
#define ROW1 (1 << 7)
#define ROW2 (1 << 1)
#define ROW3 (1 << 5)

#else ////////////////////////////////////////////////// For the black keypad
#define COL0 (1 << 5) //PIN D5
#define COL1 (1 << 6) //PIN D6
#define COL2 (1 << 7) //PIN D7

#define ROW0 (1 << 1) //PIN D1
#define ROW1 (1 << 2) //PIN D2
#define ROW2 (1 << 3) //PIN D3
#define ROW3 (1 << 4) //PIN D4
#endif

#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)

// 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() {
}

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 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
case 2 : set_tris_kbd(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;
}

if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);




I need delete firsts defines of COLs and ROWs?


but if you dont import you can explain me how you know this pinout? I like understand more about this driver.

this is for an car alarm whitch car locator... I stay make an prototype ;)
you can see more about my projects on http://filjoa.myvnc.com


regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 4:12 pm     Reply with quote

Quote:
I need delete firsts defines of COLs and ROWs?

No. The 'blue_keyboard' constant is not defined anywhere, so
the code for it will not be compiled. Instead, the code for the
"black keyboard" will be compiled.


Quote:
can explain me how you know this pinout?

Look at these statements:
Code:

#define COL0 (1 << 5) //PIN D5
#define COL1 (1 << 6) //PIN D6
#define COL2 (1 << 7) //PIN D7

#define ROW0 (1 << 1) //PIN D1
#define ROW1 (1 << 2) //PIN D2
#define ROW2 (1 << 3) //PIN D3
#define ROW3 (1 << 4) //PIN D4

The expression (1 << 5) defines a bitmask. It means 0b00000001
shifted left by 5 bit positions. It's the same as this:
Code:
#define COL0 0b00100000

Port D has 8 bits: D7 D6 D5 D4 D3 D2 D1 D0
Each bit corresponds to an i/o pin on Port D.
A bit in the following position corresponds to bit 5, which is pin D5 on Port D:
Code:
#define COL0 0b00100000
filjo



Joined: 29 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Tue Apr 29, 2008 6:54 pm     Reply with quote

Hi

now I understand... thanks

best regards PCM programmer, you are a crak ;)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group