refresh lcd

hey all,
when i upload my code, the displayed time is incorrect on the display, but the real time is correct. also the calc made based on the time =correct.
but the displayed time not.
it does count til 59 sec but then:
0:0:59
0:1:09
0:1:19
0:1:29
i haven't done a lcd.clear becouse then it the screen is bad without delay.(with delay the timing is off)
how can i fix?

int start_pin = 12;
unsigned long currentMillis;
unsigned long previousMillis;
int h = 0;
int m = 0;
int s = 0;
int ms = 0;
int start = 0;
double verbruik;
double tank;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
/////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {

  //// input van de timer
  start = digitalRead (start_pin); //reading buton state
  if (start == LOW)
  {
    currentMillis = millis();
    if ( (currentMillis - previousMillis) >= 1000) {
      previousMillis = previousMillis + 1000;
      s = s + 1;
      if (s == 60) {
        s = 0;
        m = m + 1;
        if (m == 60) {
          m = 0;
          h = h + 1;
        } // end hrs check
      } // end minutes check
    } // end seconds check


    lcd.setCursor(0, 0);  //setting start point on lcd
    lcd.print("TIME:");   //writting TIME
    lcd.print(h);         //writing hours
    lcd.print(":");
    lcd.print(m);         //writing minutes
    lcd.print(":");
    lcd.print(s);         //writing seconds
    //uur omzetten naar verbruikte liters
    verbruik = h * 2.2 + m * 0.0367;
    tank = 3150 - verbruik;
    lcd.setCursor(0, 2);
    lcd.print(verbruik);
    lcd.print("L");
    lcd.setCursor(8, 2);
    lcd.print(tank);
    lcd.print("L");

  }
  else;

  lcd.setCursor(0, 0);  //setting start point on lcd
  lcd.print("TIME:");   //writting TIME
  lcd.print(h);         //writing hours
  lcd.print(":");
  lcd.print(m);         //writing minutes
  lcd.print(":");
  lcd.print(s);         //writing seconds
  //uur omzetten naar verbruikte liters
  verbruik = h * 2.2 + m * 0.0367;
  tank = 3150 - verbruik;
  lcd.setCursor(0, 2);
  lcd.print(verbruik);
  lcd.print("L") ;
  lcd.setCursor(8, 2);
  lcd.print(tank);
  lcd.print("L");

}

hey all,
i solved (i think)
i have ad lcd.clear but not at the end.
is my solution correct? (no influence on the millis timer)
i inserted it at:

s = 0;
m = m + 1;
if (m == 60) {
lcd.clear(); // here refresh lcd (once every 60 sec)
m = 0;

it does count til 59 sec but then:
0:0:59
0:1:09

What is happening us that the trailing 9 from 59 is not being written over when you print 0 after rollover. Whilst clearing the LCD will solve this it is a sledgehammer solution and will cause the LCD to blink. Instead, either always print a space after the time or print a space after the time when the value being printed is less than 10

I stumbeld on a other problem.
After a period of time my counter:
H:m:s
Acts like m:s:ms
It goes verry rapidly....
If i reset it goes normal....
Can somebody help?
Is the variable wrong?
Int h
Int m
Int s
?

I don't see anything in the code that would make it run wild. Do you know what "period of time" before it goes wild?

What is the 'start_pin' supposed to do? What is there no pinMode() call for it?

You don't use the 'ms' variable.

You have an "else;" that does nothing after your 'if'.

You are doing the output twice: Once inside the 'if' and again outside the 'if'. Why?

Most people display minutes and seconds with a leading zero:

  lcd.print("TIME:");   //writting TIME
  lcd.print(h);         //writing hours
  lcd.print(":");
  if (m < 10) lcd.print("0");
  lcd.print(m);         //writing minutes
  lcd.print(":");
  if (s < 10) lcd.print("0");
  lcd.print(s);         //writing seconds

I think it's after 8 or 9 hours....
The inpin 12 is a hall sensor.
The els after if is becouse otherwise the screen goes blank when the input is high.
I was thinking on the rollover of millis()
But thats 49 days....
I want to time up to 9999 hours.
Regards

The els after if is becouse otherwise the screen goes blank when the input is high.

But the else has no code associated with it, apart from the semicolon, that is

I look in to that...
Update,
I found the problem.
Not yet sollution.
The millis keeps running in background even with input high

Good catch! That's exactly what your code will do if the input is HIGH for a while... When it goes back to LOW the counter will count seconds as fast as it can until it catches up with the millis() counter.

Just reset the PreviousMillis when the input pin is HIGH:

#include <LiquidCrystal.h>

const byte start_pin = 12;

unsigned long PreviousMillis;
bool Changed = true;  // Update display

int h = 0;
int m = 0;
int s = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

/////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  pinMode(start_pin, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
  unsigned long currentMillis = millis();

  //// input van de timer
  if (digitalRead(start_pin))
  {
    PreviousMillis = currentMillis;
  }
  else
  {
    if (currentMillis - PreviousMillis >= 1000)
    {
      PreviousMillis += 1000;

      // Reduce flicker by only updating the LCD when
      // the display values have changed
      Changed = true;

      s++;
      if (s == 60)
      {
        s = 0;
        m++;
        if (m == 60)
        {
          m = 0;
          h++;
        } // end hrs check
      } // end minutes check
    } // end seconds check
  }

  // Reduce flicker by only updating the LCD when
  // the display values have changed
  if (Changed)
  {
    lcd.setCursor(0, 0);  //setting start point on lcd
    lcd.print("TIME:");   //writting TIME
    lcd.print(h);         //writing hours
    lcd.print(":");
    if (m < 10) lcd.print("0");
    lcd.print(m);         //writing minutes
    lcd.print(":");
    if (s < 10) lcd.print("0");
    lcd.print(s);         //writing seconds

    //uur omzetten naar verbruikte liters
    double verbruik = h * 2.2 + m * 0.0367;
    double tank = 3150 - verbruik;
    lcd.setCursor(0, 1);
    lcd.print(verbruik);
    lcd.print("L") ;
    lcd.setCursor(8, 1);
    lcd.print(tank);
    lcd.print("L");

    Changed = false;
  }
}

Another option is to keep the millis() timer running but only update the time when the input pin is LOW.

#include <LiquidCrystal.h>

const byte start_pin = 12;

unsigned long PreviousMillis;
bool Changed = true;  // Update display

int h = 0;
int m = 0;
int s = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

/////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  pinMode(start_pin, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - PreviousMillis >= 1000)
  {
    PreviousMillis += 1000;

    //// input van de timer
    if (digitalRead(start_pin) == LOW)
    {
      // Reduce flicker by only updating the LCD when
      // the display values have changed
      Changed = true;

      s++;
      if (s == 60)
      {
        s = 0;
        m++;
        if (m == 60)
        {
          m = 0;
          h++;
        } // end hrs check
      } // end minutes check
    } // end seconds check
  }

  // Reduce flicker by only updating the LCD when
  // the display values have changed
  if (Changed)
  {
    lcd.setCursor(0, 0);  //setting start point on lcd
    lcd.print("TIME:");   //writting TIME
    lcd.print(h);         //writing hours
    lcd.print(":");
    if (m < 10) lcd.print("0");
    lcd.print(m);         //writing minutes
    lcd.print(":");
    if (s < 10) lcd.print("0");
    lcd.print(s);         //writing seconds

    //uur omzetten naar verbruikte liters
    double verbruik = h * 2.2 + m * 0.0367;
    double tank = 3150 - verbruik;
    lcd.setCursor(0, 1);
    lcd.print(verbruik);
    lcd.print("L") ;
    lcd.setCursor(8, 1);
    lcd.print(tank);
    lcd.print("L");

    Changed = false;
  }
}

johnwasser;
i don't know why(yet) but your code seems to work.
i want to measure how much time the input is low.
how accurate is now this timer?
thanks to all for the great suport!
ps: i think my hall sensor is not sensitive enough....
now i am using hall sensor 3144.
it is mounted on a electric valve(and i want to know how long the elektric valve is opperated)
wich hall sensor would you guys recomend?

your time is "start" as an integer, but it counts in ms, the 16-bit variable will roll over, at some point (so do 32-bit variables but that takes a lot longer.)

Nickske:
johnwasser;
i don't know why(yet) but your code seems to work.
i want to measure how much time the input is low.
how accurate is now this timer?

I would go with the second version. It checks the input once every second. If the input is LOW it adds another second to the counter. It should average out to being accurate to about one second.

Ok , youre code works !
I'm going to add (or trying to) a menu option.
Now i have the value in the programming( the volume in the tank)
But i would like to change it without external computer.

And the option if the power is lost that the data isn't lost so when power is back, the data is back...
But to do that i first need to reed a little bit more :wink:
I try to keep you post it