Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

keyborad scaning c program please explain

Status
Not open for further replies.

thannara123

Advanced Member level 5
Joined
Jan 7, 2010
Messages
1,580
Helped
122
Reputation
244
Reaction score
114
Trophy points
1,353
Location
India
Activity points
10,378
How to scan or works please anyone explain thanks in advance

Code:
uint8_t GetKeyPressed()
{
      uint8_t r,c;


      KEYPAD_PORT|= 0X0F;
	  


      for(c=0;c<4;c++)
      {
         KEYPAD_DDR&=~(0XFF);


         KEYPAD_DDR|=(0X80>>c);
         for(r=0;r<4;r++)
         {
            if(!(KEYPAD_PIN & (0X08>>r)))
            {
               return (r*4+c);
            }
         }
      }
	  return 0XFF;//Indicate No key pressed
}
 
Last edited by a moderator:

There are numerous methods of driving and interfacing a keypad.

The particular method you've posted is a simple scan/poll method.

Typically each column output line is sequentially pulled logical low and the row input lines are normally logical high through the use of pullup resistors, while the column output line is pulled logical low the intersecting row input lines are polled individually until a logical low input is detected.

The logical low input indicates that a switch closure has occurred, at which point a unique number is generated by the formula r*4+c, which uses the column (c) and row (r) for loop indexes.

Each row line is sequentially polled by the use of a bitmask (0x08) and bitwise ANDoperator (&), the bitmask is sequentially shifted to left during each for loop interation, effectively walking the high bit of the bitmask to the left.

The following keypad tutorial discusses similar methods as the posted code:

Lab 18: Matrix keypad interfacing

Martix Keypad Interfacing with Microcontrollers: Introduction


Using external interrupts or interrupt-on-change is a more efficient method, rather than polling.

If resources are tight, keypads can be interfaced and driven using a single input to an ADC module, if required.


BigDog
 
may i get more explanation because of i haven't too knowledge in c programming ?
 

At the beginning of each of the outer for loop iterations the PORT used as the keypad interface is configured with all lines as inputs with internal pullup resisters active on PORT bits 0 to 3, keypad row lines.

Code:
uint8_t GetKeyPressed()
{
      uint8_t r,c;


      [COLOR="#FF0000"]KEYPAD_PORT|= 0X0F;[/COLOR]
	  


      for(c=0;c<4;c++)
      {
         [COLOR="#FF0000"]KEYPAD_DDR&=~(0XFF);[/COLOR]


         KEYPAD_DDR|=(0X80>>c);
         for(r=0;r<4;r++)
         {
            if(!(KEYPAD_PIN & (0X08>>r)))
            {
               return (r*4+c);
            }
         }
      }
	  return 0XFF;//Indicate No key pressed
}

With each iteration of outer for loop, the c index is incremented and the PORT bits 7 to 4 are sequentially changed to outputs, pulling the corresponding column line low by using the left shift operator and the c index:

Code:
uint8_t GetKeyPressed()
{
      uint8_t r,c;


      KEYPAD_PORT|= 0X0F;
	  


      [COLOR="#FF0000"]for(c=0;c<4;c++)[/COLOR]
      {
         KEYPAD_DDR&=~(0XFF);


        [COLOR="#FF0000"] KEYPAD_DDR|=(0X80>>c);[/COLOR]
         for(r=0;r<4;r++)
         {
            if(!(KEYPAD_PIN & (0X08>>r)))
            {
               return (r*4+c);
            }
         }
      }
	  return 0XFF;//Indicate No key pressed
}

The inner for loop then increments the r index which is then used to sequential poll each of the four intersecting row lines using a bitmask, the left shift operator and r index, when a low is detected by the if statement a unique value is generated using both the r and c indexes and returned as the routine is exited.

Code:
uint8_t GetKeyPressed()
{
      uint8_t r,c;


      KEYPAD_PORT|= 0X0F;
	  


      for(c=0;c<4;c++)
      {
         KEYPAD_DDR&=~(0XFF);


         KEYPAD_DDR|=(0X80>>c);
         [COLOR="#FF0000"]for(r=0;r<4;r++)[/COLOR]
         {
            [COLOR="#FF0000"]if(!(KEYPAD_PIN & (0X08>>r)))[/COLOR]
            {
               [COLOR="#FF0000"]return (r*4+c);[/COLOR]
            }
         }
      }
	  return 0XFF;//Indicate No key pressed
}


Are there particular sections of the routine of which you still have questions?

The second tutorial previously posted has a side by side comparison of a similar AVR routine in both Assembly and C languages.


BigDog
 
Code:
while(!system_reset)
        {
            x=0;
            
            
            
        
        
keyCode=GetKeyPressed();                             //Get the keycode of pressed key



if(keyCode==prev_key)
continue;
else if(keyCode==0xFF)
{
    prev_key=0xFF;
    continue;
}
else
{
    prev_key=keyCode;
}


            if(pos==3)
              {
                return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3]));        //save the password in 16 bit integer
                //return(1234);
                break;
                //Wait for enter key or reset key
                
                
                //Convert pass to a single integer
                //
               }
//
switch (keyCode)                                     //generating key characeter to display on LCD
{
    case (11):
    string("1");    
    dis_cmd(k++);
    key[x]=1;
    ++x;
    pos++;
    break;
    
    
    case (10):
    //dis_cmd(k++);
    string("2");    
    dis_cmd(k++);
    key[x]=2;
    ++x;
    pos++;
    break;
    
    case (9):
    string("3");    
    dis_cmd(k++);
    key[x]=3;
    ++x;
    pos++;
    break;
    
    case (7):
    string("nubere");
    dis_cmd(k++);
    key[x]=4;
    ++x;
    pos++;
    break;
    
    case (6):
    //dis_cmd(k++);
    string("5");
    dis_cmd(k++);
    key[x]=5;
    ++x;
    pos++;
    break;
    
    case (5):
    string("6");
    dis_cmd(k++);
    key[x]=6;
    ++x;
    pos++;
    break;
    
    case (3):
    string("7");
    dis_cmd(k++);
    key[x]=7;
    ++x;
    pos++;
    break;
    
    case (2):
    string("8");
    dis_cmd(k++);
    key[x]=8;
    ++x;
    pos++;
    break;
    
    case (1):
    string("9");
    dis_cmd(k++);
    key[x]=9;
    ++x;
    pos++;
    break;
    
    case (15):
    string("0");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (14):
    string("#");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (13):
    system_reset=1;
    
    break;
    
    default: ;

}

_delay_loop_2(1600);

        }
        //key[0]=1;key[1]=2;key[2]=3;key[3]=4;
        
        
    
    }

In each case how can i get the values that is keycode / which key is pressed ?
 

Attachments

  • lcd interfacing with AVR.rar
    82 KB · Views: 108
Last edited:

I am not getting the correct value .why so ?
Code:
switch (keyCode)                                     //generating key characeter to display on LCD
{
    case (11):
    string("1");    
    dis_cmd(k++);
    key[x]=1;
    ++x;
    pos++;
    break;
    
    
    case (10):
    //dis_cmd(k++);
    string("2");    
    dis_cmd(k++);
    key[x]=2;
    ++x;
    pos++;
    break;
    
    case (9):
    string("3");    
    dis_cmd(k++);
    key[x]=3;
    ++x;
    pos++;
    break;
    
    case (7):
    string("nubere");
    dis_cmd(k++);
    key[x]=4;
    ++x;
    pos++;
    break;
    
    case (6):
    //dis_cmd(k++);
    string("5");
    dis_cmd(k++);
    key[x]=5;
    ++x;
    pos++;
    break;
    
    case (5):
    string("6");
    dis_cmd(k++);
    key[x]=6;
    ++x;
    pos++;
    break;
    
    case (3):
    string("7");
    dis_cmd(k++);
    key[x]=7;
    ++x;
    pos++;
    break;
    
    case (2):
    string("8");
    dis_cmd(k++);
    key[x]=8;
    ++x;
    pos++;
    break;
    
    case (1):
    string("9");
    dis_cmd(k++);
    key[x]=9;
    ++x;
    pos++;
    break;
    
    case (15):
    string("0");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (14):
    string("#");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (13):
    system_reset=1;
    
    break;
    
    default: ;

}

when i press 1,2,3,4 that is switch case 11,10,9,7 but not giving 1234 value .what is the reason
asigined int key[]={0,0,0,0} please help me

consumed too time .....:cry:
is there any array value return problem ?
 

Try this code.
Code:
 x = 0;
switch (keyCode)                                     //generating key characeter to display on LCD
{
    case (11):
    string("1");    
    dis_cmd(k++);
    key[x]=1;
    pos++;
    break;
    
    
    case (10):
    //dis_cmd(k++);
    string("2");    
    dis_cmd(k++);
    key[x]=2;
    pos++;
    break;
    
    case (9):
    string("3");    
    dis_cmd(k++);
    key[x]=3;
    pos++;
    break;
    
    case (7):
    string("nubere");
    dis_cmd(k++);
    key[x]=4;
    pos++;
    break;
    
    case (6):
    //dis_cmd(k++);
    string("5");
    dis_cmd(k++);
    key[x]=5;
    pos++;
    break;
    
    case (5):
    string("6");
    dis_cmd(k++);
    key[x]=6;
    pos++;
    break;
    
    case (3):
    string("7");
    dis_cmd(k++);
    key[x]=7;
    pos++;
    break;
    
    case (2):
    string("8");
    dis_cmd(k++);
    key[x]=8;
    pos++;
    break;
    
    case (1):
    string("9");
    dis_cmd(k++);
    key[x]=9;
    pos++;
    break;
    
    case (15):
    string("0");
    dis_cmd(k++);
    key[x]=0;
    pos++;
    break;

    case (14):
    string("#");
    dis_cmd(k++);
    key[x]=0;
    pos++;
    break;

    case (13):
    system_reset=1;
    break;
    
    default: ;

}
x++;
I assume key[] is an unsigned int array. What value are you geting if you enter 1234? Can I see the codes for string() and dis_cmd() functions?
 

You can use value = value*10 + key; for getting the integer value of keypresses.

Incorrect. Keypads generally do not produce a linear code, therefore a linear formula will not produce the expect results.

Typically, a lookup table of some fashion is used to translate the keypad routine output to more appropriate values, such as ASCII or integer.

I am not getting the correct value .why so ?
Code:
switch (keyCode)                                     //generating key characeter to display on LCD
{
    case (11):
    string("1");    
    dis_cmd(k++);
    key[x]=1;
    ++x;
    pos++;
    break;
    
    
    case (10):
    //dis_cmd(k++);
    string("2");    
    dis_cmd(k++);
    key[x]=2;
    ++x;
    pos++;
    break;
    
    case (9):
    string("3");    
    dis_cmd(k++);
    key[x]=3;
    ++x;
    pos++;
    break;
    
    case (7):
    string("nubere");
    dis_cmd(k++);
    key[x]=4;
    ++x;
    pos++;
    break;
    
    case (6):
    //dis_cmd(k++);
    string("5");
    dis_cmd(k++);
    key[x]=5;
    ++x;
    pos++;
    break;
    
    case (5):
    string("6");
    dis_cmd(k++);
    key[x]=6;
    ++x;
    pos++;
    break;
    
    case (3):
    string("7");
    dis_cmd(k++);
    key[x]=7;
    ++x;
    pos++;
    break;
    
    case (2):
    string("8");
    dis_cmd(k++);
    key[x]=8;
    ++x;
    pos++;
    break;
    
    case (1):
    string("9");
    dis_cmd(k++);
    key[x]=9;
    ++x;
    pos++;
    break;
    
    case (15):
    string("0");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (14):
    string("#");
    dis_cmd(k++);
    key[x]=0;
    ++x;
    pos++;
    break;

    case (13):
    system_reset=1;
    
    break;
    
    default: ;

}

when i press 1,2,3,4 that is switch case 11,10,9,7 but not giving 1234 value .what is the reason
asigined int key[]={0,0,0,0} please help me

consumed too time .....:cry:
is there any array value return problem ?

In this case the lookup table is coded in the form of a switch/case statements.

As keypads often differ in their layout and interfaces, you will likely need to customize the switch/case statements to your particular application.

How may keys does your keypad have, 12, 16, etc? What is the layout of your keypad? When you press 1, 2 ,3, 4, what is the resulting sequence of keyCode(s)?


If you have hardware debugging capabilities, i.e. breakpoints, set a breakpoint before entering the switch/case statement and record the value of keyCode after each press of a key.

Or

If you do not have hardware debugging capabilities, you could modify the above routine to store each sequential keypress into an array of appropriate size and type.

Then simply press each key in an organized fashion, for example: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, *, # for a typical 12 button keypad, then output the array and modify the switch/case statements accordingly.


The statement:

Code:
key[]={0,0,0,0};

Simply initialize the array with NULL, a value which technically shouldn't be returned by the press of a key.


BigDog
 
How may keys does your keypad have, 12, 16, etc? What is the layout of your keypad? When you press 1, 2 ,3, 4, what is the resulting sequence of keyCode(s)?
BigDog
Key pad matrix i used 12 keys ,
lay out of keypad is 4x3 - (attached Proteus file)
When i press 1,2,3,4 key it displays as 1,2,3,4 respectively
I didnt checked key code directly .
Sir i attached my full projects in the previous post (#5)

If you have hardware debugging capabilities, i.e. breakpoints, set a breakpoints before entering the switch/case statement and record the value of keyCode after each press of a key.
Or
If you do not have hardware debugging capabilities, you could modify the above routine to store each sequential keypress into an array of appropriate size and type.

BigDog
yes sir i have debugging cappabilities but never used (dont know well how to ) .I am using AVR Studio6 .
where can i record the keycode value and how to see it ?

thanks in advance
 

If you are getting 1, 2, 3, 4 when you press 1, 2, 3, 4 then what is your problem? You said

you are not getting the right vaues. When you display 1, 2, 3, 4 on lcd it its value will be

0x31, 0x32, 0x33, 0x34 or d49, d50, d51, d52 because they are characters. Can I see the code

for GetKeyPressed() function?

You'r GetKeyPressed() functions returns uint8_t value to keycode. Convert keycode value to

char like keycodechar = keycode + 48; or keycodechar = keycode + 0x30; and send the

keycodechar variable to lcd print character function. See what values you get when you press

keys 0 to 9 and *, #. Reply what values you get on lcd.

Your function
Code:
 string("1");... string("9");
in the switch case statementis

displaying
the values 0, 1, 2, 3, 4,..9 on the lcd. I don't know why you are using
Code:
 dis_cmd(k++);

Instead of using string("1"), etc., in the case statement use
Code:
//Global variables
unsigned char keycodechar;

keycode = GetKeyPressed();
keycodechar = keycode + 48;
dis_data(keycodechar);
to display keypressed values on lcd. That way you will no

what values you are getting for keypresses.
 
Last edited:

If you are getting 1, 2, 3, 4 when you press 1, 2, 3, 4 then what is your problem? You said you are not getting the right vaues. When you display 1, 2, 3, 4 on lcd it its value will be 0x31, 0x32, 0x33, 0x34 or d49, d50, d51, d52 because they are characters.
Yes getting the right value only on LCD not in return function ;
When the function return - (return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3])))- its not return the actual value even pressed 1234 keys which displayed on lcd as 1234
But if i give manually the values 1234 its working that is as flows

// return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3])) // disabled

key[0]=1;key[1]=2;key[2]=3;key[3]=4; // Or return(1234); worked well

what is the reason ?

Can I see the code for GetKeyPressed() function?
[/QUOTE]

yes
Code:
/*
 * keypad.h
 *
 * Created: 12/19/2012 10:49:06 PM
 *  Author: Gelectorn
 */ 


#ifndef KEYPAD_H_
#define KEYPAD_H_

#define KEYPAD_PORT PORTD
#define KEYPAD_DDR   DDRD
#define KEYPAD_PIN   PIND

uint8_t GetKeyPressed()
{
  uint8_t r,c;
  KEYPAD_PORT|= 0X0F;
  for(c=0;c<3;c++)
	 {
		KEYPAD_DDR&=~(0X7F);
		KEYPAD_DDR|=(0X40>>c);
		for(r=0;r<4;r++)
		   {
			if(!(KEYPAD_PIN & (0X08>>r)))
			  {
				return (r*3+c);
			  }
		   }
	 }
	  return 0XFF;//Indicate No key pressed
}	  



#endif /* KEYPAD_H_ */
 

So, your keycode value for 1 is 11, for 2 is 10, for 3 is 9 like that. Your return function
Code:
 return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3]))
is for the function
Code:
 uint16_t InputNumber(char *msg)
right? Where are you assigning the return value to? You should assign something like this
Code:
uint16_t retval = 0;

retval = InputNumber();
 

my problem is as follows

i can correctly read the keyboard using keyCode=GetKeyPressed();
when i press a key ,the keycode has get a case value which select the corresponding key and displaying the correct value ......
Also put a corresponding value to the key[] array ;
4 keys pressed got correct LCD display
that is, key[] array is

key[0],key[1],key[2],key[3]
finally return using function return((1000*key[0])+(100*key[1])+(10*key[2])+key[3]); not working //:oops:
but the return value is wrong not getting correct value .

For example pressed key is 1,2,3and 4
LCD displayed same as 1,2,3and 4 using switch case .
but the return value is not 1234
 

When you enter 1234 what is the return value you are getting from return((1000*key[0])+(100*key[1])+(10*key[2])+key[3]);?

Assign your return value to a int varible like
Code:
unsigned int retval = 0;
unsigned char sretval[5];

retval = InputNumber(char *msg);

Then convert retval to string like
Code:
sretval[0] = (retval/1000) + 48;
sretval[1] = (retval/100)%10 + 48;
sretval[2] = (retval/10)%10 + 48;
sretval[3] = (retval/1)%10 + 48;
sretval[4] = '\0'; 

string(sretval);

See what value you get on lcd. See if the value is 1234 for 1234 or some other value. Reply me what value you get.

Try this code
Code:
#include <avr/io.h>
#include <inttypes.h>
#include<util/delay.h>

#include "keypad.h"
#include "user_interface.h"
#include "lcd.h"

unsigned int retval = 0;
unsigned char sretval[5];

uint16_t InputNumber(char *msg)
{
	uint8_t keyCode,x=0,pos = 0;
	uint8_t prev_key=0xFF;
	uint8_t k=0xc1;
	uint8_t system_reset = 0;
	uint8_t key[]="####";
	dis_cmd(0x81);
	//string("Enter Password");
	while(*msg) dis_data(*msg++);
     LINE2;
	while(!system_reset)
		{
			
			
			
			
		
		
keyCode=GetKeyPressed(); 							//Get the keycode of pressed key



if(keyCode==prev_key)
continue;
else if(keyCode==0xFF)
{
	prev_key=0xFF;
	continue;
}
else
{
	prev_key=keyCode;
}


if(pos==3)
{
				
	retval = (1000*key[0])+(100*key[1])+(10*key[2])+1*key[3]);
	return 0;
	//return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3]));					//save the password in 16 bit integer
	//return(1234);
	break;
	//Wait for enter key or reset key
	//Convert pass to a single integer
}

sretval[0] = (retval/1000) + 48;
sretval[1] = (retval/100)%10 + 48;
sretval[2] = (retval/10)%10 + 48;
sretval[3] = (retval/1)%10 + 48;
sretval[4] = '\0'; 

string(sretval);

switch (keyCode) //generating key characeter to display on LCD					{
	case (11):
		string("1");	
		dis_cmd(k++);
		key[x]=1;
		++x;
		pos++;
		break;	
	
	case (10):
		string("2");	
		dis_cmd(k++);
		key[x]=2;
		++x;
		pos++;
		break;
	
	case (9):
		string("3");	
		dis_cmd(k++);
		key[x]=3;
		++x;
		pos++;
		break;
	
	case (7):
		string("nubere");
		dis_cmd(k++);
		key[x]=4;
		++x;
		pos++;
		break;
	
	case (6):
		string("5");
		dis_cmd(k++);
		key[x]=5;
		++x;
		pos++;
		break;
	
	case (5):
		string("6");
		dis_cmd(k++);
		key[x]=6;
		++x;
		pos++;
		break;
	
	case (3):
		string("7");
		dis_cmd(k++);
		key[x]=7;
		++x;
		pos++;
		break;
	
	case (2):
		string("8");
		dis_cmd(k++);
		key[x]=8;
		++x;
		pos++;
		break;
	
	case (1):
		string("9");
		dis_cmd(k++);
		key[x]=9;
		++x;
		pos++;
		break;
	
	case (15):
		string("0");
		dis_cmd(k++);
		key[x]=0;
		++x;
		pos++;
		break;

	case (14):
		string("#");
		dis_cmd(k++);
		key[x]=0;
		++x;
		pos++;
		break;

	case (13):
		system_reset=1;
		break;
	
	default: 
		;

}

_delay_loop_2(1600);

}

}
 
Last edited:

When you press the four buttons do you get the correct result?
Code:
key[0]=1, key[1]=2, key[2]=3, key[3]=4

If you do then
Code:
( (1000*key[0]) + (100*key[1]) + (10*key[2]) + key[3] );
will give a result of 1234 but this is a binary value, in order to show it in a display you have to convert it to four ascii characters

So do this instead to convert each digit to ASCII to show it in the display (assuming that this is what you want)
key[0] +='0';
key[1] +='0';
key[2] +='0';
key[3] +='0';
 
@alexan_e

No. He is displaying the keypresses using string("1"); etc., function calls in switch case statement and he is getting 0,1,2,3,... for 0,1,2,3,4,...
If 1 is pressed keycode will be 11, So, case (11) will be selected and string("1") displays 1 on lcd. His key[] is an int8_t array.
 
my main code is here

Code:
#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>
#include "eeprom.h"
#include "lcd.h"
//#include "keypad.h"
#include "user_interface.h"


int main(void)
{
    DDRB=0xFF;
    lcd_init();
        
        uint16_t password;
        uint8_t keyCode,x,pos;
        uint8_t prev_key=0xFF;
        int ct=1000;
        int pass=0;
        uint16_t newpassword;
        //if(ReadPassFromEEPROM()==255)
        //{
            //Password is blank so store a default password
            WritePassToEEPROM(1234);
        //}

        
        LCD_clear;
        LINE1;
        dis_cmd(0x84);
        string("Drive");
      _delay_ms(200);
    
    
    while(1){  
                    LCD_clear;
                   [COLOR=#ff0000] password=  InputNumber("Enter Password");//Get the keycode of pressed key[/COLOR]   /// worng 
                        
                        if(password==ReadPassFromEEPROM())
                        {
                          LCD_clear;
                          string(" Unlocked");    
                          _delay_ms(500);
                          while(GetKeyPressed()==255)
                          {
                              _delay_loop_2(10);
                          }                        
                        }
                        
                                                  
                   else if(keyCode=0)
                  { LINE2;
                    LCD_clear;
                  //string("");
                  newpassword = InputNumber("Enter new password");    
                  WritePassToEEPROM(newpassword);
                  string("changed");
                  _delay_ms(1000);
                  }
                  
                  else
                  {
                      LCD_clear;
                      string("Wrong Password");
                      _delay_ms(1000);
                  }    
        
          }             
    }

- - - Updated - - -

When you enter 1234 what is the return value you are getting from return((1000*key[0])+(100*key[1])+(10*key[2])+key[3]);?

Assign your return value to a int varible like
Code:
unsigned int retval = 0;
unsigned char sretval[5];

retval = InputNumber(char *msg);

Then convert retval to string like
Code:
sretval[0] = (retval/1000) + 48;
sretval[1] = (retval/100)%10 + 48;
sretval[2] = (retval/10)%10 + 48;
sretval[3] = (retval/1)%10 + 48;
sretval[4] = '\0'; 

string(sretval);


used it and displayed the string as 00001 when i pressed "1" key only one time . 4 zeros extra:???:

screen shoot
Untitled.jpg
 

Enter 1234 and reply what value you get. You have initialized Key[] to 0. So all the elements will be zero initially so 0001 is the right value. Have to see why you are getting the extra one 0.

retval is initially 0. so it will be like 00000000 00000000.
sretval[0] = '0', sretval[1] = '0', sretval[2] = '0', sretval[3] = '1' is the correct value if you enter 1.

I think the extra 0 is due to dis_cmd(k++); function. Initially k will be 0, k++ is 1. So, it should display 1 but displaying 0. Check if dis_cmd() is working or not.
Just insert a dummy function call dis_cmd(6); in the code. See if you get 6 on the lcd. Then enter 9876 and see what value you get on lcd. you have to enter 4 digits then only you get the retval because there is the condition if(pos==3). If you just enetered 1 i.e., pressed only one key then pos will not be 3, so may be the 1 you are getting is due to dis_cmd(k++); function and the four zeroes are because of sretval[].

Try this code, it will confirm whether the value you are getting is due to dis_cmd() or sting() function.

Code:
#include <avr/io.h>
#include <inttypes.h>
#include<util/delay.h>

#include "keypad.h"
#include "user_interface.h"
#include "lcd.h"

unsigned int retval = 0;
unsigned char sretval[5];

uint16_t InputNumber(char *msg)
{
	uint8_t keyCode,x=0,pos = 0;
	uint8_t prev_key=0xFF;
	uint8_t k=0xc1;
	uint8_t system_reset = 0;
	uint8_t key[]="####";
	dis_cmd(0x81);
	//string("Enter Password");
	while(*msg) dis_data(*msg++);
     LINE2;
	while(!system_reset)
		{
			
			
			
			
		
		
keyCode=GetKeyPressed(); 							//Get the keycode of pressed key



if(keyCode==prev_key)
continue;
else if(keyCode==0xFF)
{
	prev_key=0xFF;
	continue;
}
else
{
	prev_key=keyCode;
}


if(pos==3)
{
				
	retval = (1000*key[0])+(100*key[1])+(10*key[2])+1*key[3]);
	return 0;
	//return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3]));					//save the password in 16 bit integer
	//return(1234);
	//Wait for enter key or reset key
	//Convert pass to a single integer

	sretval[0] = (retval/1000) + 48;
	sretval[1] = (retval/100)%10 + 48;
	sretval[2] = (retval/10)%10 + 48;
	sretval[3] = (retval/1)%10 + 48;
	sretval[4] = '\0'; 

	string(sretval);
	break;
}



switch (keyCode) //generating key characeter to display on LCD					{
	case (11):
		string("1");	
		dis_cmd(k++);
		key[x]=1;
		++x;
		pos++;
		break;	
	
	case (10):
		string("2");	
		dis_cmd(k++);
		key[x]=2;
		++x;
		pos++;
		break;
	
	case (9):
		string("3");	
		dis_cmd(k++);
		key[x]=3;
		++x;
		pos++;
		break;
	
	case (7):
		string("nubere");
		dis_cmd(k++);
		key[x]=4;
		++x;
		pos++;
		break;
	
	case (6):
		string("5");
		dis_cmd(k++);
		key[x]=5;
		++x;
		pos++;
		break;
	
	case (5):
		string("6");
		dis_cmd(k++);
		key[x]=6;
		++x;
		pos++;
		break;
	
	case (3):
		string("7");
		dis_cmd(k++);
		key[x]=7;
		++x;
		pos++;
		break;
	
	case (2):
		string("8");
		dis_cmd(k++);
		key[x]=8;
		++x;
		pos++;
		break;
	
	case (1):
		string("9");
		dis_cmd(k++);
		key[x]=9;
		++x;
		pos++;
		break;
	
	case (15):
		string("0");
		dis_cmd(k++);
		key[x]=0;
		++x;
		pos++;
		break;

	case (14):
		string("#");
		dis_cmd(k++);
		key[x]=0;
		++x;
		pos++;
		break;

	case (13):
		system_reset=1;
		break;
	
	default: 
		;

}

_delay_loop_2(1600);

}

}

retval and hence sretval is displayed only when pos==3. If you get 1 when only 1 is pressed then it is due to dis_cmd(k++); Enter 9876 and see if you get 9876 on lcd.


-------------Update-------------------

OK. I found the problem. In the 00001 you are getting 0000 is the value of sretval and 1 is displayed because of string("1"); in case(11) statement when you pressed 1 key.

Try this new code.
Code:
#include <avr/io.h>
#include <inttypes.h>
#include<util/delay.h>
#include "keypad.h"
#include "user_interface.h"
#include "lcd.h"

unsigned int retval = 0;
unsigned char sretval[5];

uint16_t InputNumber(char *msg)
{
	uint8_t keyCode,x=0,pos = 0;
	uint8_t prev_key=0xFF;
	uint8_t k=0xc1;
	uint8_t system_reset = 0;
	uint8_t key[4]; //="####";
	dis_cmd(0x81);
	//string("Enter Password");
	while(*msg) dis_data(*msg++);
     	LINE2;
	while(!system_reset)
	{
		keyCode=GetKeyPressed(); 							

		//Get the keycode of pressed key

		if(keyCode==prev_key)
			continue;
		else if(keyCode==0xFF)
		{
			prev_key=0xFF;
			continue;
		}
		else
		{
			prev_key=keyCode;
		}


		if(pos==3)
		{
				
			retval = (1000*key[0])+(100*key[1])+(10*key[2])+1*key[3]);
			//return 0;
			//return(((1000*key[0])+(100*key[1])+(10*key[2])+key[3]));		

			//save the password in 16 bit integer
			//return(1234);
			//Wait for enter key or reset key
			//Convert pass to a single integer

			sretval[0] = (retval/1000) + 48;
			sretval[1] = (retval/100)%10 + 48;
			sretval[2] = (retval/10)%10 + 48;
			sretval[3] = (retval/1)%10 + 48;
			sretval[4] = '\0'; 

			string(sretval);
			break;
		}



		switch (keyCode) //generating key characeter to display on LCD			

		{
			case (11):
				string("1");	
				dis_cmd(k++);
				key[x]=1;
				++x;
				pos++;
				break;	
	
			case (10):
				string("2");	
				dis_cmd(k++);
				key[x]=2;
				++x;
				pos++;
				break;
	
			case (9):
				string("3");	
				dis_cmd(k++);
				key[x]=3;
				++x;
				pos++;
				break;
	
			case (7):
				string("nubere");
				dis_cmd(k++);
				key[x]=4;
				++x;
				pos++;
				break;
	
			case (6):
				string("5");
				dis_cmd(k++);
				key[x]=5;
				++x;
				pos++;
				break;
	
			case (5):
				string("6");
				dis_cmd(k++);
				key[x]=6;
				++x;
				pos++;
				break;
	
			case (3):
				string("7");
				dis_cmd(k++);
				key[x]=7;
				++x;
				pos++;
				break;
	
			case (2):
				string("8");
				dis_cmd(k++);
				key[x]=8;
				++x;
				pos++;
				break;
	
			case (1):
				string("9");
				dis_cmd(k++);
				key[x]=9;
				++x;
				pos++;
				break;
	
			case (15):
				string("0");
				dis_cmd(k++);
				key[x]=0;
				++x;
				pos++;
				break;

			case (14):
				string("#");
				dis_cmd(k++);
				key[x]=0;
				++x;
				pos++;
				break;

			case (13):
				system_reset=1;
				break;
	
			default: 
				;

		}

		_delay_loop_2(1600);

	}

}
 
Last edited:

yes sir i have debugging cappabilities but never used (dont know well how to ) .I am using AVR Studio6 .
where can i record the keycode value and how to see it ?

Concerning the debug issue:

Do you have a hardware programmer/debugger like the JTAGICE, JTAGICE mkII or Dragon? If so what specific model do you have?

If you do not have a hardware programmer/debugger, you will need to rely on software debugging techniques like outputting your debugging data by some method like the LCD or through the UART.


BigDog
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top