4*4 Alpha Numeric Keypad code Optimization help needed

C30 Compiler, ASM30, Link30. Conference for discussion of Microchip's MPLAB C30 Compiler and related language tools for dsPIC microcontrollers.

4*4 Alpha Numeric Keypad code Optimization help needed

Postby Thota_Suresh » Tue Sep 23, 2014 8:58 am

Hi,

Below mentioned code is 4*4 alphanumeric keypad,
my code is working absolutely fine, is there any optimizing techniques to reduce code size and complications can any one please suggest me...

KEYPAD Specification:

M 1 2 3

U 4 5 6

D 7 8 9

E S 0 C


O/P(col) = 0
I/P(row) = 1


Code: Select all
[code]



#include<P30f5011.h>

int main()
{
   uart_init();
   while(1)
   {
      KeyPadScan();
      delay(100);
   }

}





////////////////////// KP headers /////////////////////////////



const unsigned char keys[16]  =     {0x11,0x12,0x14,0x18,
                           0x21,0x22,0x24,0x28,
                           0x41,0x42,0x44,0x48,
                           0x81,0x82,0x84,0x88};
 
                                             //[R][C]
const unsigned char key_char[16][4]=   {{'M','M','M','M'},  //[1][0]
                               {'1',',','.','@'},   //[1][1]
                              {'2','A','B','C'},   //[1][2]
                              {'3','D','E','F'},   //[1][3]
                                                      
                              {'U','U','U','U'},   //[2][0]
                              {'4','G','H','I'},   //[2][1]
                              {'5','J','K','L'},   //[2][2]
                              {'6','M','N','O'},  //[2][3]


                              {'D','D','D','D'},   //[3][0]
                              {'7','P','Q','R'},   //[3][1]
                              {'8','S','T','U'},   //[3][2]
                              {'9','U','V','W'},   //[3][3]

                              {'E','E','E','E'},   //[4][0]
                              {'*','X','Y','Z'},   //[4][1]
                              {'0','0','0','0'},   //[4][2]
                              {'C','C','C','C'}};   //[4][3]


unsigned char key_pos1=0,n=0;

void KP_INIT(void)
{
   ADCON1bits.ADON = 0;         //ADC DISABLED
   ADPCFG = 0xFFFF;             //Digital port active   

   TRISB   =    0x00F0;            //CONFIGURE directions of TRISB(COL as INPUT ROW as OUTPUT)
   LATB   =   0x0000;            //ALL LATB PINS LOW
   printf("Key pad init done...\n");
}

void KeyPadScan( void )
{
    unsigned char j=0,i=0;

   PORTB=0x0F;                  //initializing portb again and again(COL as LOW and Rows As HIGH)

   if(PORTB != 0x0F )            //if pressed Cols switch wil high,and enters into loop
   {
      for(i=0;i<4;i++)         
      {
         PORTB = 1<<i;         //ROW i-th value high remaining zeros (i=0,1,2,3),and pressed value of Col switch get high
         for(j=0;j<16;j++)      //in pressed key row and col get high remaining all pins zero...
         {
            if((PORTB == keys[j]))
            {

               if(key_pos1 != j)
                  n=0;                  
               key_pos1 = j;
               
                if(n==0 || n==1 || n==2 || n==3)
               {   
                  printf("%c\n",key_char[j][n]);
                  n++;
                  if(n==4)
                     n=0;
                  break;
               }

            }
         }
   
      }

   }
}




[/code]
Thota_Suresh
 
Posts: 6
Joined: Tue Sep 23, 2014 7:41 am

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby BobAGI » Tue Sep 23, 2014 9:26 am

If you think that the code size is too big, then I suggest it is because you used the library function printf()...
Since you did not mention what PIC and compiler you use I can only make some general comments based on my experience with PIC24FJ256GB206 and a smaller PIC I started out with for a recent project.

What I found was that my code space was a LOT bigger than I expected for the simple test program I made and it turned out that if I excluded the library functions for sprintf/printf and instead wrote my own formatting code I gained a very large reduction in code space!
It seems like these library functions are really bloated because they can handle next to any kind of data type you throw at them. This comes at a codespace cost!

So my advice is:
1) Comment out the printf statement and build your project again. Note the difference in codespace used.
2) If it is as I suspect, then create your own formatting function which handles only the exact need you have and plug that in instead.

I suggest that you will see a lot of improvement both in execution speed and flash size.
--
Bo B
Sweden & Texas
User avatar
BobAGI
Verified identity
 
Posts: 49
Joined: Sun May 25, 2014 2:28 pm
Location: Sweden and Texas
PIC experience: Professional 5+ years with MCHP products

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby Thota_Suresh » Tue Sep 23, 2014 9:38 am

thanq for the reply BobAGI,

I am using PIC30f5011 Micro controller and Mplab c30 compiler,your advice is very helpful for me to reduce the code size,
except library function any more technical issues(simplified methods) as per hardware as well as software can you please suggest if this code is good enough i will go further.
Thota_Suresh
 
Posts: 6
Joined: Tue Sep 23, 2014 7:41 am

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby BobAGI » Tue Sep 23, 2014 10:24 am

When you check code size, just make sure that you comment out ALL uses of printf().
I saw that you have at least one more in the startup code. As long as there is a single instance of printf() in the code the library functions will be added to your flash size.

Regarding your other question it does not seem like spending time on such a small piece of code is worthwhile. If it works then leave it alone.
You can check the size of your KeyPadScan() function in the map file, but I think it is going to show up as really tiny.
--
Bo B
Sweden & Texas
User avatar
BobAGI
Verified identity
 
Posts: 49
Joined: Sun May 25, 2014 2:28 pm
Location: Sweden and Texas
PIC experience: Professional 5+ years with MCHP products

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby ric » Tue Sep 23, 2014 10:33 am

That code looks pretty inefficient to me.
The lack of comments in the code means I'm not sure why you are doing half of what you are doing.
I think if you just decoded the upper 4 bits of PORTB, rather than all 8 bits, it would be a lot simpler.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby Thota_Suresh » Tue Sep 23, 2014 11:45 am

Tanq for reply ric,

i would like to implement mobile keypad, by using 16 switches (4x4) and 8 port pins (PORTB).
each switch carries at least 4 output characters like 2,A,B,C. means 16x4 = 64 output characters.


in PORTB 4 pins tied to Pullup registers,and
remaining 4 pins tied to pulldown registers.

i am using scanning method (KeyPadScan()) to detect which key is pressed

i need output something like
const unsigned char key_char[16][4]=
{{'M','M','M','M'}, //[1][0] => switch 1
{'1',',','.','@'}, //[1][1]=> switch 2
{'2','A','B','C'}, //[1][2]=> switch 3
{'3','D','E','F'}, //[1][3] => switch 4

{'U','U','U','U'}, //[2][0]=> switch 5
{'4','G','H','I'}, //[2][1]=> switch 6
{'5','J','K','L'}, //[2][2]=> switch 7
{'6','M','N','O'}, //[2][3]=> switch 8


{'D','D','D','D'}, //[3][0]=> switch 9
{'7','P','Q','R'}, //[3][1]=> switch 10
{'8','S','T','U'}, //[3][2]=> switch 11
{'9','U','V','W'}, //[3][3]=> switch 12

{'E','E','E','E'}, //[4][0]=> switch 13
{'*','X','Y','Z'}, //[4][1]=> switch 14
{'0','0','0','0'}, //[4][2]=> switch 15
{'C','C','C','C'}}; //[4][3]=> switch 16



The above code i am implementing is effective or is there any algorithm to get efficient coding rather than key scan using 2D array.
Thota_Suresh
 
Posts: 6
Joined: Tue Sep 23, 2014 7:41 am

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby user2009 » Tue Sep 23, 2014 3:26 pm

You should write to LATB and not PORTB. This code looks a little complicated and I still dont understand how you address 64 output chars with a 4*4 matrix? I would use the way ric mentioned.
user2009
 
Posts: 13
Joined: Tue Jul 01, 2014 11:48 am
PIC experience: Professional 2-5 years with MCHP products

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby ric » Tue Sep 23, 2014 9:17 pm

Thota_Suresh wrote:i would like to implement mobile keypad, by using 16 switches (4x4) and 8 port pins (PORTB).

Yes, that is very straightforward.
each switch carries at least 4 output characters like 2,A,B,C. means 16x4 = 64 output characters.

How?
Do you want it to be like typing text on a phone keypad, where if you press the same key multiple times rapidly, you get extra alpha characters?
I guess maybe that is what your "n" variable is trying to do, but I doubt it will work how you intend.

You really should pick some more descriptive variable names, and comment your code a bit better.

i need output something like
const unsigned char key_char[16][4]=
{{'M','M','M','M'}, //[1][0] => switch 1
{'1',',','.','@'}, //[1][1]=> switch 2
{'2','A','B','C'}, //[1][2]=> switch 3
{'3','D','E','F'}, //[1][3] => switch 4

{'U','U','U','U'}, //[2][0]=> switch 5
{'4','G','H','I'}, //[2][1]=> switch 6
{'5','J','K','L'}, //[2][2]=> switch 7
{'6','M','N','O'}, //[2][3]=> switch 8


{'D','D','D','D'}, //[3][0]=> switch 9
{'7','P','Q','R'}, //[3][1]=> switch 10
{'8','S','T','U'}, //[3][2]=> switch 11
{'9','U','V','W'}, //[3][3]=> switch 12

{'E','E','E','E'}, //[4][0]=> switch 13
{'*','X','Y','Z'}, //[4][1]=> switch 14
{'0','0','0','0'}, //[4][2]=> switch 15
{'C','C','C','C'}}; //[4][3]=> switch 16



Is that really the final output you want, or just an intermediate step before you get it stepping between the four options correctly?
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: 4*4 Alpha Numeric Keypad code Optimization help needed

Postby Thota_Suresh » Wed Sep 24, 2014 5:14 am

How?
Do you want it to be like typing text on a phone keypad, where if you press the same key multiple times rapidly, you get extra alpha characters?
I guess maybe that is what your "n" variable is trying to do, but I doubt it will work how you intend.


its not exact mobile application its replica model i selected for my project and i don't need to type a text...
if i press the same key multiple times rapidly get an extra alpha characters this is what i want really,
and as your guess exactly "n(changed variable name as Press_key_count)" variable is doing that job in my code.

Is that really the final output you want, or just an intermediate step before you get it stepping between the four options correctly?


its just an intermediate step to detect all the charters in my keypad and i will control further peripherals by using these detected characters...




Code: Select all
//headers inclusion
int main()   //Main routines here
{
   uart_init(); //Uart initialization to see the output on terminal
   KP_INIT();   //Keypad Initialization

       while(1)     // Endless loop
   {
      KeyPadScan(); //Every time scan the keypad
      delay(100);     //delay routine
   }

}




/* 4x4 KEYPAD

   M  1  2  3 

   U  4  5  6
   
   D  7  8  9
   
   E  S  0  C
   
                         
          O/P(col)                       I/P(row)                 //TRIS Direction set As Output & input
                                     
   | B7 |B6 | B5 | B4|       | B3 | B2 | B2 | B0 |     //Positions of each bit in PORTB
                                                                         
       0    0   0     0                  1    1    1    1              //Initial values For upper and lower nibble
     
     
    */



const unsigned char keys[16]  =     {0x11,0x12,0x14,0x18,
                     0x21,0x22,0x24,0x28,
                     0x41,0x42,0x44,0x48,
                     0x81,0x82,0x84,0x88};
 
//16 keys array=> to detect address which key is pressed   
// Example for 1st key M is pressed:

     1) Initially we set I/P(row) PORTBbits.RB0 as  logic"1" and remaining(B1,B2,B3) set logic "0"
     2) If we press the key 'M' O/P(column) B4 get '1' and remaining(B5,B6,B7) is in '0' position
     3)Now we compare the values COL = 1,ROW = 1 ==> 0X11 ==> keys[] array
     4)MEANS 0x11 value is M address from key_char[][]



                                                               //[R][C]
                    const unsigned char key_char[16][4]=   {{'M','M','M','M'},   //[1][0]
                                              {'1',',','.','@'},   //[1][1]
                              {'2','A','B','C'},   //[1][2]
                              {'3','D','E','F'},   //[1][3]
                                                      
                              {'U','U','U','U'},   //[2][0]
                              {'4','G','H','I'},   //[2][1]
                              {'5','J','K','L'},   //[2][2]
                              {'6','M','N','O'},    //[2][3]


                              {'D','D','D','D'},   //[3][0]
                              {'7','P','Q','R'},   //[3][1]
                              {'8','S','T','U'},   //[3][2]
                              {'9','U','V','W'},   //[3][3]

                              {'E','E','E','E'},   //[4][0]
                              {'*','X','Y','Z'},   //[4][1]
                              {'0','0','0','0'},   //[4][2]
                              {'C','C','C','C'}};   //[4][3]


unsigned char key_pos1=0,        //To detect the key position
unsigned char Press_key_count=0,j; //To count how many time one key is pressing

void KP_INIT(void)
{
   ADCON1bits.ADON = 0;         //ADC DISABLED
   ADPCFG = 0xFFFF;             //Digital port active   

   TRISB   =    0x00F0;         //CONFIGURE directions of TRISB(COL as INPUT ROW as OUTPUT)
   LATB   =   0x0000;            //ALL LATB PINS LOW
   printf("Key pad init done...\n");
}

void KeyPadScan( void )        //Scanning function calls from main to detect which key is pressed
{
    unsigned char j=0,i=0;       // Local variables to run the for loop

   PORTB=0x0F;         //assigning portb again and again(COL as logic 0(B0,B1,B2,B3) and Rows As logic 1(B4,B5,B6,B7))

   if(PORTB != 0x0F )   //if any key pressed Cols goes to logic 1,and enters into loop
   {
      for(i=0;i<4;i++)      // For loop routine to detect which key in column get high   
      {
         PORTB = 1<<i;   
         for(j=0;j<16;j++)      
         {
            if((PORTB == keys[j])) //Comparing pressed key with the Address(from keys array) of PORTB
            {

               if(key_pos1 != j) // comparing previous pressed key with present pressed key.if not equal     //Press_key_count equal to 0 other wise pressed key count get increased.
                  Press_key_count=0;                  
               key_pos1 = j;     // Assign pressed key value to keep track previous pressed key     
               
                if(Press_key_count==0 || Press_key_count==1 || Press_key_count==2 || Press_key_count==3)
               {   //if condition to print which key is pressed
                  printf("%c\n",key_char[j][n]);  //Printing output on Terminal
                  Press_key_count++;           //Increasing pressed key count
                  if(Press_key_count==4)         // key count =4 means start key count from 0
                     Press_key_count=0;
                  break;
               }

            }
         }
   
      }

   }
}



Thota_Suresh
 
Posts: 6
Joined: Tue Sep 23, 2014 7:41 am


Return to MPLAB C30

Who is online

Users browsing this forum: No registered users and 2 guests

cron