Not able to read key press from 4X4 HEX keypad

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm new to AVR,I'm trying this code but its not working,I'm not able to read the keypress,Here there is code for only first row scanning... Pls guide me....

#include 
#include 
#include 


#define ROW1	PINC0	// pin1
#define ROW2	PINC1	// pin2
#define ROW3	PINC2	// pin3
#define ROW4	PINC3	// pin4 

#define COL1	PIND0	// pin1
#define COL2	PIND1	// pin2
#define COL3	PIND2	// pin3
#define COL4	PIND3	// pin4

int main(void)
{
	DDRA=0xFF; // Making PORTA as output Port (DATA)
	DDRB=0x07; // Making PORTB as output (CONTROL)
	
        LCD_init(); // LCD Intialization
	LCD_goto(1,1); // To choose from which line and character the string has to be displayed 
	LCD_print("THE PRESSED KEY:"); // String which has to be displayed on LCD
    
	
	MCUCSR=(1<<JTD);    // DISABLING JTAG
        MCUCSR=(1<<JTD);
	
        DDRC=0x00;		
        DDRD=0xFF;
    
	PORTC=0x00;		//MAKING PORTC AS INPUT
	PORTD=0xFF;		//MAKING PORTD AS OUTPUT
	
   
        PORTD = PORTD & 0x7F;     // link column 1 to GND (PORTB0 = 0) 
      
        asm volatile ("nop");  
    
        while(COL1==0)              //CHECK IN 1sT COLOUMN
	{
     
	 if (ROW1==1)               //CHECK IF ANY KEY IN ROW 1 IS PRESSED
	   {
          
           LCD_goto(2,7); 
           LCD_print("0");
           break;
	   } 
   
         else if (ROW2==1)         //CHECK IF ANY KEY IN ROW 2 IS PRESSED
	   {
            LCD_goto(2,7); 
            LCD_print("1");
	    break;
	   }
 
         else if (ROW3==1)         //CHECK IF ANY KEY IN ROW 3 IS PRESSED
	   {    
            LCD_goto(2,7); 
	    LCD_print("2");
	    break;
	   } 
          
         else if (ROW4==1)         //CHECK IF ANY KEY IN ROW 4 IS PRESSED
	   {    
            LCD_goto(2,7); 
            LCD_print("3");
	    break;
	   }
    }  
}

[capitals removed from thread title and CODE tags added. Please use normal case for thread titles in future and add your own CODE tags around sequences of code - moderator]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're not reading the pin register for port C or D. PINC0 has the value of 0, C1=1 and so on. Youmneed to do something like this:

If ( PINC & (1<<PINC0))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But i've globally defined PINC0 as ROW1 and PIND0 as COL1 and so on...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What Kartman is saying, Praveen, is that PINC0 is defined to be a bit number rather than a bit mask.

Although, as you say, you have defined "ROW1" as PINC0, you are still referring to bit numbers.

What you need is something like...

if (PINC & (1 << ROW1))

As this converts the bit number (0) into a mask (0x01).

I hope that helps.

/A

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh oh... Got it... Thanks AndyG... I changed the code as below

while(PIND & (0 << COL1))              //CHECK IN 1sT COLOUMN
	{
     
	 if  (PINC & (1 << ROW1))              //CHECK IF ANY KEY IN ROW 1 IS PRESSED
	   {
          
           LCD_goto(2,7); 
		   LCD_print("0");
		   break;
	   } 
   
      else if (PINC & (1 << ROW2))       //CHECK IF ANY KEY IN ROW 2 IS PRESSED
	   {
            LCD_goto(2,7); 
		    LCD_print("4");
			break;
	   }
 
      else if (PINC & (1 << ROW3))         //CHECK IF ANY KEY IN ROW 3 IS PRESSED
	   {    
            LCD_goto(2,7); 
		    LCD_print("8");
			break;
	   } 
          
       else if (PINC & (1 << ROW4))         //CHECK IF ANY KEY IN ROW 4 IS PRESSED
	   {    
            LCD_goto(2,7); 
		    LCD_print("C");
			break;
	   }
    }  
}

But when i press the key,the LCD is just blinking... Not getting the display on LCD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while(PIND & (0 << COL1)) //CHECK IN 1sT COLOUMN 

This line does not make sense, Praveen. The "while" loop will never execute.

/A

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
PORTD = PORTD & 0x7F; // link column 1 to GND (PORTB0 = 0)

You need to clear column 1 and set all other columns. This code does not do this.
Use

PORTD |= 0x0f; // set all columns
PORTD &= ~(1<<COL1); // clear COL1

And you should test for 0, not for 1.

if ((PINC&(1<<ROW1))==0) //CHECK IF ANY KEY IN ROW 1 IS PRESSED  
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...................................................................................................................................
Try this

#include 
#include 
#include 

#define setbit(port,bit)  ((port) |=  (1<<bit)) // set bit
#define clrbit(port,bit)  ((port) &= ~(1<<bit)) // clear bit

#define ROW1 PINC0 // pin1
#define ROW2 PINC1 // pin2
#define ROW3 PINC2 // pin3
#define ROW4 PINC3 // pin4

#define COL1 PD0 // pin1
#define COL2 PD1 // pin2
#define COL3 PD2 // pin3
#define COL4 PD3 // pin4

int main(void)
{
   DDRA=0xFF; // Making PORTA as output Port (DATA)
   DDRB=0x07; // Making PORTB as output (CONTROL)
   DDRD=0xFF;
   DDRC=0x00;
   PORTC |= 0x0f; // pull-up on input pins
    
   LCD_init(); // LCD Intialization
   LCD_goto(1,1); // To choose from which line and character the string has to be displayed
   LCD_print("THE PRESSED KEY:"); // String which has to be displayed on LCD

   MCUCSR=(1<<JTD); // DISABLING JTAG
   MCUCSR=(1<<JTD);

   PORTC=0x00; //MAKING PORTC AS INPUT
   PORTD=0xFF; //MAKING PORTD AS OUTPUT

   while(1)  // main loop
   {
      // FIRST COLUMN
      PORTD = PORTD & 0x0F; // set all columns to 1 
      clrbit(PORTD,COL1);   // link column 1 to GND (PORTB.0 = 0)
      asm volatile ("nop");

      while (bit_is_clear(PIND,COL1)) //CHECK IN 1sT COLOUMN
      {
         _delay_ms(50);  // debounce
         
         if (bit_is_clear(PINC,ROW1)) //CHECK IF ANY KEY IN ROW 1 IS PRESSED
         {
            LCD_goto(2,7);
            LCD_print("0");
            break;
         }

         if (bit_is_clear(PINC,ROW2)) //CHECK IF ANY KEY IN ROW 2 IS PRESSED
         {
            LCD_goto(2,7);
            LCD_print("1");
            break;
         }
         // test ROW 3,4
      
         loop_until_bit_is_set(PIND,COL1); // wait for buton released
      }
      
      // SECOND COLUMN
      PORTD = PORTD & 0x0f; // set all columns to 1 
      clrbit(PORTD,COL2);   // link column 2 to GND (PORTB.1 = 0)
      asm volatile ("nop");

      while (bit_is_clear(PIND,COL2)) //CHECK IN 2nd COLOUMN
      {
         _delay_ms(50);  // debounce
         
         if (bit_is_clear(PINC,ROW1)) //CHECK IF ANY KEY IN ROW 1 IS PRESSED
         {
         ...
         ...

   } //while(1)
} //main()
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank u Visovian... U made me understand how it acually works... The program worked...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've edited thread title and code tags above. Please see my note in the first post. [Moderator]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now I have noted a mistake.

         loop_until_bit_is_set(PIND,COL1); // wait for buton released

Put this line on the end of while(1) loop (after all columns checked).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Visovian wrote:
Now I have noted a mistake.

         loop_until_bit_is_set(PIND,COL1); // wait for buton released

Put this line on the end of while(1) loop (after all columns checked).

Probably a good idea (for future readers) for you to edit your code to include this. Less confusion/mistakes.

Cheers,

Ross

Ross McKenzie, Melbourne Australia