|
|
View previous topic :: View next topic |
Author |
Message |
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
Problem in getting a char array from a 4x4 keypad!!! |
Posted: Wed Feb 09, 2011 8:29 am |
|
|
Hello everyone,
I am trying to get a 4 digit idNo from a keypad and want to display it on a character lcd. I put all the characters into an array named idNo, after that I put 0x00 to the last element of the array like PCM programmer said in
http://www.ccsinfo.com/forum/viewtopic.php?p=130746
http://www.ccsinfo.com/forum/viewtopic.php?t=36304&start=2
after that I tried to convert this char array into an integer named "no" using atoi() function. Then I have tried to put this integer in to lcd but it generally gives a "0", besides it gives "0" when I push the button second time not in 5th time. I could not figure out what I do wrong. Any help will be appreciated.
Code: |
#include <18F4550.h>
#include <stdlib.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#include <flex_lcd.c>
#byte portb = 0xf81
#use fast_io(b)
int1 keyPressed=false;
char key='\0';
char idNo[5];
int no;
static int oldBState;
int i=0;
void getKey(void){
int pin, bState, delay = 10;
delay_ms(50);
disable_interrupts(INT_RB);
pin=4;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '1';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '2';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '3';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'A';
}
}
pin=5;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '4';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '5';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '6';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'B';
}
}
pin=6;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '7';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '8';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '9';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'C';
}
}
pin=7;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '*';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '0';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '#';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'D';
}
}
portb = oldBState;
enable_interrupts(INT_RB);
}
void printKey(void) {
if(key!='\0') {
lcd_gotoxy(1,1) ;
lcd_putc("\f");
printf(lcd_putc,"%c",key);
key = '\0';
}
if(i==5){
no=atoi(idNo);
lcd_gotoxy(1,1) ;
lcd_putc("\f");
printf(lcd_putc,"%i",no);
i=0;
}
}
#INT_RB
void RB_isr(VOID) {
if (oldBState != portb){
oldBState = portb;
keyPressed=true;
i++;
}
}
//===========================
void main(){
setup_adc_ports ( NO_ANALOGS ) ;
setup_adc ( ADC_OFF ) ;
setup_psp ( PSP_DISABLED ) ;
setup_spi ( FALSE ) ;
setup_timer_0 ( RTCC_INTERNAL | RTCC_OFF ) ;
setup_timer_1 ( T1_DISABLED ) ;
setup_timer_2 ( T2_DISABLED, 0, 1 ) ;
setup_timer_3 ( T3_DISABLED | T3_DIV_BY_1 ) ;
enable_interrupts ( INT_RB ) ;
enable_interrupts ( global ) ;
lcd_init ( ) ;
port_b_pullups(TRUE);
output_b(0xf0);
set_tris_b (0xf0); // B4 - 7 input B0 - 3 output
oldBState=portb;
lcd_gotoxy (1,1) ;
lcd_putc ( "Basliyor ..." ) ;
delay_ms ( 1000 ) ;
lcd_putc ( "\f" ) ;
WHILE ( TRUE ) {
if(keyPressed){
keyPressed=false;
getKey();
if(i<5 && (key!='\0')){
idNo[i]=key;
}
if(i==4){
idNo[i]=0x00;
}
}
printKey();
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Feb 09, 2011 10:08 am |
|
|
You need to think about the sequence of your program.
First, as written, printKey, is going to get called each time round the main loop, even if nothing has yet arrived.....
You need to build the string 'first', before calling this.
Then, you write the key to the array if is is less than 5, not less than '5'. Big difference. Since the key routine returns 'text' characters, how are these ever going to be <5?.
Then you also test for key!='\0', yet the keyboard routine never returns a '\0' character.
So, get your tests right, and then only call the printKey, once the entire number is assembled (normally you would test for a limit like the i==4 you currently use, and possibly for the '#' key as an 'EOL' as well - depends what you want).
Best Wishes |
|
|
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Wed Feb 09, 2011 11:23 am |
|
|
Ttelmah wrote: | You need to think about the sequence of your program.
First, as written, printKey, is going to get called each time round the main loop, even if nothing has yet arrived.....
You need to build the string 'first', before calling this.
Then, you write the key to the array if is is less than 5, not less than '5'. Big difference. Since the key routine returns 'text' characters, how are these ever going to be <5?.
Then you also test for key!='\0', yet the keyboard routine never returns a '\0' character.
So, get your tests right, and then only call the printKey, once the entire number is assembled (normally you would test for a limit like the i==4 you currently use, and possibly for the '#' key as an 'EOL' as well - depends what you want).
Best Wishes |
Thank you Ttelmah for your help. Actually you are right, when I looked at it again I noticed that printkey function and value 5 looks silly.
I will correct them and inform you about the result.
However there is also one thing I want to ask is this the right way to do this? Do you have better ways to get a char array from keypad? In my project the further step will be transmission of this char array to a receiver via rf. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 09, 2011 12:35 pm |
|
|
This post has code that calls the keypad driver every 10 ms and if
a key has been pressed, it puts the key into a circular buffer which
can be checked in your main code.
http://www.ccsinfo.com/forum/viewtopic.php?t=42707 |
|
|
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Thu Feb 10, 2011 1:26 am |
|
|
Thank you very much for the help PCM programmer.
I have corrected my code and I can put a 5 digit idNo on a lcd. However I have another problem, when I put the 5 digit idno on lcd, but I get an awkward character at the end. What can be the problem?
Code: |
#include <18F4550.h>
#include <stdlib.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#include <flex_lcd.c>
#byte portb = 0xf81
#use fast_io(b)
int1 keyPressed=false;
char key='\0';
char idNo[5];
static int oldBState;
int i=0;
int j;
void getKey(void){
int pin, bState, delay = 10;
delay_ms(50);
disable_interrupts(INT_RB);
pin=4;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '1';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '2';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '3';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'A';
}
}
pin=5;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '4';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '5';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '6';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'B';
}
}
pin=6;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '7';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '8';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '9';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'C';
}
}
pin=7;
if (!bit_test(oldBState,pin)){
portb = 0xf1;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '*';
}
portb = 0xf2;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '0';
}
portb = 0xf4;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = '#';
}
portb = 0xf8;
delay_us(delay);
bState = portb;
if (bit_test(bState,pin)) {
key = 'D';
}
}
portb = oldBState;
enable_interrupts(INT_RB);
}
void printKey(void) {
if(key!='\0') {
lcd_gotoxy(1,1) ;
lcd_putc("\f");
printf(lcd_putc,"%c",key);
key = '\0';
}
if(i==5){
i=0;
lcd_gotoxy(2,1) ;
lcd_putc("\f");
printf(lcd_putc,"\%s",idNo);
for(j=0;j<5;j++)
idNo[j]="";
}
}
#INT_RB
void RB_isr(VOID) {
if (oldBState != portb){
oldBState = portb;
keyPressed=true;
}
}
//===========================
void main(){
setup_adc_ports ( NO_ANALOGS ) ;
setup_adc ( ADC_OFF ) ;
setup_psp ( PSP_DISABLED ) ;
setup_spi ( FALSE ) ;
setup_timer_0 ( RTCC_INTERNAL | RTCC_OFF ) ;
setup_timer_1 ( T1_DISABLED ) ;
setup_timer_2 ( T2_DISABLED, 0, 1 ) ;
setup_timer_3 ( T3_DISABLED | T3_DIV_BY_1 ) ;
enable_interrupts ( INT_RB ) ;
enable_interrupts ( global ) ;
lcd_init ( ) ;
port_b_pullups(TRUE);
output_b(0xf0);
set_tris_b (0xf0); // B4 - 7 input B0 - 3 output
oldBState=portb;
lcd_gotoxy (1,1) ;
lcd_putc ( "Basliyor ..." ) ;
delay_ms ( 1000 ) ;
lcd_putc ( "\f" ) ;
WHILE ( TRUE ) {
if(keyPressed){
keyPressed=false;
getKey();
if((i<5) && (key!='\0')){
idNo[i]=key;
i++;
}
printKey();
}
}
}
|
|
|
|
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Thu Feb 10, 2011 2:53 am |
|
|
How can I discard the null character at the end of the string in order to write it on a an character lcd? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 10, 2011 3:03 pm |
|
|
You don't need to discard the null character at the end of a string.
You need the NULL character to mark the end of a string. String functions
such as atoi() need to see the NULL to find the end of the string. Also,
using printf with "%s" requires that a NULL character is at the end of the
string.
If your string has 5 numbers in it, such as "12345", then the array must
be large enough to hold the 5 numbers, and also the NULL. So the array
must be declared like this, with 6 elements:
If you are getting a garbage character displayed when using printf(), then
make sure you have a NULL at the end of the string. If you don't have it,
then printf() will continue displaying anything it sees in RAM memory
until it finds a NULL byte. Then it will stop. This could be the cause of
your problem. |
|
|
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Fri Feb 11, 2011 2:50 am |
|
|
Thank you very much pcm programmer, I did it as exactly as you said, I expand array size to 6 and to the last element of array I add null character '\0' it works very fine now. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|