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.

Column and row scanning

Status
Not open for further replies.


does processor matter ..... logic is same for any processor.... did you understand the logic of keypad interface.... i had posted... then try the same code with your zilog header files and port pins
 

does processor matter ..... logic is same for any processor.... did you understand the logic of keypad interface.... i had posted... then try the same code with your zilog header files and port pins

yes.i understand it..
im creating my own program but it seems that something is wrong. my programs goes like this:

#include <eZ8.h>


void init(void)
{
// Set Data direction of GPIO's as outputs
PCDD &= 0x0F;

// Set Output Control
PAOC &= 0x00; // Use push pull configuration
PBOC &= 0x00;
PCOC &= 0x00;
PDOC &= 0x00;

row1= PBIN&0x00
row2= PBIN&0x01
row3=PBIN&0x02
row4= PBIN&0x03
col1=PBIN&0x04
col2=PBIN&0x05
col3=PBIN&0x06
}

void main(void)
{
unsigned int ctr=0:
init();


while(1)
{
if (row1==1 && col1==1);
PDOUT=0xFF;
for(ctr=0;ctr<65535;ctr++);
}
 

Dear Friends ,

May be i treat the same project , so i need your help , for my application i use PIC 16F877 with 4X3 matrix keypad and LCD display .

My goal is to test the keypad characters and send all the pressed number into LCD.

I start my programm with this character # that initialise the PIC to get the numbers the PIC will send to the LCD "Please write phone number" then clear it to write the numbers ,when finish the phone number we press * to confirm that the code is writed , this code will be appear in LCD following with '0' to confirm or '1' to repeat the number .

If the phone number is correct then we will save it in a variable called number1 , or number2,... and use it for other application.

The code desired is in C language , i have some doubts how to manage the characters in C.

Thanks .
 

The above posts are really two different threads.
akoangsimula - your code is not incorrect but it doesn't scan the keypad, it only looks for one combination of row and column. You need to rotate a '1' across the keypad outputs in a loop so that all the rows/columns are scanned in sequence.

First, decide which are the inputs to the keypad and which are the outputs. Walk a single '1' across the outputs while keeping the other outputs at '0'. Each time you have advanced to the next output state, read the inputs form the keypad. If the input is zero, no keys are pressed, if it isn't zero, calculate the key value using the pin sending the '1' and the pin receiving it.

Brian.
 

Thanks for your reply ,

The matrix keypad will occupy the RA0 , RA1 , RA2 and RA3 for the Rows, and the RB1 ,RB2 and RB3 for the columns. The rows are outputs and the columns are inputs.

This is the code that i wrote :
bit L1 @ RA0
bit L2 @ RA1
bit L3 @ RA2
bit L4 @ RA3
bit C1 @ RB1
bit C2 @ RB2
bit C3 @ RB3
void keyboard_total(void);
void keyboard_button(void)
{
If ((L4=1)&&(L3=1)&&(L2=1)&&(L1=0)) {
If ((C1= 0)&&(C2=1)&&(C3=1)) Return('1');
If ((C1= 1)&&(C2=0)&&(C3=1)) Return('2')
If ((C1= 1)&&(C2=1)&&(C3=0)) Return('3')}
If((L4=1)&&(L3=1)&&(L2=0)&&(L1=1)) {
If ((C1= 0)&&(C2=1)&&(C3=1)) Return('4')
If ((C1= 1)&&(C2=0)&&(C3=1)) Return('5')
If ((C1= 1)&&(C2=1)&&(C3=0)) Return('6')}
If((L4=1)&&(L3=0)&&(L2=1)&&(L1=1)) {
If ((C1= 0)&&(C2=1)&&(C3=1)) Return('7')
If ((C1= 1)&&(C2=0)&&(C3=1)) Return('8')
If ((C1= 1)&&(C2=1)&&(C3=0)) Return('9')
If((L4=0)&&(L3=1)&&(L2=1)&&(L1=1)){
If ((C1= 0)&&(C2=1)&&(C3=1)) Then Return('*')
If ((C1= 1)&&(C2=0)&&(C3=1)) Return('0')
If ((C1= 1)&&(C2=1)&&(C3=0)) Return('#')}
Else Return(0) // no touch or many touchs in same time
}

This code i wrote will return the key pressed , but need to get all the characters writed in same line ,the number should be at least 12 characters , as if the user write 00212676508090 on the keypad, the program will store this number in variable to use it for future.

Thanks And Best Regards.
 

That is certainly 'artistic' code, there are much simpler ways to do it.

To store a sequence of numbers you have to return numbers (but not zero) from your routine and store them in an array. For example:

unsigned char MyArray[12];
unsigned char ArrayPosition;

ArrayPosition = 0;

// call your code and get a number 'Number'

MyArray[ArrayPosition++] = Number;

That will store the number in the next array position each time you press a key. If you want to return only when 12 characters have been pressed, use 'if(ArrayPosition == 12) ........' to tell when the array is full.

Brian.
 

Thanks for your support friend,

Please let me write the code i developp basing on your help , may be there are something that i should add.
//first program
//test matrix keyboard
//hi-Tech
#include<stdio.h>
#include<16F887.H>
#define L1 @ RA0
#define L2 @ RA1
#define L3 @ RA2
#define L4 @ RA3
#define C1 @ RB1
#define C2 @ RB2
#define C3 @ RB3

unsigned char MyArray[12];
unsigned char ArrayPosition;
unsigned number;
//* to return back or delete ,# to enter into
//program to write numbers
//so if the user press # it accept the number
void store()
{

ArrayPosition = 0;
while (number==0X23){ // ASCII code for # in HEX

MyArray[ArrayPosition++] = number;
}

if(ArrayPosition == 12){
display_number();
}
}

// is a function that display
//the full number on the LCD

void keyboard_touch(void)
{
if((L4=L3=L2=1)&&(L1=0))
if ((C1=0)&&(C2=C3=1)) return('1')= number;
if ((C1= 1)&&(C2=0)&&(C3=1)) {return('2')=number;}
if ((C1= 1)&&(C2=1)&&(C3=0)) {return('3')=number;}

if((L4=1)&&(L3=1)&&(L2=0)&&(L1=1)) {
if ((C1= 0)&&(C2=1)&&(C3=1)) return('4')=number;
if ((C1= 1)&&(C2=0)&&(C3=1)) return('5')=number;
if ((C1= 1)&&(C2=1)&&(C3=0)) return('6')=number;

if((L4=1)&&(L3=0)&&(L2=1)&&(L1=1)) {
if ((C1= 0)&&(C2=1)&&(C3=1)) return('7')=number;
if ((C1= 1)&&(C2=0)&&(C3=1)) return('8')=number;
if ((C1= 1)&&(C2=1)&&(C3=0)) return('9')=number;}

if((L4=0)&&(L3=1)&&(L2=1)&&(L1=1)){
if ((C1= 0)&&(C2=1)&&(C3=1)) return('*')=number;
if ((C1= 1)&&(C2=0)&&(C3=1)) return('0')=number;
if ((C1= 1)&&(C2=1)&&(C3=0)) return('#')=number;
else return(0); // no touch or many touchs in same time
}
}


Thanks And Best Regards

Yassine.K
 

There are a few things wrong in your code:

1. void functions return no value so you can't define "void keyboard_touch(void)", it should be (a guess as you don't actually use the function) "unsigned char keyboard_touch(void)".
2. the 'store()' function sets the pointer to the array position to zero each time it is called, I think what you need to do is call 'store()' after each key press and only reset the pointer to zero at the start and after each time # is pressed. If you keep setting it to zero, the key number will always be saved in MyArray[0] instead of [1],[2]...
3. you have "while (number==0X23)", so it would only save into the array when # was the key pressed, I think it should be "while(number != 0x23)".
4. The most numbers you can store in myArray[] is 12 because that's the size it was created. You should add a check in the code so you can't store more than 12 digits or it will overflow.

Part of your code is still missing, there is nothing to scan the keypad, only code to read back if it had been scanned.

Brian.
 

Dear Brian,

The user press # one time to enter the full number , i use it for phone application to send informations into GR47 module ,

The details, basing on the phone numbers entred by the user and the Informations witch come from PC by RS232 , the PIC will send into the GR47 AT commands , to send SMS into the phone programmed , the LCD will display the phone number ,if accept press # to store , if not press * and return into the test keypad function without storing.


Thanks for your help

---------- Post added at 07:47 ---------- Previous post was at 07:24 ----------

Dear Brian ,

is this code can get only 12 numbers and store it .

unsigned char MyArray[12];
unsigned char ArrayPosition;
//* to return back or delete ,# to enter into
//program to write numbers
//so if the user press # it accept the number
void store()
{

ArrayPosition = 0;
while (number !=0X23){ // ASCII code for # in HEX , is the # pressed?

for(i=0 ,i=<12,i++){
MyArray[ArrayPosition++] = number;
}

display_number(); // is a function that display the full number on the LCD
control_number() // this function control if the number is correct or not , if yes it store it in variable called Number1 , Number2,...


Yassine.K

}
}
 

I understand the application better now but I still think your code is wrong. It is syntactically correct so the compiler will not show an error but I don't think it will function as you intend it to.

for(i=0 ,i=<12,i++){
MyArray[ArrayPosition++] = number;
}

the ',' should be ';' in the 'for' statement and you will set all 12 positions in the array to the same value 'number'. I think you are trying to store the numbers from the keypad so the first number goes in MyArray[0], the second number in MyArray[1] and so on.


I suggest you take a step back from writing the 'C' code and draw a flow chart of the process, it will help you to see the structure of code you need to write later.

Brian.
 

dear friend ,

So how can i store numbers from keypad in MyArray[0],...

Thanks for your support.
 

Flow chart it.

Basically I think this is what you are trying to do:

1. scan the whole keypad
2. if no keys were pressed, go back to step 1, otherwise go to step 3
3. if the key was '#' set the array counter to zero, otherwise go to step 4
4. store the digit in the array at the present counter position and if the counter is less than 12, add one to it
5. if the counter has reached 12, send the array contents to the phone then go to step 1.

That should loop until a key is pressed, check if it is a '#' and if it is, starts storing the next 12 digits. When 12 digits are stored it sends them to the phone.

Brian.
 

Hi ,

i created a program that manage the 3X4 keypad , and display the key pressed into LCD display , i compiled the code in MikroC for PIC and the compilation was successful , i get the HEX file and i put it into the PIC by the ISIS Version 7 software after creating the design .

when i try to run the simulation , the LCD display the default message , and when i press the keypad it shows errors , and i notice that some I/O that are programmed doesn't work.


Please can you help me to know the exact problem in my project.

Please find the program and the design in file attached.


Thanks.
 

Attachments

  • LCD.rar
    14 KB · Views: 58
  • myprogram.rar
    802 bytes · Views: 63

The program structure is wrong. As I stated earlier, you do not actually drive the keypad, you must do it like this:

L4 = 0; L3 = 0; L2 = 0; L1 = 1; //start with 0001
read the columns....
L2 = 1; L1 = 0; //change to 0010
read the columns....
L3 = 1; L2 = 0; // change to 0100
read the columns....
L4 = 1; L3 = 0; // change to 1000
read the colimns....

Also make sure the port direction for L4,L3,L2 and L1 is 'output' and the direction for C3, C2 and C1 is 'input'.

Brian.
 

Hi,

Thanks for your reply , please find attached the new program and tell what you see .

Best regards.
 

Attachments

  • myprogram.rar
    775 bytes · Views: 51

I'm not even going to guess what that does!

Follow the instructions I gave you, you do not need any 'case' or 'switch' statements and you can probably make all your code in less than 10 lines. you are making it much more complicated than it needs to be and you still do not produce the signal to drive the rows (lines).

You MUST do this:
Make the 'L' pins outputs so you can use them to send the signals to the keypad. Make the 'C' pins inputs so you can read the keypad back.
There are four lines (L) driving the keypad, you must make one of these lines high and the other lines low. (for example L4 = 0; L3=0; L2 = 0; L1 = 1 produces data 0001 on the keypad rows)
After setting the row signals, read back the columns (C). If all C lines are zero then no key is pressed, otherwise one of C1, C2 or C3 will be '1' depending on which key on that column and row was pressed. You can easily convert this to the real key number.
Repeat three times, setting a different row (L) to '1' each time.

With a little thought, you can work out the mathematic relationship between the L signals and C signals for eack key and calculate it with a simple formula.

Brian.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top