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");
}
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 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
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
I try to keep you post it