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.

[PIC] Replacing a character on an LCD

Status
Not open for further replies.

stip

Newbie level 5
Joined
Jun 8, 2015
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
79
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?
Thanks in advance!

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]);

}

char menu()
{
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
Lcd_Cmd(_LCD_BLINK_CURSOR_ON);// Blink the cursor

while(k<5)
{
while (string[k] == 0) // wait for any key to be pressed
{
string[k] = Keypad_Key_Click();
}
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++){
Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);//Advance the cursor
string[k]=0;
}
break;
}
}

}

void main(){

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

Keypad_Init();//initialize keypad
menu();//calls the menu function


}
 

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

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:
  • Like
Reactions: stip

    stip

    Points: 2
    Helpful Answer Positive Rating
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

  • keypad.rar
    66.8 KB · Views: 110

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.
 
  • Like
Reactions: stip

    stip

    Points: 2
    Helpful Answer Positive Rating
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.
 

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

  • keypad.rar
    53.4 KB · Views: 103

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!
 

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.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top