First Project - LCD Flickering

Hello,

I'm still working on my first project. I got the menu system working and I can communicate with the user through the 2x 16 LCD. I'm using a "Super Start Kit" Uno 3 Project from Elegoo.

Everything seems to be functioning as I want (except the LCD), I use Serial.print for development feedback. This is my first time I learn any coding so this seemed helpfull. Surely my code looks like a mess and there are better ways, feel free to give feedback on that. But, the issue is that the screen is really flickering.

When I use a refresh rate of 1 till 2000, it's Always acting funny when I look from certain angles.
I feel like this is some sort of power issue or such, should the LCD be powered separately?

If you would load the code, I did a / / on the 'startup' part. Felt pretty useless while creating.

Thanks for any feedback!

//Load and use pre-defined LCD system
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
//create integers used
int Status = 1;
int Refresh = 1;
int RandomNr;
int Position;
int Move;
int RedLed = 12;
int GreenLed = 11;
int Button1 = 2;
int Button2 = 3;
int ZeroSetting = 0;
int LCDLight = 6;
int MaxSetting = 0;
int RandomMode = 0;
int MinRandom = 1000;
int MaxRandom = 4000;
int BState1 = 0;
int BState2 = 0;
int MenuPos = 0;
int ScreenMls;
int ScreenRefresh = 0;
const int ScreenRefreshInterval = 70;
unsigned long PreviousMls = 0;
const long Interval = 2000;
const long IntervalButton = 600;
String vers = "    Version 0.1";


void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  Serial.begin(9600);
  // Declare pinmode's
  pinMode(Button1, INPUT_PULLUP);
  pinMode(Button2, INPUT_PULLUP);
  pinMode(RedLed, OUTPUT);
  pinMode(GreenLed, OUTPUT);
  pinMode(LCDLight, OUTPUT);
  analogWrite(LCDLight, 140); // brightness setting for LCD, 0-255 (0-5v)
  // Welcome user on the LCD
  /*
  lcd.print(" #ScaleSimTool#");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(" *ScaleSimTool*");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(" /ScaleSimTool/");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(" #ScaleSimTool#");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(" *ScaleSimTool*");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(" /ScaleSimTool/");
  lcd.setCursor(0, 1);
  lcd.print(vers);
  delay(500);
  lcd.clear();
  lcd.print(".");
  delay(500);
  lcd.clear();
  lcd.print("...");
  delay(500);
  lcd.clear();
  lcd.print("......");
  delay(500);
  lcd.clear();
  lcd.print("Starting Up!");
  delay(1500);
  lcd.clear();
  */
  lcd.print("Hello World :)");
  }

void loop() 
    {
  unsigned long ScreenCurrentMls = millis();
  unsigned long CurrentMls = millis();
  unsigned long CurrentRandomMls = millis();
  // Refresh Screen rate to prevent flickering
    if (ScreenCurrentMls - ScreenMls >= ScreenRefreshInterval)
    { 
    if (ScreenRefresh == 0) 
    {
    ScreenRefresh = 1;
    ScreenMls = ScreenCurrentMls;
    Serial.println("Refresh 1");
    } 
    else 
    {
    ScreenRefresh = 0;
    Serial.println("Refresh 0");
    }
    }
 
  if (MenuPos == 6) { //checking requirements if it's ok to do random weighings 
    if (CurrentRandomMls - PreviousMls >= Interval) { //using an if statement to bypass the delay
    // If Status & Random is on, but zero/max is off
    Serial.println("Generating random values as test"); //using the serial tool as debug
    RandomNr = random(MinRandom - MaxRandom); // Update the integer with a random number, Min&Max can be user defined
    PreviousMls = CurrentRandomMls; //update Previous Milisecond integer to be used in the timer tool
    Serial.println(RandomNr); 
    }
    
  }
  // ################################################################################################
  // Button 1 & 2 -> Endless loop setting BState1 high/low during the 'IntervalButton' period
  // LCD&Serial print feedback enabled for debugging / development
  
  if (Status == 1) {
    
        if ((digitalRead(Button1) == LOW) && (BState1 == 0))  // Check if the button is pushed & if it's state is clear
          {    
            BState1 = 1; //set button 'high' so this if is locked
            PreviousMls = CurrentMls; //update timer int
            Serial.println("Button 1 pressed"); //serial print for feedback
              if (MenuPos < 6) { 
              MenuPos = MenuPos +1;
              Serial.println(MenuPos);
              }
           }
         if ((CurrentMls - PreviousMls >= IntervalButton) && (BState1 == 1)) // timer loop to prevent double pushing
           { 
             BState1 = 0; //unlock again after 'IntervalButton' timer has passed
             Serial.println("Button 1 state release");
           }             
        if ((digitalRead(Button2) == LOW) && (BState2 == 0)) 
          {
            BState2 = 1;
            PreviousMls = CurrentMls;
            Serial.println("Button 2 pressed");
            if ((MenuPos <= 6) && (MenuPos > 0)) 
            { 
              MenuPos = MenuPos -1;
              Serial.println(MenuPos);
            }
              else {
                MenuPos = 0;
                Serial.println(MenuPos);
              }
            }
            
           }
         if ((CurrentMls - PreviousMls >= IntervalButton) && (BState2 == 1))
           { 
            BState2 = 0;
            Serial.println("Button 2 state release");
        }
 
//########################################################### End of button loop
//####Menu buildup

if (Status == 1)
  {
    if (( MenuPos == 1) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.print("Use Up and Down");
    lcd.setCursor(0, 1);
    lcd.print("To navigate");

  }
    if (( MenuPos == 2) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.print("1= Set Zero");
    lcd.setCursor(0, 1);
    lcd.print("2= Set Max");
  }
    if (( MenuPos == 3) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.print("3= Random Weight");
    lcd.setCursor(0, 1);
    lcd.print("Next Scrn is 1");
  }
      if (( MenuPos == 4) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.print("1 Setting Zero");
    lcd.setCursor(0, 1);
    lcd.print(" Calibrate Scale");
  }
        if (( MenuPos == 5) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("2 Setting Max");
    lcd.setCursor(0, 1);
    lcd.print(" Calibrate Scale");
  }
          if (( MenuPos == 6) && (ScreenRefresh == 1))
  {
    lcd.clear();
    lcd.print("3 Random Weights");
    lcd.setCursor(0, 1);
    lcd.print(" Testing Scale");
  }
 }
} //end void

You use lcd.clear() a lot. That will cause flickering. Instead of using clear. use setCursor to move the cursor to the line that you want to write to and overwrite tho old data. Pad with spaces if necessary.

Like this:

lcd.print(" #ScaleSimTool#");
lcd.setCursor(0, 1);
lcd.print(vers);
delay(500);
lcd.setCursor(0, 0);  // move back to line 0
lcd.print(" *ScaleSimTool* "); // overwrite old data
                               // pad with space(s) to make sure 
                              // old data overwritten
lcd.setCursor(0, 1);
lcd.print(vers);
lcd.print("     ");  // print some spaces to make sure 
                     // old data overwritten
delay(500);

Thank you, I replaced the lcd.clear(); in the 'Menu State' loop by lcd.print(" "); and I already see results.
Guess I now have to do some basic math to calculate the spaces cause it seems way of already.