Keypad Interfacing Using Digital I/O Ports

 


COMSATS UNIVERSITY ISLAMABAD

 

MICROPROCESSOR SYSTEMS AND INTERFACING

                        LAB REPORT 6

SUBMITTED TO:

SIR KHIYAM IFTIKHAR

SUBMITTED BY:

JUNAID AHMAD

IBRAR AHMAD

JARRAR MALIK

REGISTRATION NO:

CIIT/FA19-BEE-089/ISB

CIIT/FA19-BEE-083/ISB

CIIT/FA19-BEE-087/ISB

 

DATE:

01-10-2021

Keypad Interfacing Using Digital I/O Ports

 

Objectives:

      Using digital I/O ports of AVR microcontroller for digital Inputs.

      Use I/O ports To Interface matrix keypad with microcontroller.

Tools:

Software Tools:

      AVR Studio/ Microchip Studio

      Proteus ISIS

      AVRDUDESS

Hardware Tools:

Name

Value

Quantity

Arduino Nano

-

1

4X4 Keypad

-

-

Resistors 

100Ω

8

 

PRE-LAB:

6.1 4x4 Membrane Keypad:

The Keypad 4x4 features 16 push buttons arranged in 4x4 matrix to form standard alphanumeric keypad. It provides a useful human interface component for microcontroller projects.Matrix keypads uses a combination of four rows and four columns to provide button states to the microcontroller. Underneath each key is a pushbutton, with one end connected to one row, and the other end connected to one column. These connections are shown in figure 6.1. 

 

Key Specifications 

      Maximum Rating: 24 VDC, 30 mA 

      Interface: 8-pin access to 4x4 matrix

      Operating temperature: 32 to 122 °F (0 to 50°C) 

      Dimensions: Keypad, 2.7 x 3.0 in (6.9 x 7.6 cm) Cable: 0.78 x 3.5 in (2.0 x 8.8 cm) 

This keypad can be used in Security systems, Menu selection, Data entry for embedded systems and various other applications.

 


6.2 Working of keypad:

As can be seen in figure 6.1, the buttons consist of 16 switches that are normally open. When one button is pressed, a pair of pins are connected, as seen in figure 6.2. As shown in the figure, the R2 and C2 pins will help determine the button that is pressed.  


 

Figure 6.2 – Standard 4x4 Keypad

To use a keypad with a microcontroller, it should be connected to in a way where either the rows are the input to the controller and the columns are the output to the microcontroller, or vice-versa. Suggested connections are shown in figure 6.3.


 

Figure 6.3 – Button Matrix Connection

You should remember the role of IO-registers in the ATmega328p as illustrated in figure 6.4. Assume all the 4 rows are initially set as input (by virtue of DDRx register). The programmer will have to scan the rows to determine if a button is pressed. Normally, the values on the row would be all 0 i.e. R4-R1 == 0000. When the button is pressed as shown in figure 5.2, the value would change to R4-R1 == 0010.

The fundamental idea is that the program keeps scanning the rows as long as no button is pressed. However, as soon as a button is pressed, inverse the rows to outputs and the columns to input. This would happen so fast that the button will still be pressed. So, on scanning the columns, C4-C1 == 0010. In this one can identify the button that is pressed, which in this case is ‘5’. [hint: the sequence 0010-0010 could signify ‘5’, or R1-C4 can be represented by 1000-0001 signifying ‘A’]


 

Figure 6.4 – ATmega328p port registers roles 

 

 

 

 

 

In order for the microcontroller to determine which button is pressed, following steps are followed:

1)      Create a look-up table filled with 16 entries for all keys of the keypad.

2)      Four microcontroller pins should be defined as outputs, and other four pins should be defined as inputs. 

3)      Connect columns of the keypad to input port and rows to the output port. Pull up the input port and then read the value of columns.

4)      Now connect rows of the keypad to input port and columns to the output port. Pull up the input port and then read the value of rows.

5)      If no key is pressed, the value of rows and columns will be 0000. If any key is pressed, the value of rows and columns can be 0000,0001,0010,0100,1000 (1,2,4,8).

6)      If no key is pressed, return 0. If a key is pressed, find its location in the keypad look-up table and return the key pressed.

 

IN-LAB TASK:

 

TASK 1:

 

Interfacing Atmega 328P with Keypad:

Connect a keypad to the microcontroller. Scan the keypad for key press and display the pressed key on the serial monitor using serial communication.

 

MAIN.C

#include "maininc.h"

#include "keypadtable.h"

#include <avr/io.h>

 

int main(void)

{

    /* Replace with your application code */

   

          unsigned char ch;

          UCSR0B&=~(1<<TXEN0);

          UCSR0B&=~(1<<RXEN0);

          while (1)

    {

    ch=readkeypad();

    //if (ch==0b01111110)

                   //{DDRB=0xff;     PORTB=1;}

         

          switch(ch){

                  

                   case one:                                  writetoport(1); break;

                   case 0b10111110:           writetoport(2);      break;

                   case 0b11011110:           writetoport(3);      break;

                   case 0b01111101:           writetoport(4);      break;

                   case 0b10111101:           writetoport(5);      break;

                   case 0b11011101:           writetoport(6);      break;

                   case 0b01111011:           writetoport(7);      break;

                   case 0b10111011:           writetoport(8);      break;

                   case 0b11011011:           writetoport(9); break;

                   case 0b10110111:           writetoport(0);      break;

                   default:                 writetoport(ch);

          }

          //writetoport(1);

         

          }

}

 

 

 

READKEYPADALGO.C

#include "readkeypadinc.h"

#define F_CPU 16000000UL

#include <util/delay.h>

#include <avr/io.h>

#define rlength 4   //Number of row pins

#define clength 3

 

char readkeypad(){

         

          char row,col,in;

          //TWCR=0x00;

          DDRC=0xff;

          setrowoutcolin();

         

          waitforpress();

          _delay_ms(80);//For debouncing

          col=readport();

          _delay_ms(10);

          setcoloutrowin();

          _delay_us(5);//If this delay is less than 4us, correct value is not updated in PIND

          row=readport();

          waitforrelease();

          _delay_ms(80);// For debouncing

         

          in=(col+row);

         

          return (in);

}

 

 

         

 

WRITETOPORT.C

 

#include <avr/io.h>

 

void writetoport(char ch){

         

         

 

 

PORTC=ch;

         

}

 

 

 

 

       

ACCESSPINS.C

 

#include <avr/io.h>

#include <util/delay.h>

#define col0 PORTD4

#define col1 PORTD5

#define col2 PORTD6

#define col3 PORTD7

 

#define row0 PORTD0

#define row1 PORTD1

#define row2 PORTD2

#define row3 PORTD3

 

 

 

 

#define colpins(a,b,c,d) (((1<<a)|(1<<b)|(1<<c)|(1<<d)))

#define rowpins(e,f,g,h) (((1<<e)|(1<<f)|(1<<g)|(1<<h)))

 

void setcoloutrowin(){

         

          DDRD&=~ rowpins(row0,row1,row2,row3);         //ROWS in (first change status to input )

         

          PORTD=rowpins(row0,row1,row2,row3);   //Pullup (modify complete port, not selected bits otherwise previously

         

         

          DDRD|=colpins(col0,col1,col2,col3); //col out(if this is used 1st then both connected

                                                                                                // will be output i.e output connected to other output)                          

         

         

         

         

}

 

void setrowoutcolin(){

 

DDRD&=~ colpins(col0,col1,col2,col3);//cols in

 

PORTD=colpins(col0,col1,col2,col3); //Pullup (modify complete port, not selected bits otherwise previously

 

//pulled up remain at 1. So set them to zero. This way input pulled to output also goes through intermediate stage

 

//_delay_ms(2);

DDRD|=rowpins(row0,row1,row2,row3);    //row out

 

//PORTC=(PIND&0xF0)>>4;

 

}

 

 

void waitforpress(){

         

_delay_us(5);        //If this delay is removed PIND remains zero and thus doesn't wait for press. If set >1us and < 5us than PIND gets set correctly for while check but not for the next debug instruction i.e PORTC=PIND&0xF0. Half the bits still remain zero

//PORTC=(PIND&0xF0)>>4; 

 

          while ((PIND&0xF0)==0xF0)

          {

          }

 

 

}

 

 

void waitforrelease(){

//PORTC=(PIND&0x0f);

          //_delay_us(1);     

          while ((PIND&0x0F)!=0x0F)

          {

          }

 

PORTC=(PIND&0x0f);          

}

 

 

char readport(){

         

          return PIND;

         

}

 

 

 

BUILD ON AVR:



TASK 2:

 

SIMULATION:



TASK 3:

 

HARDWARE:




CRITICAL ANAYSIS:

 

In this lab experiment we got to know how to interface keypad by using digital I/O ports. An Avr code was created and burned in Arduino and was connected to keypad. After compiling the code on AVR, we simulated it on proteus and checked the functioning of 4*4. For the functioning of keypad we used look-up table filled with 16 entries for all keys of the keypad and used four microcontroller pins as outputs, and other four pins should be defined as inputs. For reading the values of columns we set the columns to input and pulled up the columns whereas we set the rows to output and pulled them down. Secondly, for reading the values of rows we set the rows to input and pulled up the rows whereas we set the columns to output and pulled them down. The Keypad 4x4 features 16 push buttons arranged in 4x4 matrix form so that when we implemented this task on hardware and one of the 16 buttons were pressed, a pair of pins were connected together, and the numeric value was displayed on Arduino IDE.

 

         

 

Post a Comment

Post a Comment (0)

Previous Post Next Post