Help With Screen Flicker [SOLVED]

Hi Guys
Please could you perhaps assist with a piece of code.
The basic idea is to have a countdown timer for my sons model rocket. He sets the time by mapping a pot and then "Arms" the system. After doing the checks he then presses a "Launch" button to initiate the countdown timer.
Once the timer reaches "0" it activates a relay and in turn fires the rocket.

I found the below code on the net and modified it with the help of a friend to use a i2c 16x2 LCD display.
I am in no way an expert but having fun learning.

I have 2 x minor issues now.

1st I need to add a decimal point to the countdown seconds (Currently displaying 000 seconds, I would like 00.0)
2nd, the LCD display is flickering. Even more so when the countdown initiates. ( I think this is due to bad coding)

Is anyone able to point me in the right direction and possibly recommend some improvements?

Code below -

#define FuseTIME      1500  //Fuse current duration in milliseconds.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);//change address according to your LCD
#define Fuss     7          //Pin connected to the Fuse relay.
int GoButt = 6;             //Pin Connected to the GO button.
int ArmButt = 5;            //Pin connected to the ARM button.
#define BuzzPin  4          //Connected to the Speaker.
#define SetPot   0          //Analog Pin connected to the Pot.


void setup() {


  lcd.begin();

  pinMode(Fuss, OUTPUT);
  pinMode(ArmButt, INPUT);        // set "ARM" button pin to input
  pinMode(GoButt, INPUT);         // set "GO" button pin to input
  digitalWrite(Fuss, LOW);        //OPEN the fuse circuit.
  digitalWrite(ArmButt, HIGH);    // turn on pullup resistor
  digitalWrite(GoButt, HIGH);     // turn on pullup resistor


  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("Rocket");
  lcd.setCursor(3, 1);
  lcd.print("Launcher");
  delay(2000);

}

int  DownCntr;                    // down counter (1/10 Secs.)
int  Go = 0;                      // Stopped



//================================================================

void loop() {

  if (!digitalRead(GoButt) || !digitalRead(ArmButt)) {

    Go = 0;                       //ABORT!!!
    tone(BuzzPin, 440, 1500);
    delay(1500);
  }
  if (Go == 0) {
    WaitARM();
    WaitGO();
  }
  ShowTimer();
  if (DownCntr > 50) {
    if (DownCntr % 10 == 0)tone(BuzzPin, 1000, 50); //Tone every second.
  }
  else if (DownCntr % 2 == 0)tone(BuzzPin, 1000, 50); //Tone every 1/5 second.
  if (DownCntr == 0) {

    //------------------ ROCKET LAUNCH! --------------------

    tone(BuzzPin, 440, FuseTIME);  //Launch audible signal

    digitalWrite(Fuss, HIGH);      //CLOSE the fuse circuit

    delay(FuseTIME);

    digitalWrite(Fuss, LOW);       //OPEN the fuse circuit.

    //------------------------------------------------------

    Go = 0;
  }
  while (millis() % 100);       //Wait until the next 1/10 of second.
  delay(50);
  DownCntr--;
}

//----------------------------------------

void WaitGO() {
  ShowTimer();
  while (digitalRead(GoButt));
  Go = 1;
  delay(20);
  while (!digitalRead(GoButt)); //Debounce GO button.
}

//------------------------------------------------------

void ReadTimer() {
  DownCntr = map(analogRead(SetPot), 0, 1023, 10, 60);     // DownCntr = map(analogRead(SetPot), 0, 1023, 5, 60);
  DownCntr *= 10;
}

//------------------------------------------------------

void ShowTimer() {
  String seconds = String (DownCntr, DEC);
  while (seconds.length() < 3)seconds = "0" + seconds; //format to 3 numbers.



  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Launching In");
  lcd.setCursor(1, 1);
  lcd.print(seconds);
  lcd.setCursor(5, 1);
  lcd.print("Seconds");

}

//------------------------------------------------------

void WaitARM() {
  while (digitalRead(ArmButt) == 1) {
    ReadTimer();
    delay(50);
    ReadTimer();
    ShowTimer();                   //Show Digits.
    delay(150);
  }

  Go = 0;
  ShowTimer();
  tone(BuzzPin, 2000, 150);
  delay(200);
  tone(BuzzPin, 2000, 150);
  delay(200);
  tone(BuzzPin, 2000, 150);
  delay(20);
  while (!digitalRead(ArmButt)); //Debounce ARM button.

}

Hi,
Welcome to the forum.
The LCD flicker is due to the lcd.clear(); command, there is a time between clearing and writing EVERYTHING back to the screen.

The trick is not to use lcd.clear();, but to simply write blank spaces over the old data you want to update, then write your new data in.
You will find you don't need to completely rewrite your screen as probably a fair part of it is unchanged.

Tom.... :slight_smile:

Hi Tom
Thanks so much for the reply and welcome. This is my firs real Arduino project and learning fast and enjoying it as well.
I didn't really think of that but it now makes sense that the code is clearing the screen in the loop function and causing the flicker.
Sometimes its the simplest of things... :slight_smile:
Do you perhaps know how i can add a decimal to the screen though? It currently displays 000 and i would like it to include a decimal to display 00.0

Hi,
Just off the top of my head try;

lcd.print(seconds,2);

If you put a ,2 after the value it should print the value with 2 decimal places.
If the value is an integer then the numbers after the decimal point will be 0.
If the value is a float then you will get numbers after the decimal point if they are in your variable.
,1 and ,2 and ,3 should work for different places, but I don't know how many you can ultimately got to.

Tom... :slight_smile:
PS I'm off to bed 12:20am here.

Hi Tom
Thanks for that, Unfortunately it did not work.
I got the below error when adding the

lcd.print(seconds,2);

Error -

Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"

C:\Users\wdean\Documents\Arduino\Rocket_Launcher_v1\Rocket_Launcher_I2C\Rocket_Launcher_I2C.ino: In function 'void ShowTimer()':

Rocket_Launcher_I2C:115:22: error: no matching function for call to 'LiquidCrystal_I2C::print(String&, int)'

   lcd.print(seconds,2);

                      ^

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:233,

                 from sketch\Rocket_Launcher_I2C.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:65:12: note: candidate: size_t Print::print(const __FlashStringHelper*)

     size_t print(const __FlashStringHelper *);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:65:12: note:   candidate expects 1 argument, 2 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:66:12: note: candidate: size_t Print::print(const String&)

     size_t print(const String &);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:66:12: note:   candidate expects 1 argument, 2 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:67:12: note: candidate: size_t Print::print(const char*)

     size_t print(const char[]);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:67:12: note:   candidate expects 1 argument, 2 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:68:12: note: candidate: size_t Print::print(char)

     size_t print(char);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:68:12: note:   candidate expects 1 argument, 2 provided

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:69:12: note: candidate: size_t Print::print(unsigned char, int)

     size_t print(unsigned char, int = DEC);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:69:12: note:   no known conversion for argument 1 from 'String' to 'unsigned char'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:70:12: note: candidate: size_t Print::print(int, int)

     size_t print(int, int = DEC);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:70:12: note:   no known conversion for argument 1 from 'String' to 'int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:71:12: note: candidate: size_t Print::print(unsigned int, int)

     size_t print(unsigned int, int = DEC);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:71:12: note:   no known conversion for argument 1 from 'String' to 'unsigned int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:72:12: note: candidate: size_t Print::print(long int, int)

     size_t print(long, int = DEC);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:72:12: note:   no known conversion for argument 1 from 'String' to 'long int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:73:12: note: candidate: size_t Print::print(long unsigned int, int)

     size_t print(unsigned long, int = DEC);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:73:12: note:   no known conversion for argument 1 from 'String' to 'long unsigned int'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:74:12: note: candidate: size_t Print::print(double, int)

     size_t print(double, int = 2);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:74:12: note:   no known conversion for argument 1 from 'String' to 'double'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:75:12: note: candidate: size_t Print::print(const Printable&)

     size_t print(const Printable&);

            ^~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:75:12: note:   candidate expects 1 argument, 2 provided

exit status 1

no matching function for call to 'LiquidCrystal_I2C::print(String&, int)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Im also off to bed. Been a long day here in Sunny South Africa.
Ill take another look at this in the morning.

Hi,
If you are printing a float value, the LCD should display to 2 decimal places automatically.
Try;

lcd.print((float)seconds);

I'm not sure but you may have seconds declared as an integer,
If that works, then try;

lcd.print((float)seconds,1);

That may give you 1 decimal place.

Tom.. :slight_smile:
Good morning...

Thanks to everyone with their input especially TomGeorge and Andrew George. The project has been completed and working perfectly.

I changed this piece of code form this

[color=#333333]//String seconds = String (DownCntr, DEC);[/color]
[color=#333333]//while (seconds.length() < 3)seconds = "0" + seconds; //format to 3 numbers[/color]

To This

[color=#333333]loat displayCount = (DownCntr / 10.0);         // This will treat the answer as an integer so 199/10 becomes 19.9 and displayCount will hold 19.9 [/color]
[color=#333333]String seconds = String(displayCount, 1);[/color]

The display now has a decimal point.