LCD flashing rapidly

Hey guys.

I am making my first project with an LCD display.
I created a scroll menu that shows different screens every time you press the scroll up or down button. However, sinse the program runs over and over all the time, the arduino refreshes the state the LCD should be in all the time. I believe this is what is causing the flashing. What I want to know: is there a way to ckeck the state it should be in only when I press the button, and not over and over all the time?

Here is my code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int but1 = 9;
const int but2 = 8;
int prevState1 = 0;
int prevState2 = 0;
int val = 0;

void setup() {
lcd.begin(16, 2);
pinMode(but1, INPUT);
pinMode(but2, INPUT);
lcd.write("System ready");
delay(2000);
lcd.clear();

}

void loop() {
int state1 = digitalRead(but1);
int state2 = digitalRead(but2);


 if(state1 != prevState1){
  if(state1 == LOW){
  val++;
 }
 prevState1 = state1;
 }
 else if(state2 != prevState2){
 if(state2 == LOW){
val--;
}
prevState2 = state2;
}

if(val > 3){

  val = 0;
}

else if(val < 0){

val = 3;
}
else{
  
}

lcd.clear();

switch(val){
case 0 :
lcd.write("Feed every");
lcd.setCursor(0, 1);
lcd.write("12");
lcd.setCursor(3, 1);
lcd.write("hours");
break;

case 1:
lcd.write("Water temp:");
lcd.setCursor(0, 1);
lcd.write("33");
lcd.setCursor(2, 1);
lcd.write("/");
lcd.setCursor(3, 1);
lcd.write("34");
lcd.setCursor(6, 1);
lcd.write("°C");
break;

case 2:
lcd.write("Feed manually");
break;

case 3:
lcd.write("Light:");
lcd.setCursor(0, 1);
lcd.write("ON");
break;
}
}

As you can see the value is increased and decreased according to the buttons you press, and if you reach the end of the menu, it will start from the other side(creating an infinite loop of scrolling through the menu) I use a switch...case to show the menu corresponding to the menu value. But now it reads that value over and over again causing it to flash, instead of just checking it when I want to change menu screens...

Some help would be greatly appreciated
Thanks in advance
Sean

Fish_feeder.ino (1.14 KB)

Do the same thing that you do with the switch states. If val has not changed from oldVal skip the switch block.

When I see the term 'flickering' or 'flashing' associated with 'LCD' in the title of a post I immediately look for an lcd.clear() statement in loop(). Guess what ... I found one here.

It is typically possible to achieve the desired result without the use of lcd.clear() since any new data will overwrite the old. You may have to do some selective erasing by writing 'spaces' but it is seldom necessary to erase the entire screen.

ALSO - go back and edit your original post to put your code in a 'code box'. The forum instructions (you did read them didn't you) have instructions on how to do this.

Don

Thanks so much guys you are such geniusses! And no I didn't read the instructions :slight_smile: I'll be sure to look into that.

I appreciate your help a lot!

void setup() {

}

void loop() {
 
}

//I figured out how to use the code box! I think....
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int but1 = 9;
const int but2 = 8;
int prevState1 = 0;
int prevState2 = 0;
int val = 0;
int prevVal = 0;


void setup() {
lcd.begin(16, 2);
pinMode(but1, INPUT);
pinMode(but2, INPUT);
lcd.write("System ready");
delay(2000);

}

void loop() {
int state1 = digitalRead(but1);
int state2 = digitalRead(but2);


 if(state1 != prevState1){
  if(state1 == LOW){
  val++;
 }
 prevState1 = state1;
 }
 else if(state2 != prevState2){
 if(state2 == LOW){
val--;
}
prevState2 = state2;
}

if(val > 3){

  val = 0;
}

else if(val < 0){

val = 3;
}
else{
  
}

if(val != prevVal){

lcd.clear();

switch(val){
case 0 :
lcd.write("Feed every");
lcd.setCursor(0, 1);
lcd.write("12");
lcd.setCursor(3, 1);
lcd.write("hours");
break;

case 1:
lcd.write("Water temp:");
lcd.setCursor(0, 1);
lcd.write("33");
lcd.setCursor(2, 1);
lcd.write("/");
lcd.setCursor(3, 1);
lcd.write("34");
lcd.setCursor(5, 1);
lcd.write("°C");
break;

case 2:
lcd.write("Feed manually");
break;

case 3:
lcd.write("Light:");
lcd.setCursor(0, 1);
lcd.write("ON");
break;
}
prevVal = val;
}
}

So now I changed it so it checks to see if the val is different than before, before clearing and re-writing the LCD. It works great! the only problem is that now it displays an infinity sign before the degrees C. Any advice?

Here is a picture:

TheQubit:
Here is a picture:

LCD infinity error.jpg
OK, here is your picture.

The "°" sign you used is the degree sign for your computer, not the one for your LCD. On the computer, it is two bytes. For your LCD I think it needs to be char(0x83) so you need to use

lcd.setCursor(5, 1);
lcd.write(char(0x83),"C");

But you really do not need to set the cursor for every piece of the text.

Oh, and please go back to your first post above and mark up the code properly. :grinning:

Thanks I'll try it! Also I've put my code in a box now

Paul__B:
For your LCD I think it needs to be char(0x83) so you need to use

For the hd44780 displays I've worked with, the degree symbol is 0xDF not 0x83.
0xDF in octal is 337

To print the "degree" symbol, you can simply embed the character code in the string with the 'C' character.

lcd.print("\337C"); // print degree symbol and the character 'C'

--- bill

bperrybap:
For the hd44780 displays I've worked with, the degree symbol is 0xDF not 0x83.

Ah yes, the Kanji page - I was thinking of the Euro page - which is actually nicer! :roll_eyes:

Bummer, since there is no way to know what font ROM the LCD device has.
To avoid any issues from potentially different front ROMs, a custom character could be defined.
It could even have the degree symbol and the units character in the same single custom character.
i.e.

uint8_t degreeC[8]     = {0x18,0x18,0x03,0x04,0x04,0x04,0x03,0x00};
uint8_t degreeF[8]     = {0x18,0x18,0x07,0x04,0x07,0x04,0x04,0x00};

These are from the LCDCustomChars example that comes with the hd44780 library.

--- bill