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 3x4 keypad

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ercarlitosg



Joined: 08 Sep 2014
Posts: 20

View user's profile Send private message

Problem with 3x4 keypad
PostPosted: Fri Jun 26, 2015 7:48 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 26, 2015 9:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 4:31 am     Reply with quote

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: 9196
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 4:52 am     Reply with quote

Please post a 'link' to the KPD schematic or mfr/make/model....


Jay
ercarlitosg



Joined: 08 Sep 2014
Posts: 20

View user's profile Send private message

PostPosted: Sun Jun 28, 2015 3:30 am     Reply with quote

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: 19431

View user's profile Send private message

PostPosted: Sun Jun 28, 2015 4:23 am     Reply with quote

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: 9196
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 28, 2015 4:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 30, 2015 6:48 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 30, 2015 7:16 am     Reply with quote

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 Embarassed Embarassed Embarassed 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);
}

Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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