Keypad Module question

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Ok. Now apply the pull-up resistors to the 4 x 4 keypad matrix.
How would you detect that a key is pressed?
Let's assume I have following 4*4 matrix keypad with pull up resistors

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16


A 4×4 matrix keypads consists of 4 rows and 4 columns. This is roughly how the keypads table looks like:

set R/CSet C1set C2set C3set C4check C1check C2check C3check C4Button
R1 0
R2 1
R3 1
R4 1
11110
1
1
1
1
0
1
1
1
1
0
1
1
1
1
0
1 Pressed
2 Pressed
3 Pressed
4 Pressed
R1 1
R2 0
R3 1
R4 1
11110
1
1
1
1
0
1
1
1
1
0
1
1
1
1
0
5 Pressed
6 Pressed
7 Pressed
8 Pressed
R1 1
R2 1
R3 0
R4 1
11110
1
1
1
1
0
1
1
1
1
0
1
1
1
1
0
9 Pressed
10 Pressed
11 Pressed
12 Pressed
13 Pressed
R1 1
R2 1
R3 1
R4 0
11110
1
1
1
1
0
1
1
1
1
0
1
1
1
1
0
14 Pressed
15 Pressed
16 Pressed
17 Pressed
R1 1
R2 1
R3 1
R4 1
11111111Not Pressed any key

I hope logic table make sense to scan 4*4 matrix keypad
 
Last edited:

MrChips

Joined Oct 2, 2009
30,824
As I said, take one step at a time.
As a first step, do not worry about which key is pressed. Simple determine that any key is pressed.

Now post the pseuo-code for this.
No table, no flow-chart.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Now post the pseuo-code for this.
No table, no flow-chart.
This is the pseuo-code I made from the table

C:
//function to read  key
unsigned char Keypad_Scan()
{
  /*Scane Row1*/
  R1 = 0;       //Make R1 to low(0)
  R2=R3=R4=1;   //Make All other Row to high(1)
  if(C1 == 0)   //If Switch in columns1 is pressed
      return 1; //return '1'
 
  if(C2 == 0)   //If Switch in columns2 is pressed
     return 2;    //return '2'
    
  if(C3 == 0)   //If Switch in columns3 is pressed
      return 3; //return '3'
 
  if(C4 == 0)//If Switch in columns4 is pressed
      return 4; //return '4'
      
 
/* scane Row2*/
  R2 = 0;     //Make ROW2 to low(0)
  R1=R3=R4=1; //Make All other Row to high(1)
 
  if(C1 == 0) //If Switch in columns1 is pressed
    return 5; //return '5'
    
  if(C2 == 0)//If Switch in columns2 is pressed
    return 6;   //return '6'
    
  if(C3 == 0)//If Switch in columns3 is pressed
    return 7; //return '7'
      
  if(C4 == 0)//If Switch in columns4 is pressed
    return 8;  //return '8'
      
/*Scane Row3 */
  R3 = 0;  //Make ROW3 to low(0)
  R1=R2=R4=1;//Make All other Row to high(1)

  if(C1 == 0)//If Switch in columns1 is pressed
    return 9; //return '9'
      
  if(C2 == 0)  //If Switch in columns2 is pressed
    return 10;   //return '10'
    
  if(C3 == 0)//If Switch in columns3 is pressed
    return 11;  //return '11'
      
  if(C4 == 0)  //If Switch in columns4 is pressed
    return 12;  //return '12'

  
/*Scane Row4*/   
  R4 = 0;  //Make ROW4 to low(0)
  R1=R2=R3=1;//Make All other Row to high(1)
 
 if(C1 == 0)//If Switch in columns1 is pressed
     return 13;  //return '13'
      
  if(C2 == 0)//If Switch in columns2 is pressed
    return 14;  //return '14'
    
  if(C3 == 0)//If Switch in columns3 is pressed
    return 15; //return '15'
      
  if(C4 == 0)//If Switch in columns4 is pressed
    return 16; //return '16'
      
  return '\0';
}
 

MrChips

Joined Oct 2, 2009
30,824
If would appear that you do not understand what is meant by pseudo-code.
Therefore I will give you my solution for either option.

Option A - with pull-down resistors on input pins
Set all four output pins to HIGH.
Read four input pins.
If any input pin is HIGH, then a key is pressed.

Option B - with pull-up resistors on input pins
Set all four output pins to LOW.
Read four input pins.
If any input pin is LOW, then a key is pressed.
 

jpanhalt

Joined Jan 18, 2008
11,087
If would appear that you do not understand what is meant by pseudo-code.
Therefore I will give you my solution for either option.

Option A - with pull-down resistors on input pins
Set all four output pins to HIGH.
Read four input pins.
If any input pin is HIGH, then a key is pressed.

Option B - with pull-up resistors on input pins
Set all four output pins to LOW.
Read four input pins.
If any input pin is LOW, then a key is pressed.
What about setting outputs to high, inputs on the IOC pins and waiting for an interrupt or IF rather than polling everything?
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
If would appear that you do not understand what is meant by pseudo-code.
I understand use of pull up and pull down register. My comments show step of pseudo-code
What about setting outputs to high, inputs on the IOC pins and waiting for an interrupt or IF rather than polling everything?
We can do the same with with interrupt on change, so checking it in each run is purely a waste of time. In PIC microcontrollers, PORT B has the Interrupt on Change feature. the interrupt occurs when there is a state change in any of the port pin associated with this feature.
 

MrChips

Joined Oct 2, 2009
30,824
What you have shown in post #43 is not pseudo-code.

My example in post #45 is an example of pseudo-code.
Notice in my example there is no computer code. There is no reference to any MCU or computer language.
There is no port or pin assignment. I do not say which pin or which port is being used.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
What you have shown in post #43 is not pseudo-code.
Let's move on, Now I am thinking that if I press any button in the keypad it should display on the LCD

In this thread, I have made a function that can be read the key press

I had thread https://forum.allaboutcircuits.com/threads/write-data-to-lcd-flow-chart.165615/page-2 where I can write data to LCD. see code in post #31 I have tested code and it's working fine

Now I want to make a common program for both keypad and LCD to achieve target.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
Ok. You can move on without further assistance from me.
MrChips I am sorry If you hurt, I apologize for this, I do not want to hurt your feelings. English is not my first language You can see in my signature

I like working with you. You have come a long way and I have just started on the path, you know better than me. Each of your advice would be good for me

Please tell me what i should do next. I will do as you say
 
Last edited:

MrChips

Joined Oct 2, 2009
30,824
MrChips I am sorry If you hurt, I apologize for this, I do not want to hurt your feelings. English is not my first language You can see in my signature

I like working with you. You have come a long way and I have just started on the path, you know better than me. Each of your advice would be good for me

Please tell me what i should do next. I will do as you say
You did not hurt my feelings. I just ran out of patience.
Let's see how you do with advice from someone else.
 

jpanhalt

Joined Jan 18, 2008
11,087
Let's move on, Now I am thinking that if I press any button in the keypad it should display on the LCD
1) First, define what you mean by "it" on an LCD. For example, do you mean the arbitrary value you have assigned to that button or the bit pattern in the byte that you read? That may sound obvious to you, but I have a well-used subroutine for reading and displaying a byte on an LCD. It helps in debugging under "run" conditions.
2) The byte pattern is dependent on how you wire the keypad and set up the MCU. You need to provide that schematic and processor set-up.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
You need to provide that schematic and processor set-up.
What about setting outputs to high, inputs on the IOC pins and waiting for an interrupt or IF rather than polling everything?
I am taking one step back. So now I will try to understand interrupt on Change IOC without the keypad

I want to show my hardware connection before writing a program

Is everything correct ?

1579055926737.png
 

jpanhalt

Joined Jan 18, 2008
11,087
The IOC pins on the 16F877A are RB<4..7> (pins #37..40, respectively):
1579063593059.png

You show the buttons connected to RB<0..3>:
1579063707241.png

Did you notice the pins on the chip you are simulating are not located symmetrically on each side?

I think you would be well served to use a device in your simulator that has the pins in the same position as they are on the actual chip. Which raises the question of whether your past schematic posts suffered the same error.
 
Last edited:

Thread Starter

Gajyamadake

Joined Oct 9, 2019
310
The IOC pins on the 16F877A are RB<4..7> (pins #37..40, respectively):
View attachment 196912
Okay I have corrected my mistake

This is modified version of hardware

1579094855508.png



C:
// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 20000000

void interrupt  ISR(void)
{
   if(RBIF==1)
  {
       if (RB4 ==0)
       {
          RD0=~RD0;
          __delay_ms(40);//Delay 40 milliseconds
        RBIF = 0;    
       }

       if (RB5 ==0)
       {
          RD1=~RD1;
          __delay_ms(40);//Delay 40 milliseconds
        RBIF = 0;    
       }

       if (RB6 ==0)
       {
          RD2=~RD2;
          __delay_ms(40);//Delay 40 milliseconds
        RBIF = 0;    
       }
       if (RB7 ==0)
       {
          RD3=~RD3;
          __delay_ms(40);//Delay 40 milliseconds
        RBIF = 0;    
       }

  }

}


void main(void)
{
    /*Port B as a Input */
    TRISB0=0xFF;

    /*Port D as a Output */
    TRISD=0;

    PORTD = 0x00;

    /* Register PORTB interrupt */
    OPTION_REG = 0b00000000;

    INTCON = 0b11001000;
    while(1) {
 
    }
}
if I press p1, blue led become On
if I press p2 , red led become On
if I press P3, green led become On
if I press P4, yellow led become On

if I press again p1, blue led become Off
if I press again p2 , red led become Off
if I press again P3, green led become Off
if I press again P4, yellow led become Off
 
Last edited:
Top