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

Keypad problem

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



Joined: 29 Aug 2010
Posts: 11

View user's profile Send private message Send e-mail Yahoo Messenger

Keypad problem
PostPosted: Mon Jul 25, 2011 2:57 pm     Reply with quote

Hi all the CCS programmer. I have a problem and i know that here some people can help me. I'm using 4x3 keypad. I still can only read one value. And I want to read many character from the keypad like some 8 character username and password. Please if some people know how to do post it here it will help all the community.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 26, 2011 4:01 pm     Reply with quote

Here's a demo program that shows how to get an 8-digit ASCII password
from a 4x3 keypad and display it on an LCD.

When you run the program, it will display this on the LCD:
Quote:

Enter Password:

Then you type in a password and press the '#' key, and it
might look like:
Quote:

Enter Password:
12345678

Then it displays the password that you entered:
Quote:

Password is:
12345678



Here's the main program:
Code:

#include <16F877.H>
#fuses HS, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20M)

#include "flex_lcd.c"
#include "flex_kbd.c"
#include "kbd_buffer.c"

#define MAX_PASSWORD_SIZE  8

//==================================
void main()

int8 password_array[MAX_PASSWORD_SIZE +1];

lcd_init();
kbd_init();   
kbd_buffer_init();

while(1)
  {
   lcd_putc("\fEnter Password:\n");
   
   // Get the password from keypad input by the user.  The password
   // can be from 1 to 8 digits.
   // The user must press '#' key to exit the password entry screen.
   // The user can press '*' key to backspace over chars.
   kbd_get_string(password_array, MAX_PASSWORD_SIZE);
   
   // Display the password that we just got.
   lcd_putc("\fPassword is:\n");
   printf(lcd_putc, "%s", password_array);

   delay_ms(3000);
  }

}


flex_lcd.c is from here:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661

flex_kbd.c is from here:
http://www.ccsinfo.com/forum/viewtopic.php?t=26333
Note: You need to edit the flex_kbd.c driver as follows:
Edit the #define statement for the debounce factor, and change it 0.
It was set to 33, but that's for a software-loop polled keypad. The
example code in this post uses a 10ms timer interrupt, so disable
the software-loop polling by setting it to 0 as shown below:
Code:
#define KBD_DEBOUNCE_FACTOR  0



The kbd_buffer.c file is given below:
Code:

#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;


// The RTCC preload value calculated below will
// will give an RTCC interrupt rate of 100 Hz.
// This is intended for an oscillator of 4 to 20 MHz.

#define FOSC getenv("CLOCK")

#if(FOSC < 26000000)
  #define RTCC_PRELOAD (256 - (FOSC/4/256/100))
#else
  #error Oscillator frequency is too high:  FOSC
#endif

// Setup Timer0 to provide a 10ms tick for the keypad driver.
void kbd_buffer_init(void)
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
set_rtcc(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}


//------------------------------
// The keypad is polled every 10ms in this interrupt
// routine.
#int_rtcc
void rtcc_isr(void)
{
int t;
int k;

set_rtcc(RTCC_PRELOAD); // Reload Timer0 for 10ms rate

k = kbd_getc();  // Check the keypad for a keypress

// If we got a keypress, put it in the circular
// buffer.
if(k != 0) 
  {
   buffer[next_in] = k;
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
      next_in=t;
  }

}

#define bkbhit (next_in!=next_out)

//------------------------------
int8 bgetc(void)
{
int8 c;

while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}

//------------------------------
// This version of get_string() works with a keypad
// and LCD.  The max_str_size parameter is the max
// length of the actual text the user is allowed to
// enter.   Your array that holds the text must be
// at least 1 char larger than this, to allow for
// the terminator null byte (0x00) at the end of a
// string.

#define KEYPAD_ENTER '#'
#define KEYPAD_BS    '*'

void kbd_get_string(int8 *str, int8 max_str_size)
{
int8 len;
int8 c;

if(max_str_size == 0)
  {
   *str = 0;
   return;
  }

len=0;

while(1)
  {
   c=bgetc();

   if(c == KEYPAD_BS) // Was the backspace key pressed ?
     { 
      if(len>0)   // If yes, then do we have any existing text ?
        {
         len--;   
         lcd_putc('\b');
         lcd_putc(' ');
         lcd_putc('\b');
        }
     }
   else if(c == KEYPAD_ENTER)
     {
      break;
     }
   else
     {
      if(len < max_str_size)
        {
         str[len++]=c;
         lcd_putc(c);
        }
     }
   }

str[len]=0;
}


-----------------------
Edit:
Added note about editing flex_kbd.c to set debounce factor to 0.


Last edited by PCM programmer on Wed Aug 06, 2014 2:41 pm; edited 1 time in total
yasotha



Joined: 05 Mar 2012
Posts: 6

View user's profile Send private message

hi..need help
PostPosted: Tue Mar 06, 2012 11:26 pm     Reply with quote

I've tried the codings given above exactly but yet i encountered some errors in kbd_buffer.c

undefined identifier --lcd_putc (4errors)
undefined identifier --lcd_init (1 error)

I don't know how to show the print screen of the error... can help me? I'm doing exactly the same project.
yasotha



Joined: 05 Mar 2012
Posts: 6

View user's profile Send private message

hi..
PostPosted: Tue Mar 06, 2012 11:36 pm     Reply with quote

I figured it out myself...
sterob



Joined: 24 Jun 2011
Posts: 9

View user's profile Send private message

PostPosted: Sat May 26, 2012 4:32 am     Reply with quote

Quote:
PCM_PROGRAMMER

Hi, I tried to adapt the example code you posted to request for a password set, store it in eeprom. Then, ask a user to enter password,store the user's input and compare with the "set password in memory", my "if" conditions return "wrong", how do I achieve this. And I also observed that, the keypad takes like 1 second before it responds to keypress (the scanning through port B) takes time, how do I hasten it up?
Here's your code that I edited:
Code:

#include <string.h>
#include "flex_lcd.c"
#include "flex_KBD.c"
#include "kbd_buffer.c"

#define MAX_PASSWORD_SIZE  4

//==================================
void main()

   int8 password_array[MAX_PASSWORD_SIZE +1];
   int8 password_request[MAX_PASSWORD_SIZE +1];
   int8 stored,userPass;
   lcd_init();
   delay_ms(500);// for lcd initialization
   kbd_init();   
   kbd_buffer_init();
   
   write_eeprom(8,100);
   write_eeprom(16,120);
   while(1)
     {
      lcd_putc("\fSet Password:\n");
      kbd_get_string(password_array, MAX_PASSWORD_SIZE);
      write_eeprom(8,password_array);
      stored = read_eeprom(8);
      printf(lcd_putc, "\fstored = %s", stored);
      delay_ms(1000);
      lcd_putc("\fEnter Password:\n");
      // Get the password from keypad input by the user.  The password
      // can be from 1 to 8 digits.
      // The user must press '#' key to exit the password entry screen.
      // The user can press '*' key to backspace over chars.
      kbd_get_string(password_request, MAX_PASSWORD_SIZE);
      write_eeprom(16,password_request);
      userPass = read_eeprom(16);
      printf(lcd_putc, "\nuserPass = %s", userPass);
      delay_ms(1000);
      if(stored==userPass)
      {
      lcd_putc("\f Correct ");
      }
      if(stored!=userPass) 
      {
      lcd_putc("\f wrong\n");
      }
      delay_ms(1000);
       
     }

}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat May 26, 2012 1:35 pm     Reply with quote

You've got delay_ms(1000)'s sprinkled through your code. This could account for
Quote:
the keypad takes like 1 second before it responds to keypress(

How are you comparing the characters of the stored_password against the characters of the user_password?

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 27, 2012 12:15 pm     Reply with quote

Post all the missing lines from the top of the program.
Post these lines:
1. #include for PIC
2. #fuses
3. #use delay()

Tell us if this is a real hardware project or is it a Proteus simulator project.


Quote:

int8 password_array[MAX_PASSWORD_SIZE +1];

write_eeprom(8,password_array);

Also I think you have a misunderstanding of the write_eeprom() function.
It does not write an array to eeprom. It only writes one byte to eeprom.
Look in the CCS manual to see how a function should be used.

Finally, I think you have a misunderstanding of how to use the keypad
password program. You are supposed to compare the complete password
string, as typed in by the user, to the stored password string. You need
to use the strcmp() function to do this. Make sure you completely
understand what is a "string" in the C language. Also, make sure you
completely study the return values from the strcmp() function.
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