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

4x4 Keypad Problem Pic18f4550!!!

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



Joined: 07 Feb 2011
Posts: 21
Location: Turkey

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

4x4 Keypad Problem Pic18f4550!!!
PostPosted: Mon Feb 07, 2011 12:52 am     Reply with quote

Hello everyone!

I am trying to use a 4x4 keypad with pic18f4550, I am using the codes which PCM Programmer gave in this link:

http://www.ccsinfo.com/forum/viewtopic.php?t=28022&start=14

besides I have looked at several discussions in this forum but I could not be successful. I am giving the code and schematic below, I will be glad if you can say where I did wrong,



Code:

#include <18F4550.h>
#fuses XTPLL,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
                       
#include <flex_lcd.c>                                                       
                                                   
//=============================                   
//Keypad connection:                           
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6                     
#define row3 PIN_B7                       
#define col0 PIN_B0                                               
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3

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


#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()               
{
//set_tris_b(0x0F);
//output_b(0x0F);                                   
//port_b_pullups(true);                           
}

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

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

      case 3:
        output_high(col0);
        output_high(col1);
        output_high(col2);
        output_low(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;

kbd_init();
lcd_init();

     
lcd_gotoxy(1,1);
lcd_putc("Starting ...");
delay_ms(3000);                                             
lcd_putc("\f");
                                             
while(TRUE)                                             
  {
   k=kbd_getc();
   lcd_gotoxy(1,1);                                   
   lcd_putc("Keypad is read ...");
   delay_ms(1000);
   lcd_putc("\f");                                 
   lcd_putc("...");
   delay_ms(1000);
   lcd_putc("\f");                   
      if(k!='\0')                       
     {                                         
      if(k=='*'){       
         lcd_gotoxy(1,2);           
         printf(lcd_putc,"%c", '*');
         delay_ms(3000);
         lcd_putc("\f");}
      else{                   
         lcd_gotoxy(1,2);
         printf(lcd_putc,"%c", k);
         delay_ms(3000);
         lcd_putc("\f");}
     }                                                                           
  }                                       
 
}                                         
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 07, 2011 1:22 am     Reply with quote

You have series resistors on the row pins. That's wrong. Also, you have
row pin 'A' connected to Vdd. That's also wrong.

This is a series resistor. This is what your schematic shows:

Code:
PIC pin ------/\/\/\/-------- Keypad pin



This is a pull-up resistor. This is what you need on each of the row pins:
Code:

    +5v ---/\/\/\/---
                    |
                    |
PIC pin ------------o---------- Keypad pin
 


Or, because you're using Port B, you could just enable Port B pull-ups
like this:
Code:

void kbd_init()               
{
port_b_pullups(true);                           
}


Also, the keypad must be polled at a high rate. You have huge 1000ms
and 3000ms delays in your main loop. Delete all those delays.
Look at this CCS example file:
Quote:

c:\program files\picc\examples\ex_lcdkb.c

They don't have any delays in the polling loop that calls kbd_getc().
Do it similar to that.
altanonat



Joined: 07 Feb 2011
Posts: 21
Location: Turkey

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Mon Feb 07, 2011 1:38 am     Reply with quote

Dear PCM programmer

Thank you very much for such a light speed reply. Actually I am doing exactly as you said above, all the rows are connected to Vdd not only the row pin 'A'. I have commented out Port B pull-ups section because I use external resistors. Is there a way to do this with delays?

I am doing a project, rf data collection system, I need to transfer some id codes to a receiver. These id codes must be character arrays. This(keypad reading) will be the very first step for me, but I have failed even reading a single key in keypad.

Just two days ago I have done an rfid reader card with pic16f877a. However when I tried it on a pic18f4550 it did not work. I think it is because of the register adresses but I could not see any register adress in the library em4095_read.c , but I have to say this is very annoying situation. It is meaningless to use libraries which is mcu dependent. I have to admit that because of this situation I am thinking of changing the compiler.
Ttelmah



Joined: 11 Mar 2010
Posts: 19487

View user's profile Send private message

PostPosted: Mon Feb 07, 2011 5:27 am     Reply with quote

The em4094 _library_, is device independent.
However the _demo_, is written to run on either a 16F876A, or a 18F452. It is a _demo_. The idea is that it will give you the 'basics' of how to use the library.
There is also a lot of configuration needed by the RS485 driver, which is designed to be useable on chips both with and without the hardware UART, so needs to be told a lot about what hardware to use before starting. On the two chips the demo is setup to use, this is done for you. On other chips, _you_ need to do this first.

Now, you seem to be trying to jump in at the deep end, without making sure that you can swim first. _Before_ starting to work with complex libraries, start by doing a simple 'flash an LED' test, and verify:
1) That the chip is running.
2) That it is running at the correct frequency.

Also, what else is on the pins you are trying to use?.

SETUP_PSP(FALSE);

Might be a good place to start....

Best Wishes
altanonat



Joined: 07 Feb 2011
Posts: 21
Location: Turkey

View user's profile Send private message Send e-mail Visit poster's website MSN Messenger

PostPosted: Mon Feb 07, 2011 6:03 am     Reply with quote

Ttelmah wrote:
The em4094 _library_, is device independent.
However the _demo_, is written to run on either a 16F876A, or a 18F452. It is a _demo_. The idea is that it will give you the 'basics' of how to use the library.
There is also a lot of configuration needed by the RS485 driver, which is designed to be useable on chips both with and without the hardware UART, so needs to be told a lot about what hardware to use before starting. On the two chips the demo is setup to use, this is done for you. On other chips, _you_ need to do this first.

Now, you seem to be trying to jump in at the deep end, without making sure that you can swim first. _Before_ starting to work with complex libraries, start by doing a simple 'flash an LED' test, and verify:
1) That the chip is running.
2) That it is running at the correct frequency.

Also, what else is on the pins you are trying to use?.

SETUP_PSP(FALSE);

Might be a good place to start....

Best Wishes


Dear Ttelmah,

Thank you for the suggestions. I have solved my keypad problem, instead of using flex kbd code I used the code below:

Code:

#include <16F877A.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define LCD_DATA_PORT getenv("SFR:PORTD")
#define LCD_ENABLE_PIN  PIN_D0                   
#define LCD_RS_PIN      PIN_D1
#define LCD_RW_PIN      PIN_D2                                       
#define LCD_DATA4       PIN_D4                       
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7                         
//#include <flex_lcd.c>
#include <lcd.c>
                                                   
//=============================                   
//Keypad connection:                           
/*#define row0 PIN_B4                 
#define row1 PIN_B5
#define row2 PIN_B6                     
#define row3 PIN_B7                       
#define col0 PIN_B0                                               
#define col1 PIN_B1
#define col2 PIN_B2                                       
#define col3 PIN_B3*/

char readkey()
{
     output_low(PIN_B1);
     output_low(PIN_B2);
     output_low(PIN_B3);
     output_high(PIN_B0);
     delay_ms(100);         
     if(input_state(PIN_B4)==1)
     {   
           delay_ms(20);
         return '1';                       
                                           
     }
     
     if(input_state(PIN_B5)==1)           
     {   
           delay_ms(20);
         return '4';
     
     }
     
     if(input_state(PIN_B6)==1)
     {   
           delay_ms(20);
         return '7'; 
     
     }
     
     if(input_state(PIN_B7)==1)
     {           
         delay_ms(20);
         return '*';
     
     }
     output_low(PIN_B0);
     delay_ms(100);
                       
     output_low(PIN_B0);
     output_low(PIN_B2);
     output_low(PIN_B3);
     output_high(PIN_B1);                                         
     delay_ms(100); 
     if(input_state(PIN_B4)==1)
     {           
         delay_ms(20);
         return '2';
                   
     }               
     
     if(input_state(PIN_B5)==1)
     {                 
         delay_ms(20);
         return '5';
                     
     }
     
     if(input_state(PIN_B6)==1)
     {
         delay_ms(20);
         return '8';
     
     }
     
     if(input_state(PIN_B7)==1)
     {
         delay_ms(20);
         return '0';
     
     }
     output_low(PIN_B1);
     delay_ms(100);                   
     
     output_low(PIN_B0);
     output_low(PIN_B1);
     output_low(PIN_B2);
     output_high(PIN_B3);
     delay_ms(100); 
     if(input_state(PIN_B4)==1)
     {
         delay_ms(20);
         return '3';
     
     }
     
     if(input_state(PIN_B5)==1)
     {               
         delay_ms(20);
         return '6';
     
     }
     
     if(input_state(PIN_B6)==1)
     {
         delay_ms(20);
         return '9';
                     
     }
     
     if(input_state(PIN_B7)==1)
     {
         delay_ms(20);
         return '#';
                     
     }
     output_low(PIN_B3);
     delay_ms(100);
     
     output_low(PIN_B0);
     output_low(PIN_B1);                   
     output_low(PIN_B3);
     output_high(PIN_B2);
     delay_ms(100); 
     if(input_state(PIN_B4)==1)
     {                 
         delay_ms(20);
         return 'A';
             
     }
     
     if(input_state(PIN_B5)==1)
     {
         delay_ms(20);
         return 'B';
     
     }
     
     if(input_state(PIN_B6)==1)
     {
         delay_ms(20);
         return 'C';
     
     }
     
     if(input_state(PIN_B7)==1)
     {   
         delay_ms(20);
         return 'D';
                     
     }
     output_low(PIN_B2);         
     delay_ms(100); 
                       

     return 'x';           
}     

//===========================
void main()
{
SET_TRIS_B(0b11110000);//you mus set in main function before infinite loop port configuration
char key;
//kbd_init();                           
lcd_init();
                                                                       
     
lcd_gotoxy(1,1);
lcd_putc("Basliyor ...");
delay_ms(2000);                                             
lcd_putc("\f");
                                             
while(TRUE)                                             
  {                                 
   lcd_gotoxy(1,1);                                   
   lcd_putc("Tus takımı okunuyor ...");
   delay_ms(200);                                   
   lcd_putc("\f");                                 
   lcd_putc("...");                   
   delay_ms(200);
   lcd_putc("\f");
   key = readkey();
   delay_ms(500);
   if(key!='x')
     {                                         
      if(key=='*'){       
         lcd_gotoxy(1,2);                 
         printf(lcd_putc,"%c", '*');
         delay_ms(1000);
         lcd_putc("\f");                       
         }
      else{                                             
         lcd_gotoxy(1,2);                 
         printf(lcd_putc,"%c", key);
         delay_ms(1000);
         lcd_putc("\f");
         }
     }                                                                           
  }                                       
}


About the rfid reader, I could not modify em4095.c to work with pic18f pics. If you know the way and tell me, it will be appreciated.

Code:

/////////////////////////////////////////////////////////////////////////
////                             em4095.c                            ////
//// This file contains drivers for a EM4095 RFID basestation.       ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////


++++++++++++++++++++
em4095.c code deleted.

Reason: Forum Rule #10

10. Don't post the CCS example code or drivers, or ask for such code and drivers.

Forum Rules:
http://www.ccsinfo.com/forum/viewtopic.php?t=26245

-- Forum Moderator
++++++++++++++++++++
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