# [PIC]Replacing a character on an LCD

Status
Not open for further replies.

#### stip

##### Newbie level 5
Hi everybody!
I am using PIC18F2550 Mikroc as compiler. My project has a matricial keypad (https://www.arduiner.com/en/tastier...switch-keypad-keyboard-for-arduinoavrpic.html) to get a five digits number that will be a reference to a motor's speed in RPM. At the same time every digit is displayed on an LCD. I want to be able to use one of the key to return( when key '*' is pressed) or advance(when key '#' is pressed) for any digit and replace it in case the user want it. I am trying to use the code below. I have made a function called "print" to print each character. My idea to replace any character was to decrement or increment an integer called "k" so I could know the position of the cursor on the LCD. Then I just printed the new character in the "k" position, but it is not working properly. I can get any digit and print it, but when I press the key "#" or '*' it is not working. Could someone help me with any tips to do it?

Code:
char keypadPort at PORTB;

sbit LCD_RS at RC6_bit;
sbit LCD_EN at RA0_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISC6_bit;
sbit LCD_EN_Direction at TRISA0_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC7_bit;

int i, k=0;
char string[5];

void print(){

Lcd_Chr(2, k+1 , string[k]);

}

{
Lcd_Init(); // Initialize the LCD
Lcd_Cmd(_LCD_CLEAR);// Clear the LCD
Lcd_Out(1, 1, "RPM"); // Write on LCD
Lcd_Cmd(_LCD_SECOND_ROW);//Move the cursor to the second row

while(k<5)
{
while (string[k] == 0) // wait for any key to be pressed
{
}
switch(string[k]){

case 1:
string[k]= '1';
print();
k++;
break;

case 2:
string[k]='2';
print();
k++;
break;

case 3:
string[k]='3';
print();
k++;
break;

case 5:
string[k]='4';
print();
k++;
break;

case 6:
string[k]= '5';
print();
k++;
break;

case 7:
string[k]= '6';
print();
k++;
break;

case 9:
string[k]= '7';
print();
k++;
break;

case 10:
string[k]='8';
print();
k++;
break;

case 11:
string[k]='9';
print();
k++;
break;

case 13: // key '*' was pressed
for(i=0;i<1;i++){
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);// return the cursor
string[k]=0;
}
break;

case 14:
string[k]='0';
print();
k++;
break;

case 15: //key '#' was pressed
for(i=0;i<1;i++){
string[k]=0;
}
break;
}
}

}

void main(){

ADCON0 = 0; // ADCON0 and ADCON1 registers to enable digital I/O in PORTA (where is an LCD pin)
CMCON |= 7;// disable comparators

}

#### milan.rajik

##### Banned
Zip and post the complete mikroC PRO PIC project files. It will help others in helping you.

#### xenos

##### Full Member level 4
Try something like this:
Code:
case 13: // key '*' was pressed
if(k){
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
k--;
string[k]=0;
}
break;

case 15: //key '#' was pressed
if(k<5){
Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
k++;
string[k]=0;
}//else, should we terminate user input?
break;

You may want to add an extra position in string[] array for the final NUL terminating, althow there is no reference/problem in the code that you post.
You should also improve the user movement. Let user use #/* but do not delete the indexed character so user could just skip it.

Last edited:
stip

### stip

Points: 2

#### stip

##### Newbie level 5
Zip and post the complete mikroC PRO PIC project files. It will help others in helping you.

Ok, zip file attached.

- - - Updated - - -

Try something like this:
Code:
case 13: // key '*' was pressed
if(k){
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
k--;
string[k]=0;
}
break;

case 15: //key '#' was pressed
if(k<5){
Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
k++;
string[k]=0;
}//else, should we terminate user input?
break;

You may want to add an extra position in string[] array for the final NUL terminating, althow there is no reference/problem in the code that you post.
You should also improve the user movement. Let user use #/* but do not delete the indexed character so user could just skip it.

Thanks a lot for the help. This is working now. The only problem I have to fix now is when the user is using the '#' key without finish the 5 digits, because it keeps incrementing my "k" count in the while loop. Because that my keypad stop to work without getting the 5 digits. Do you have any suggestion for this case?

Best regards.

#### Attachments

66.8 KB · Views: 71

#### xenos

##### Full Member level 4
The zip that you uploaded, contains the old code.
In your code, the key '#' increments and then zeroes position. This is a serious problem and may overwrite ram contents with unexpected behavior!!!

Why do you write this?
Code:
for(i=0;i<1;i++)
it has no meaning, waste it.

stip

### stip

Points: 2

#### stip

##### Newbie level 5
The zip that you uploaded, contains the old code.
In your code, the key '#' increments and then zeroes position. This is a serious problem and may overwrite ram contents with unexpected behavior!!!

Why do you write this?
Code:
for(i=0;i<1;i++)
it has no meaning, waste it.
Xenos, thanks for reply. I get it. You are right. I will put your code and see if it works, ok? About the
Code:
for(i=0;i<1;i++)
I am using that because when I was simulating on Proteus when I pressed the'*' or '#' the cursor started to move without stopping. I'm not sure if it was a problem with my simulator, so when I put this code it worked fine.

#### milan.rajik

##### Banned
I want to be able to use one of the key to return( when key '*' is pressed) or advance(when key '#' is pressed) for any digit and replace it in case the user want it.

What happens when '*' is pressed ? The numbers entered is discarded and it comes out of the keyread process ? What happens if '#' key is pressed after entering a 5 digit number ? The entered number is regsitered and RPM is set ? Are numbers entered always 5 digits or can it be 1 , 2, or 3 digits also ?

Which key you want to use a backspace key to erase the entered digit if it was incorrect ?

- - - Updated - - -

Try attached project.

#### Attachments

53.4 KB · Views: 61

#### stip

##### Newbie level 5
What happens when '*' is pressed ? The numbers entered is discarded and it comes out of the keyread process ? What happens if '#' key is pressed after entering a 5 digit number ? The entered number is regsitered and RPM is set ? Are numbers entered always 5 digits or can it be 1 , 2, or 3 digits also ?

Which key you want to use a backspace key to erase the entered digit if it was incorrect ?

- - - Updated - - -

Try attached project.

I use the '*' key to return the cursor to the last position to replace a wrong digit. I mean, if a digit is incorrect I don't erase it , I just put another digit on his place when another key number is pressed (because the Keypad_Key_Click() keeps running). When the '#' is pressed after entering 5 digits the Keypad_Key_Click() function stops to run and the LCD will show a message, something like this: "press the 'A' key to confirm or the 'B' for correction ( If 'B' is pressed the cursor will blink and the keyread starts again and I will be able to replace the wrong digit). When the 'A' is pressed the number will be registered and I will convert to a integer using the atoi function to set the RPM using a controller that I intend to project. The number will be 5 digits, but if the user wants to run the motor at 500 RPM he has to set 00500 ( I think this way is easier to build my code).
Anyway, if you have any suggest, lemme know, please.

Thanks again!

#### milan.rajik

##### Banned
Try the project I attached. See if it is ok for you else I will modify the code according to your needs.

Status
Not open for further replies.