Sending LCD Message one time

Hi I am trying to incorporate an LCD Widget with my project. It is an Automatic Water Change System. It draines the water into a bucket using a solenoid valve and another bucket filled with new water to replace the water that was removed. Anyway I tried adding messages to tell me what is happening when I start the water change process. Example when I the Aquarium was drained I would go in the Blynk app and see the Message on the lcd. Now my problem is that the Water Change is written in a loop. So now the Message is sent but it flickers because the message is sent over and over again. What can I do to prevent this from happening?

Start by showing us your script. Please format it properly…

Void Water is the loop I was referring to. This code also includes Temperature reading and Led control. Ignore Those.

    #include <ArduinoOTA.h>

    #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #include <Wire.h>
    #include "Adafruit_MCP23008.h"
    #include <TimeLib.h>
    #include <WidgetRTC.h>

    WidgetTerminal terminal(V13);
    #include <OneWire.h>
    #include <DallasTemperature.h>
    OneWire oneWire (14); //esp
    DallasTemperature sensors(&oneWire);

    WidgetLCD lcd(V13);

    WidgetRTC rtc;

    Adafruit_MCP23008 mcp;

    #define white 12 //esp
    #define blue 13 //esp

    #define SUNRISE 9*60 + 0
    #define DAWN 10*60 + 0
    #define DUSK 16*60 + 0
    #define SUNSET 17*60 + 0

    #define drain_bucket_full 4 //mcp
    #define fill_bucket_empty 6 //mcp
    #define aquarium_empty 5 //mcp
    #define aquarium_full 1 //mcp

    #define Fill_Pump 2 //mcp
    #define solenoid 0 //mcp

    #define watersensor 3

    int sensor = 0;

    WidgetLED Pump(V2);
    WidgetLED Solenoid_valve(V7);
    WidgetLED Done(V8);
    WidgetLED Auto(V9);
    WidgetLED error(V10);

    WidgetLED blueled(V12);
    WidgetLED whiteled(V11);

    BlynkTimer timer;

    unsigned long previousMillis = 0;


    boolean fill;
    boolean drain;
    boolean emergencystop = 0;
    boolean automatic = 0;
    boolean refilling = 0;
    boolean draining = 0;
    boolean filling = 0;
    boolean start = 0;
    boolean filled;

    int state;

    char auth[] = "501xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx071a2";
    char ssid[] = "Clzxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
    char pass[] = "clxxxxxxxxxxxxxxxx3";



    BLYNK_WRITE(V0) // At global scope (not inside of the function)

    {
      if ( param.asInt() == 1 )
      {
        fill = 1;
      }
      else
      {
        fill = 0;
        filled = 0;
      }

    }

    BLYNK_WRITE(V1) // At global scope (not inside of the function)

    {
      if ( param.asInt() == 1 )
      {

        drain = 1;
      }
      else
      {
        drain = 0;
      }

    }




    BLYNK_WRITE(V5) // At global scope (not inside of the function)

    {
      if ( param.asInt() == 1 )
      {
        automatic = 1;
        Auto.on();
        state = 0;

      }
      else
      {
        automatic = 0;
        Auto.off();
        Done.off();
        lcd.clear(); //Use it to clear the LCD Widget

      }

    }

    BLYNK_WRITE(V6) // At global scope (not inside of the function)

    {
      if ( param.asInt() == 1 )
      {
        emergencystop = 1;

      }
      else
      {
        emergencystop = 0;

      }

    }


    BLYNK_WRITE(V3) // At global scope (not inside of the function)

    {
      if ( param.asInt() == 1 )
      {
        int D7 = mcp.digitalRead(drain_bucket_full);
        int D6 = mcp.digitalRead(aquarium_empty);
        int D5 = mcp.digitalRead(fill_bucket_empty);
        int D8 = mcp.digitalRead(aquarium_full);
        sensor = mcp.digitalRead(watersensor);
        BLYNK_LOG("");
        BLYNK_LOG("drain bucket full (%d) = %d, aquarium_empty (%d) = %d, fill_bucket_empty (%d) = %d , aquarium_full (%d) = %d , watersensor = %d ", drain_bucket_full, D7, aquarium_empty, D6, fill_bucket_empty, D5, aquarium_full, D8, sensor);
        BLYNK_LOG("fill = %d , drain = %d, emergency Stop = %d, Automatic = %d, Refilling = %d, Draning = %d, start = %d", fill, drain, emergencystop, automatic, refilling, draining, start);
        BLYNK_LOG("");
        /*terminal.flush();
            terminal.println("drain bucket full () = " drain_bucket_full);
            ///terminal.println("fill = %d , drain = %d, emergency Stop = %d, Automatic = %d, Refilling = %d, Draning = %d, start = %d", fill, drain, emergencystop, automatic, refilling, draining, start);
        */
      }


    }
    void water() {
      if (mcp.digitalRead(watersensor) == 1) {
        sensor = 0;
      }
      else
      {
        sensor = 1;
      }


      //Aquarium Filling
      //---------------------------------------------------------------------------------------------------------------------

      if (filled == 0 && sensor == 0 && automatic == 0 && fill == 1 && mcp.digitalRead(fill_bucket_empty) == HIGH && mcp.digitalRead(aquarium_full) == LOW)
      {
        mcp.digitalWrite(Fill_Pump, HIGH);
        Pump.on();
        //Done.off();
        filling = 1;

      }
      else if (automatic == 0 && fill == 0 || mcp.digitalRead(fill_bucket_empty) == LOW || mcp.digitalRead(aquarium_full) == HIGH)
      {
        mcp.digitalWrite(Fill_Pump, LOW);
        Pump.off();
        filling = 0;

      }
      /*
        if (fill == 1 && mcp.digitalRead(aquarium_full) == HIGH) {
          filled = 1;
        }*/
      //---------------------------------------------------------------------------------------------------------------------

      //Aquarium Draining
      //--------------------------------------------------------------------------------------------------------------------
      if (sensor == 0 && automatic == 0 && drain == 1 && mcp.digitalRead(drain_bucket_full) == LOW && mcp.digitalRead(aquarium_empty) == HIGH) {
        mcp.digitalWrite(solenoid, HIGH);
        Solenoid_valve.on();
        //Done.off();
        draining = 1;
      }
      else if (automatic == 0 && drain == 0 || mcp.digitalRead(drain_bucket_full) == HIGH || mcp.digitalRead(aquarium_empty) == LOW) {
        mcp.digitalWrite(solenoid, LOW);
        Solenoid_valve.off();
        draining = 0;
      }

      //------------------------------------------------------------------------------------------------------------------------
      //---------------------------------------------------------AUTOMATIC------------------------------------------------------

      if (state == 0 && fill == 0 && drain == 0 && automatic == 1 && sensor == 0) {


        if (mcp.digitalRead(drain_bucket_full) == LOW && mcp.digitalRead(aquarium_empty) == HIGH) {
          mcp.digitalWrite(solenoid, HIGH);
     lcd.clear(); //Use it to clear the LCD Widget
          lcd.print(0, 0, "Automatic Mode" ); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
          lcd.print(0, 1, "Draining Water");
          Solenoid_valve.on();
          state = 1;

        }

        if (state == 1 && mcp.digitalRead(aquarium_empty) == LOW) {
          lcd.clear(); //Use it to clear the LCD Widget
          lcd.print(0, 0, "Water Drained" ); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
          lcd.print(0, 1, "Proceeding to fill again");
          state = 2;

        }

        if (state = 2 && mcp.digitalRead(fill_bucket_empty) == HIGH && mcp.digitalRead(aquarium_empty) == LOW && mcp.digitalRead(aquarium_full) == LOW)
        {
          lcd.clear(); //Use it to clear the LCD Widget
          lcd.print(0, 0, "Filling with Water" ); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")

          mcp.digitalWrite(Fill_Pump, HIGH);
          start = 1;
          Pump.on();


          if (state == 2 && mcp.digitalRead(aquarium_empty) == HIGH && mcp.digitalRead(aquarium_full) == HIGH) {
            state = 3;
            Done.on();
            lcd.clear(); //Use it to clear the LCD Widget
            lcd.print(0, 0, "WaterChangeDone"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")

          }
        }
      }


      if (state == 1 && mcp.digitalRead(drain_bucket_full) == HIGH || mcp.digitalRead(aquarium_empty) == LOW) {
        mcp.digitalWrite(solenoid, LOW);
        Solenoid_valve.off();

      }

      if (state == 1 && mcp.digitalRead(drain_bucket_full) == HIGH) {
        lcd.clear(); //Use it to clear the LCD Widget
        lcd.print(0, 0, "DraningBucketisFull"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
        //lcd.print(0, 1, "Waiting for the bucket to be empty");
      }
      if (state == 2 && (mcp.digitalRead(fill_bucket_empty) == LOW ||  mcp.digitalRead(aquarium_full) == HIGH))
      {
        mcp.digitalWrite(Fill_Pump, LOW);
        Pump.off();
      }
      if (state == 2 && mcp.digitalRead(fill_bucket_empty) == LOW) {
        lcd.clear(); //Use it to clear the LCD Widget
        lcd.print(0, 0, "FillingBucketisEmpty"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
        //lcd.print(0, 1, "Waiting for the bucket to be ");
      }

      if (automatic == 0 && fill == 0 && drain == 0) {
        mcp.digitalWrite(Fill_Pump, LOW);
        Pump.off();
        mcp.digitalWrite(solenoid, LOW);
        Solenoid_valve.off();
      }


      /*
        if (automatic == 1 && mcp.digitalRead(aquarium_full) == HIGH && mcp.digitalRead(solenoid) == LOW && mcp.digitalRead(Fill_Pump) == LOW )
        {

          Done.on();
        }
        else {
          Done.off();
        }
      */
      //-----------------------------------------------------------------------------------------------------------------------------------------------
   
      if (sensor == 1)
      {
        lcd.clear(); //Use it to clear the LCD Widget
        lcd.print(0, 0, "Water was detected and process was Stopped"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
        error.on();
        automatic = 0;
        fill = 0;
        drain = 0;

      }
      else
      {
        error.off();
      }

      if (emergencystop == 1)
      {
        automatic = 0;
        fill = 0;
        drain = 0;
        Pump.off();
        Solenoid_valve.off();
        Auto.off();
        Done.off();


      }

    }

    void temp() {
      sensors.requestTemperatures();
      float currentTemp;
      currentTemp = sensors.getTempCByIndex(0);
      Blynk.virtualWrite(V4, currentTemp); // Virtual 0

      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= 14400000 ) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        if (currentTemp > 30)
        {
          Blynk.notify("Temperature Exceeded 30°C");
        }
        else if (currentTemp < 26)
        {
          Blynk.notify("Temerature is Below 26°C");
        }
      }
    }

    void turn_on() {
      int value = 0;
      int msm = hour() * 60 + minute(); //minutes since midnight

      if ( msm < SUNRISE ) {
        value = 0;
      } else if (msm < DAWN) {
        value = map(msm, SUNRISE, DAWN, 0, 1024);
      } else if (msm < DUSK ) {
        value = 1024;
      } else if (msm < SUNSET ) {
        value = map(msm, DUSK, SUNSET, 1024, 0);
      } else {
        value = 0;
      }

      int brightness = map(value, 0, 1024, 0, 255);

      whiteled.setValue(brightness);
      blueled.setValue(brightness);


      BLYNK_LOG("Time: %d %d - setting lights to %d", hour(), minute(), value);

      analogWrite(blue, value);
      analogWrite(white, value);

    }


    void setup() {
      WiFi.mode(WIFI_STA);



      Serial.begin(9600);
      mcp.begin();      // use default address 0


      Blynk.begin(auth, ssid, pass);


      while (Blynk.connect() == false) {}

      ArduinoOTA.setHostname("Aquarium"); // OPTIONAL
      ArduinoOTA.begin();

      pinMode(white, OUTPUT);
      pinMode(blue, OUTPUT);


      mcp.pinMode(drain_bucket_full, INPUT);
      mcp.pinMode(fill_bucket_empty, INPUT);
      mcp.pinMode(aquarium_empty, INPUT);
      mcp.pinMode(watersensor, INPUT);
      mcp.pinMode(aquarium_full, INPUT);

      mcp.pullUp(drain_bucket_full, HIGH);  // turn on a 100K pullup internally
      mcp.pullUp(fill_bucket_empty, HIGH);
      mcp.pullUp(aquarium_empty, HIGH);
      mcp.pullUp(aquarium_full, HIGH);



      mcp.pinMode(Fill_Pump, OUTPUT);
      mcp.pinMode(solenoid, OUTPUT);

      mcp.digitalWrite(Fill_Pump, LOW);
      mcp.digitalWrite(solenoid, LOW);


      // Begin synchronizing time
      rtc.begin();


      fill = 0;
      drain = 0;

      timer.setInterval(10000L, turn_on);
      //  timer.setInterval(1000L, clockDisplay);
      timer.setInterval(10000L, temp);
      timer.setInterval(1000L, water);

    }

    void loop() {
      Blynk.run();
      ArduinoOTA.handle();
      timer.run();
    }

Hmm, a bit bigger script than I anticipated… lots of logic to go through, but I think I see a “flicker free” solution:

Limit your lcd.clear(); commands only to places where you actually need a clear screen. Then, when overwriting a longer message with a shorter one, just add spaces to overwrite past characters.

This will not limit the amount of lcd writes (that would probably require more counters, flags and if-then logic), but it will prevent the flicker.

PS, I still had to edit your post to add in the required backticks for proper code viewing. Now I am done for the night :sleeping: