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

Cant get the Keypad code to work !

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



Joined: 22 Apr 2006
Posts: 87

View user's profile Send private message

Cant get the Keypad code to work !
PostPosted: Sat May 06, 2006 11:39 am     Reply with quote

Hi Can any one tell me why i am geting non stop garbage on the serial monitor with this code . I am new to CCS and would appriciate any help .

I am trying to connect a 4x3 kaypad to PICDEM Mechatronics Board with a 16F917 on the J10 PINS PORTB


Code:
#include "G:\Program Files\PICC\Project\keypad2.h"

//This is a modification of CCS keypad driver (KBDD.c) with flexible pins connections.

//Code:
///////////////////////////////////////////////////////////////////////////
////                             Flex_KBD.C                            ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////       ////
////  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_B5
#define col1 PIN_B6
#define col2 PIN_B7
#define row0 PIN_B1
#define row1 PIN_B2
#define row2 PIN_B3
#define row3 PIN_B4
char kbd_getc( );
short int ALL_ROWS (void);

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

#define KBD_DEBOUNCE_FACTOR 2//33    // Set this number to apx n/333 where
                                  // n is the number of times you expect
                                  // to call kbd_getc each second

void main()
{char key;


  // port_b_pullups(TRUE);

while(1)
{
//printf("KAISER");

key=kbd_getc();
printf(key);
}

}


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_low(col0);
               output_high(col1);
               output_high(col2);
                    break;
         case 1   : output_high(col0);
               output_low(col1);
               output_high(col2);
                    break;
         case 2   : output_high(col0);
               output_high(col1);
               output_low(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);
}

short int ALL_ROWS (void)
{
   if (input (row0) & input (row1) & input (row2) & input (row3))
      return (0);
   else
      return (1);
}
Crying or Very sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 06, 2006 1:21 pm     Reply with quote

You shouldn't start a new thread every time you have a new question
on your keypad program. If you just add another post to your existing
thread, it will get "bumped" to the top of the list.

But anyway, here are some problems I see:

1. You need pull-ups on the Row pins. You have commented out
the line that enables them. You need to uncomment it.

2. In your while() loop, your method of using the keypad driver is
incorrect. You need to check if the returned value ('key') is
non-zero.
The value returned by kbd_getc() is valid only if it's non-zero.
See the CCS example file, EX_LCDKB.C which shows how to do this.

3. You're using printf() incorrectly. Printf needs to know how to
interpret the value that you've given it. If you want to display
a character, then give it the format specifier for a character.
Example:

printf("%c", key);
deltatech



Joined: 22 Apr 2006
Posts: 87

View user's profile Send private message

Cant get the Keypad code to work !
PostPosted: Sat May 06, 2006 3:48 pm     Reply with quote

[color=blue][b]Thanks PCW Programmer you are great help . I changed the code to you sugection and it is almost working . What is happening now is that I smetime get the correct number but most of the time i am getting 1s and 6s continuesly even though i press the key one . i have tried different values in the deboince but to no avail . By they how do you work out the correct value for the debonce . how did you get the value 33 ?
Code:
#include "G:\Program Files\PICC\Project\keypad2.h"[/b][/color]

//This is a modification of CCS keypad driver (KBDD.c) with flexible pins connections.

//Code:
///////////////////////////////////////////////////////////////////////////
////                             Flex_KBD.C                            ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////       ////
////  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_B5
#define col1 PIN_B6
#define col2 PIN_B7
#define row0 PIN_B1
#define row1 PIN_B2
#define row2 PIN_B3
#define row3 PIN_B4
char kbd_getc( );
short int ALL_ROWS (void);

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

#define KBD_DEBOUNCE_FACTOR 0//100   // Set this number to apx n/333 where
                                  // n is the number of times you expect
                                  // to call kbd_getc each second

void main()
{
    char key;

   port_b_pullups(TRUE);

      while(1)
      {
         char i;
          key=kbd_getc();
            if(key!=0)
   
                 printf("%c",key);
   
               
      }
}

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_low(col0);
               output_high(col1);
               output_high(col2);
                    break;
         case 1   : output_high(col0);
               output_low(col1);
               output_high(col2);
                    break;
         case 2   : output_high(col0);
               output_high(col1);
               output_low(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);
}

short int ALL_ROWS (void)
{
   if (input (row0) & input (row1) & input (row2) & input (row3))
      return (0);
   else
      return (1);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 06, 2006 11:55 pm     Reply with quote

Do you have your programmer plugged into the board while you're
running the program ? If so, unplug it. If that doesn't fix it, then
check the wiring between your keypad the PIC.

Don't set the debounce value to 0. It's got to be set to some non-zero
value. The debounce value just controls the number of times per
second that the keypad is polled for a keypress. My board is running
at 4 MHz and the CCS value of 33 seems to work OK.
PICdawg



Joined: 13 Dec 2007
Posts: 17

View user's profile Send private message

PostPosted: Fri Jul 18, 2014 5:30 pm     Reply with quote

Old post but I have a couple questions about the flex_kbd, and kbd.c drivers w.r.t. kbd_debounce_factor. I am implementing a keypad in a design for the first time. I've written a test program and it works utilizing PCM's password entry program(s). Thanks PCM. The code lives! However, I am trying to understand the kbd_debounce_factor which appears in the drivers and its associated comment....

The comment in all the drivers says 'Set this number to apx n/333 where n is the number of times per second....' This confuses me. I'm assuming 'apx' is short for 'approximately'. The driver defines this value as '33'. This is the value many on this forum use. If it's 33, then 'n' would be 333 X 33 = 10989. I'm doubting that anyone is calling their keypad routine every 91 microseconds (1/10989). Typically it's called every 10ms. kbd_call_count increments once per call (or poll)

I set my interrupt for every 10ms. That's 100hz. If I follow the comment, I should use a value of 100/333 which is less than 1. This makes no sense to me.

I believe PCM is slightly incorrect in his last post to this old thread. (PCM, don't flame me too bad if I'm completely off the mark...I'm an old guy!!!) kbd_debounce_factor does not control the number of times polled PER SECOND, just the number of times polled right? If you have a 10ms interrupt time, and kbd_debounce_factor of 33, you must hold the key for 33 polls which is 330ms per keypress. Am I missing something?

My experience as a hardware engineer has shown keybounce lasts significantly less than 330ms so the 33 number seems excessive. I'm using 3 right now and my test environment is working fine. I have regularly measured switch bounce on a scope in the neighborhood of 5ms-30ms.

So in summary, my two issues are 1) the comment verbiage in the drivers that doesn't make sense to me, and 2) the actual value and the reasoning behind the particular value chosen.

Please be kind if I've absolutely missed the most obvious thing any noob would catch..

FWIW I'm running a 16F876A at 20 Mhz. Very Happy
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 18, 2014 8:44 pm     Reply with quote

The CCS driver file kbd.c, and its associated example file ex_lcdkb.c
do not use interrupts. The keypad is polled in a loop. I setup a test
program which consists largely of ex_lcdkb.c, except without the lcd.
Inside kbd.c, right after the test where it decides to poll the keypad,
I placed a marker pulse for my scope.
Code:

if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
     
      output_high(PIN_D7);  // *** MARKER PULSE ***
      delay_us(1);
      output_low(PIN_D7);

Then I ran the program on a PicDem2-Plus (old type) with a 16F877A
with a 20 MHz crystal. The pulses occur at roughly every 190 usec.
This is about 5.2 KHz. If I was using a 4 MHz crystal, they would occur at
about every 950 usec, which is a rate of about 1 KHz. This measurement
was done with PortB pullups enabled, and with no keys pressed.

The CCS kbd.c does not use interrupts. There is no timer interrupt running
every 10ms. It's polled in a code loop, at the rates given above.
PICdawg



Joined: 13 Dec 2007
Posts: 17

View user's profile Send private message

PostPosted: Sat Jul 19, 2014 10:29 am     Reply with quote

Thanks for your quick response PCM! I understand your comments and example completely. Makes sense when the driver is not used in an interrupt driven fashion. I hadn't looked at EX_LCDKB.C until you pointed it out!

The test programs I implemented were from your post to KONAMI (Keypad problem) back in 2011. Is it fair to say that in that example which utilizes the interrupt scheme in kbd_buffer.c that a key must be held for approx. 330ms, given the 10ms interrupt and the debounce factor of 33 or am I just way out in left field?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jul 19, 2014 11:26 am     Reply with quote

I looked at the files on my PC, which were still there from 2011. The
flex_kbd.c file had been edited as follows:
Code:
//#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

#define KBD_DEBOUNCE_FACTOR 0

In other words, the software-loop debounce has been disabled. It's
done at a 10ms rate by the #int_rtcc (same as #int_timer0) interrupt.
So it's not 330ms, it's 10 ms.

When you brought up the 330ms, I figured that something was wrong
with that, because there's no way that a 330ms sampling rate would
be snappy enough in terms of keypad response time. And that's how
it was. The debounce factor was set to 0, leaving debounce to be done
by the timer interrupt.
PICdawg



Joined: 13 Dec 2007
Posts: 17

View user's profile Send private message

PostPosted: Sat Jul 19, 2014 12:23 pm     Reply with quote

Thanks PCM! We are now perfectly in sync. I've included additional comments to remind me about the debounce factor and using it in an interrupt vs polled environment. Your Password example is running and I can move to the next step of my code development.
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