help with a keypad reader

Thread Starter

eessoo

Joined Jan 29, 2012
23
pic 16f877A
keypad 16
i want the program to read from the user the input and put it back on the lcd
so far if i input 53.1 the program send out 5331.999
or 20.1 it gives 2001.999
but it works fine with out the (.)
here is the program
(part of it) the other part is taking the percentage the the user enter and so some calculation to it

please explain your self in details coz i'm not very good in english



int key=0;
int kp1;
float x;
int h=10;
int kp2=0;
float kp=0;
float blue ,red ,green;
char txt[3];
float e;
int keypad(int key)
{
switch (key)
{case 9:
key=49;
kp1=1;
break;
case 10:
key=50;
kp1=2;
break;
case 11:
key=51;
kp1=3;
break;
case 5:
key=52;
kp1=4;
break;
case 6:
key=53;
kp1=5;
break;
case 7:
key=54;
kp1=6;
break;
case 1:
key=55;
kp1=7;
break;
case 2:
key=56;
kp1=8;
break;
case 3:
key=57;
kp1=9;
break;

case 14:
key=48;
kp1=0;
break;
case 15:
key=46;
}
return (key);
}
char keypadPort at PORTD;
// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;

Rich (BB code):
void main() {

 Keypad_Init();
 lcd_init();
 while(1)
 {
         do
         key=keypad_key_click();
         while(!key);
                      key=keypad(key);
                        if(key==13)                      \\if the use enter (enter)
                              {
                              lcd_cmd(_lcd_clear);
                              break;
                              }
                        else if(key==15)                  \\if the user enter '.'
                         {
                         while(1)
                                        {lcd_chr_cp(key);
                                          do
                                         key=keypad_key_click();
                                         while(!key);
                                         key=keypad(key);
                                          kp=kp1/10+kp;                  

                                                         if(key==13)                  \\ if the user use Enter 
                                                         {lcd_cmd(_lcd_clear);
                                                         break;}
                                         }
                                        break;
                         }
                         else
                         {lcd_chr_cp(key);
                          kp=kp*10+kp1;}
}
floattostr(kp,txt);
Lcd_Out_CP(txt);
}
 
Last edited:

t06afre

Joined May 11, 2009
5,934
Have you tried some debugging. Like single stepping, adding some watches, or using breakpoints. Be able to debug is a skill the beginner often underestimate. But debugging skills are as well important as understand how to program. Are you using MPLAB?
 

Thread Starter

eessoo

Joined Jan 29, 2012
23
i'm using Proteus
can u tell me more about the debugging?what watches?
the program compiles correctly no syntax error
and if u do the equations by hand it will give correct results
 

t06afre

Joined May 11, 2009
5,934
MikroC itself does has a very nice software simulator/debugger built into the compiler. But that sums up all I know about it. Since I do not use Micro C. but MPLAB and HI-Tech C. If you think it is worth it. Start a new thread. In Programmer's Corner. And ask for debugging tips using MikroC
 

Thread Starter

eessoo

Joined Jan 29, 2012
23
the input in the lcd is in char
so i take each digit and add it the equation
for example if the use enter (123)

(output=(output*10)+input)
( kp = kp * 10 + kp1)
0 = 0 * 10 + 1 >>kp=1
1 = 1 * 10 + 2 >> kp = 12
12 = 12*10 + 3 >> kp=123
u get it?! :D

( kp=kp1/10+kp)<<< this only works if u add (.) to your number

i modified it Little bit (less error)


Rich (BB code):
int key=0;
float x;
int h=10;
char txt[15];
float kpt=0;

 int keypad(int key)
 {
           switch (key)
             {case 9:
             key=49;
             break;
              case 10:
              key=50;
             break;
              case 11:
              key=51;
             break;
              case 5:
              key=52;
             break;
              case 6:
              key=53;
             break;
              case 7:
              key=54;
             break;
              case 1:
              key=55;
             break;
              case 2:
              key=56;
             break;
              case 3:
              key=57;
             break;
             case 13:
             key=13;
             break;
              case 14:
              key=48;
              break;
              case 15:
              key=46;
              }
              return (key);
 }
char keypadPort at PORTD;
// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;


void main() {

 Keypad_Init();
 lcd_init();
 while(1)
 {
         do
         key=keypad_key_click();
         while(!key);
                           key=keypad(key);
                        if(key==13)
                              {
                              lcd_cmd(_lcd_clear);
                              break;
                              } 

                        else if(key==46)
                         {
                                        while(1)
                                        {lcd_chr_cp(key);
                                          do
                                         key=keypad_key_click();
                                         while(!key);
                                          key=keypad(key);
                                          kpt=((key-48)/10)+kpt;

                                                         if(key==13)
                                                         {lcd_cmd(_lcd_clear);
                                                         goto finaly;}

                                         }
                                        break;
                         }
                        else if(key!=13)
                         {lcd_chr_cp(key);
                          kpt=kpt*10+(key-48);}
}
finaly:
floattostr(kpt,txt);
Lcd_Out_CP(txt);
}
 
Last edited:

MrChips

Joined Oct 2, 2009
19,383
Rich (BB code):
( kp=kp1/10+kp)
You still have not demonstrated how this works in manual operation.

If the user types in 1.23
the result would be 1.5 (ignoring floating-point errors for the moment).
 

Thread Starter

eessoo

Joined Jan 29, 2012
23
Rich (BB code):
( kp=kp1/10+kp)
You still have not demonstrated how this works in manual operation.

If the user types in 1.23
the result would be 1.5 (ignoring floating-point errors for the moment).
this can be easily fixed
kp=kp1/V+kp
v=v*10
when the user enter 2 the equation will be( kp=kp1/10+kp) first value of V=10 >>>>0.2
when enter 3 it will be (kp=kp1/100+kp) >>>0.03

but i want the user to enter only one number after the (dot)
 

MrChips

Joined Oct 2, 2009
19,383
but i want the user to enter only one number after the (dot)
That's ok, but why risk the limitation and possible source of error. There are many ways to fix this. One way is as you suggested.

Did you correct the problem with key is never 15?
 

Thread Starter

eessoo

Joined Jan 29, 2012
23
That's ok, but why risk the limitation and possible source of error. There are many ways to fix this. One way is as you suggested.

Did you correct the problem with key is never 15?
there are 16 buttons on my keypad
i made key number 15 for (.)
and key number 13 for (enter)
i can't see anything wrong with it :(

tell me what u are thinking. in details plzz :)
 

MrChips

Joined Oct 2, 2009
19,383
Here is your original code:
Rich (BB code):
case 15:
              key=46;
You have replaced key=15 with key=46.
Hence your main program never sees key == 15.
 

Thread Starter

eessoo

Joined Jan 29, 2012
23
Rich (BB code):
                        else if(key==46)
                         {
                                        while(1)
                                        {lcd_chr_cp(key);
                                          do
                                         key=keypad_key_click();
                                         while(!key);
                                          key=keypad(key);
                                          kpt=((key-48)/10)+kpt;

                                                         if(key==13)
                                                         {lcd_cmd(_lcd_clear);
                                                         goto finaly;}

                                         }
                                        break;
                         }
yes
and i change my if statment to if(key==46)
 

MrChips

Joined Oct 2, 2009
19,383
Ok, now that you have fixed that, your code is messy.
There is no need to check for (key == 13) in two different places.
Write your code so that there is only one process loop.

What is the largest value the user is expected to enter?
If the value does not exceed the range of the variable type, one solution is to accumulate the number as an integer. When the "." is pressed, accumulate a power of 10 value and do the division after "ENTER" is pressed.

(This is only one of many possible solutions.)
 
Top