Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

4x3 Membrane Keypad

Status
Not open for further replies.

noname06

New Member
Hi, anyone knows if there is any error in my keypad coding...I am using pull up resistor way..The row part is ok..when i press a button it goes low..but for the column part it always go low...for the column 3 it is special... when a button is pressed it will go high instead..i do not know where is the mistake make..

#define _XTAL_FREQ 20000000
#include <htc.h>
#include <stdio.h>
#include <p18f4550.h>
#include "config.h"
#include "lcd.h"

#define ROW1 RA0 //row as output
#define ROW2 RA1
#define ROW3 RA2
#define ROW4 RA3
#define COL1 RA4 //column as input
#define COL2 RA5
#define COL3 RA6

void keypad();

void init()
{

TRISA=0B00001111; //row as input to the PIC
PORTA=0B00000000;

TRISB=0B00000000;
PORTB=0B00000000;

TRISD=0B00000000;
PORTD=0B00000000; //LCD
}

void main()
{
init();
lcd_init();

while(1)
{
COL1=0; //set col1 to low
COL2=1;
COL3=1;

while(!ROW1) //if row1 col 1 is pressed (row1 low)
lcd_puts("1");

while(!ROW2)
lcd_puts("4");

while(!ROW3)
lcd_puts("7");

while(!ROW4)
lcd_puts("*");

COL1=1; //set col2 to low
COL2=0;
COL3=1;

while(!ROW1)
lcd_puts("2");

while(!ROW2)
lcd_puts("5");

while(!ROW3)
lcd_puts("8");

while(!ROW4)
lcd_puts("0");

COL1=1; //set col3 to low
COL2=1;
COL3=0;

while(!ROW1)
lcd_puts("3");

while(!ROW2)
lcd_puts("6");

while(!ROW3)
lcd_puts("9");

while(!ROW4)
lcd_puts("#");
}
}
 
Your code does not help without a schematic. Can you post up the schematic?
 
You need to drive the keypad via tristating the column driver pins. Something like this -

Code:
	TRISA = 0xFF;			//PORTA tristate
	PORTA = 0;			//clear PORTA output latch

//check column 1

	while(1)				//loop forever
	{

		TRISA = 0b11101111;		//drop RA4
		if(!ROW1)
		{
			lcd_puts("1");
		}

		if(!ROW2)
		{
			lcd_puts("4");
		}

		if(!ROW3)
		{
			lcd_puts("7");
		}

		if(!ROW4)
		{
			lcd_puts("*");
		}

//check column 2

		TRISA = 0b11011111;		//raise RA4, drop RA5	
		if(!ROW1)
		{
			lcd_puts("2");
		}

		if(!ROW2)
		{
			lcd_puts("5");
		}

		if(!ROW3)
		{
			lcd_puts("8");
		}

		if(!ROW4)
		{
			lcd_puts("0");
		}

//check column 3
	
		TRISA = 0b10111111;		//raise RA5, drop RA6

		if(!ROW1)
		{
			lcd_puts("3");
		}

		if(!ROW2)
		{
			lcd_puts("6");
		}

		if(!ROW3)
		{
			lcd_puts("9");
		}

		if(!ROW4)
		{
			lcd_puts("#");
		}
	}
 
Last edited:
Have you measured the contact resistance with a button pressed, the pullups on the schematic you linked to are faitly low values, fine for metal to metal contacs (which you'd expect for a membrane) but a bit low if the contacts are conductive rubber or something.
 
what do mean by contact resistance?? is it mean i have to put a higher resistance value?? my column which suppose to go high is always going low around 0.12V...when i press a button is become 0.25...but the last column is totally 0V..
 
Some keypads are a mechanical contact creating a short when a button is pressed, there will be less than 1 ohm between the row and column selected, conductive rubber keypads can be a few tens or a 100 ohms or so, meaning the pullup resistor needs to be higher, more like 1k to 10k, depending on the actual resistance of the uP input port , a pic16f628 has worked well for me with 4k7 pullups.

I've never used the tristate technique, though it sounds more energy efficient, my code puts a logic 0 on all the rows and waits for a 0 on one of the colums, ie a button pressed, then a 0 is shifted along the rows untill the actual key pressed is found.
I'm sure theres better ways of doing it, thers some clever ways that only use a few pins, one method uses just 1 pin.
 
Last edited:
I've never used the tristate technique, though it sounds more energy efficient

The neat thing about the tristate technique is that it eliminates the need for "sink only" protection diodes to protect the output drivers in the event that two buttons on the same row/different columns are pressed simultaneously. With the column driver pins tristated, you cannot short the output driver if this happens.
 
Last edited:
If you have a chip without short protection thats very sensible, also thinking about it you could use all the inputs for other things with a little code overhead.
I'll bear that in mind when I'm next trying to cram several 8 bit ports onto an 'f628.
 
That's the beauty of having tri-state ports. Makes bus driving and multiplexing loads easier.

Some will say "Why multiplex when you can use a uC with more than enough pins?". Well...simple. No matter how many pins a uC has, it will always be able to do more via multiplexing than it can without. It's all relative. ;)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top