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 CCS Technical Support

Can i modify keypad library kbd.c to work with 1x4 keypad
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Mon Aug 14, 2017 2:51 pm     Reply with quote

Thank you guys Smile



I tested the keypad using scope using only pull-up resistors tied to 5V
the signal was as in the following:



Would it be better to use external pull-up resistors or internal ?

Sorry for bothering you . Sad
Your effort is highly appreciated Smile
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 14, 2017 3:00 pm     Reply with quote

Looks good to me, nice clean square edges, which is what you want.

The proof is pressing all the keys and confirm it works in the 'Real World'.

I use external 10K resistors only because some I/O pins on some PICS do NOT have internal pullups available. While it take a very small space on the PCB, it means the hardware is aways the same from product to product and I can substitute the PIC if I have to, without worrying if it'll work or have to change code.

Jay
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Mon Aug 14, 2017 3:45 pm     Reply with quote

temtronic wrote:
Looks good to me, nice clean square edges, which is what you want.

The proof is pressing all the keys and confirm it works in the 'Real World'.

I use external 10K resistors only because some I/O pins on some PICS do NOT have internal pullups available. While it take a very small space on the PCB, it means the hardware is aways the same from product to product and I can substitute the PIC if I have to, without worrying if it'll work or have to change code.

Jay



so just connect the keypad with pull-up resistor ^^

thank you temtronic Smile
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Fri Aug 18, 2017 8:27 am     Reply with quote

Hi all ^_^

I tried to use pins rb4-rb7 as output.
I modified the kbd_1row as the following:
Code:

#if defined use_portb_kbd
   #byte kbd = getenv("SFR:PORTB")
#else
   #byte kbd = getenv("SFR:PORTD")
#endif


#define ROW0 (1 << 0)   // Pin B0
#define ROW1 (1 << 1)   // Pin B1
#define ROW2 (1 << 2)   // Pin B2
#define ROW3 (1 << 3)   // pin B3

#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS)

// Keypad layout:
char const KEYS[4] = {'1','2','3','4'};


void kbd_init()
{
//port_b_pullups(0x0F);
set_tris_b(0x0f);
}


char kbd_getc(void)
{
static int1 kbd_down = FALSE;
static char last_key = '\0';
BYTE kchar;
BYTE row;
static unsigned int8 temp=0;
kchar='\0';

kbd = input_b()&0x0f;

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];
      kbd_down = TRUE;
     }
  }

delay_ms(10);  // Debounce delay

return(kchar);
}


char kbd_pressed(void){
char keypress;
keypress=kbd_getc();
   while(keypress=='\0'){
   keypress=kbd_getc();
   }
return (keypress);
}


Test code:
Code:

#include <16F877A.h>
//#rom 0X2100= {11,14,0,16,4,27,0,0,0,0,0}
//#rom 0X2100= {0,0,0,0,0,0,0,0,0}
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPROTECT,PUT, NOLVP

#use rs232(baud=9600, UART, ERRORS)
#use fast_io(b)
#define use_portb_kbd
#include "kbd_1row.c"

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

printf("Ready\n\r");
//set_tris_b(0x0f);
kbd_init();

while(TRUE)
  {
  k=kbd_pressed();
   printf("key:%c\n\r",k);
 
output_toggle(pin_b7);
     
  }
 

}


Pin B7 should toggle every key pressed but it remains low all the time.

I think the problem is here:
Code:

#if defined use_portb_kbd
   #byte kbd = getenv("SFR:PORTB")
#else
   #byte kbd = getenv("SFR:PORTD")
#endif


Code:

kbd = input_b()&0x0f;


Regards
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Fri Aug 18, 2017 12:41 pm     Reply with quote

hi,

i modified kbd_getc as the following

Code:


char kbd_getc(void)
{
static int1 kbd_down = FALSE;
static char last_key = '\0';
BYTE kchar;
BYTE row;


byte RDio=0;



static unsigned int8 temp=0;
kchar='\0';

//kbd = input_b()&0x0f;
RDio= input_b()&0x0f;

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];
      kbd_down = TRUE;
     }
  }

delay_ms(10);  // Debounce delay

return(kchar);
}



pins rb4-rb7 now working fine as o/p ^^

any comments on my modification ?

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Fri Aug 18, 2017 12:48 pm     Reply with quote

You have fiddled with the code without understanding it.

kbd is already defined as a variable to _input_ from the keyboard. That is what the #byte is doing.
In this line:
kbd = input_b()&0x0f;
You are reading portB, then writing the value back out to portB. No wonder it doesn't work....

The rest of the code correctly uses the kbd as input.
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Fri Aug 18, 2017 4:13 pm     Reply with quote

Ttelmah wrote:
You have fiddled with the code without understanding it.

kbd is already defined as a variable to _input_ from the keyboard. That is what the #byte is doing.
In this line:
kbd = input_b()&0x0f;
You are reading portB, then writing the value back out to portB. No wonder it doesn't work....

The rest of the code correctly uses the kbd as input.


thanks a lot Smile

so no need to use this line ?

Code:

kbd=input_b();


Sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Fri Aug 18, 2017 10:51 pm     Reply with quote

Exactly.

However it is important how your TRIS is being used. The code here relies on the keyboard bits being set as inputs. They will be provided you don't use a port wide output. You talk about outputting on the high four bits of the port. If you are using the standard output_high, or output_low on these, the low four bits will happily stay as they are. However if you did 'output_b' (port wide output), this would set the kbd bits as outputs and stop things working.
sareehy



Joined: 03 May 2016
Posts: 20

View user's profile Send private message

PostPosted: Sat Aug 19, 2017 12:58 am     Reply with quote

Ttelmah wrote:
Exactly.

However it is important how your TRIS is being used. The code here relies on the keyboard bits being set as inputs. They will be provided you don't use a port wide output. You talk about outputting on the high four bits of the port. If you are using the standard output_high, or output_low on these, the low four bits will happily stay as they are. However if you did 'output_b' (port wide output), this would set the kbd bits as outputs and stop things working.


sorry for bothering you :(

Code:




#if defined use_portb_kbd
   #byte kbd = getenv("SFR:PORTB")
#else
   #byte kbd = getenv("SFR:PORTD")
#endif


#define ROW0 (1 << 0)   // Pin B0
#define ROW1 (1 << 1)   // Pin B1
#define ROW2 (1 << 2)   // Pin B2
#define ROW3 (1 << 3)   // pin B3

#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS)

// Keypad layout:
char const KEYS[4] = {'1','2','3','4'};


void kbd_init()
{
//port_b_pullups(0x0F);
set_tris_b(0x0f);
}


char kbd_getc(void)
{
static int1 kbd_down = FALSE;
static char last_key = '\0';
BYTE kchar;
BYTE row;

static unsigned int8 temp=0;
kchar='\0';

//kbd = input_b();

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];
      kbd_down = TRUE;
     }
  }

delay_ms(20);  // Debounce delay

return(kchar);
}


char kbd_pressed(void){
char keypress;
keypress=kbd_getc();
   while(keypress=='\0'){
   keypress=kbd_getc();
   }
return (keypress);
}









test code


Code:


#include <16F877A.h>
//#rom 0X2100= {11,14,0,16,4,27,0,0,0,0,0}
//#rom 0X2100= {0,0,0,0,0,0,0,0,0}
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPROTECT,PUT, NOLVP
#use rs232(baud=9600, UART, ERRORS)
#use fast_io(b)
#define use_portb_kbd
#include "kbd_1row.c"

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

printf("Ready\n\r");
//set_tris_b(0x0f);
kbd_init();

while(TRUE)
  {
  k=kbd_pressed();
   printf("key:%c\n\r",k);
 
output_toggle(pin_b7);
     
  }
 

}



i modified kbd_1row and it worked fine..

thank you for your appreciated effort Smile
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 Previous  1, 2
Page 2 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