This is the code. The /// are where I added the countdown. Unfortunately the countdown only goes down 9 seconds. What I want it to do is go down the full 24 hours. I have been trying to fix this error for months with no luck.
int beeper_pin = 2; //Naming buzzer pin
int resetGarden_pin = 3; //Naming the warning led pin
int pump_pin = 6; //Naming the pump pin
#include <LiquidCrystal_I2C.h> // Driver Library for the LCD Module
LiquidCrystal_I2C lcd(0x27, A4, A5);
void clearLCDLine(int line)
{
lcd.setCursor(0, line);
for (int n = 0; n < 20; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16
{
lcd.print(" ");
}
}
void beepWarning() { //Makes beeping a subroutine
lcd.setCursor(0, 0);
lcd.print("WARNING");
delay(100);
lcd.setCursor(0, 1);
for (int x = 0; x < 3; x++) {
lcd.setCursor(0, 1);
lcd.print("WATER PUMP ACTIVE");
delay(100);
clearLCDLine(1);
lcd.setCursor(0, 1);
lcd.print("WATER PUMP ACTIVE.");
delay(100);
clearLCDLine(1);
lcd.setCursor(0, 1);
lcd.print("WATER PUMP ACTIVE..");
delay(100);
clearLCDLine(1);
lcd.setCursor(0, 1);
lcd.print("WATER PUMP ACTIVE...");
delay(100);
clearLCDLine(1);
}
lcd.setCursor(0, 1);
lcd.print("WATER PUMP ACTIVE...");
for (int x = 0; x < 3; x++) { //Repeats 3 times
digitalWrite(beeper_pin, HIGH); //Turn on buzzer
delay(100); //Delay of 400 milliseconds
digitalWrite(beeper_pin, LOW); //Turns off buzzer
delay(100); //Delay of 400 milliseconds
}
}
void SOSWarning() { //Makes SOS a subroutine
clearLCDLine(1);
lcd.setCursor(0, 0);
lcd.print("WPA Reset Aerogarden");
for (int x = 0; x < 3; x++) { //Repeats 3 times
for (int d = 0; d < 3; d++) { //Repeats 3 times
digitalWrite(beeper_pin, HIGH); //Turn on buzzer
delay(200); //Delay of 400 milliseconds
digitalWrite(beeper_pin, LOW); //Turns off buzzer
delay(200); //Delay of 400 milliseconds
}
for (int a = 0; a < 3; a++) { //Repeats 3 times
digitalWrite(beeper_pin, HIGH); //Turn on buzzer
delay(400); //Delay of 400 milliseconds
digitalWrite(beeper_pin, LOW); //Turns off buzzer
delay(400); //Delay of 400 milliseconds
}
for (int d = 0; d < 3; d++) { //Repeats 3 times
digitalWrite(beeper_pin, HIGH); //Turn on buzzer
delay(200); //Delay of 400 milliseconds
digitalWrite(beeper_pin, LOW); //Turns off buzzer
delay(200); //Delay of 400 milliseconds
}
delay(500); //Delay of 500 milliseconds
}
}
void weekDelay() { //Makes waiting for a week a subroutine
clearLCDLine(1);
lcd.setCursor(0, 0);
lcd.print("Waiting One Week");
long hour = 23, minute = 59, second = 59;//second //////////////////////////
long countdown_time = (hour * 3600) + (minute * 60) + second; ///////////////////////////////////////////////////////////////////////////
long countdowntime_seconds = countdown_time - (millis() / 1000); /////////
if (countdowntime_seconds >= 0) { ///////////////////////////////////////////////
long countdown_hour = countdowntime_seconds / 3600;
long countdown_minute = ((countdowntime_seconds / 60) % 60);
long countdown_sec = countdowntime_seconds % 60;
lcd.setCursor(4, 1);
if (countdown_hour < 10) {
lcd.print("0");
}
lcd.print(countdown_hour);
lcd.print(":");
if (countdown_minute < 10) {
lcd.print("0");
}
lcd.print(countdown_minute);
lcd.print(":");
if (countdown_sec < 10) {
lcd.print("0");
}
lcd.print(countdown_sec);
}
delay(500);///////////////////////////////////////////////////////////////
delay(500);
delay(86400000);
clearLCDLine(0);
lcd.setCursor(0, 0);
lcd.print("Waiting Six Days");
delay(86400000);
clearLCDLine(0);
lcd.setCursor(0, 0);
lcd.print("Waiting Five Days");
}
void pumpOn() { //Makes turning on the pump a subroutine
clearLCDLine(1);
lcd.setCursor(0, 1);
lcd.print("PUMPING");
delay(100);
digitalWrite(pump_pin, HIGH); //Turning on the pump
}
void pumpOff() { //Makes turning off the pump a subroutine
digitalWrite(pump_pin, LOW); //Turning off the pump
clearLCDLine(1);
lcd.setCursor(0, 1);
lcd.print("WATER PUMP OFF");
delay(100);
}
void setup() {
//run once:
lcd.backlight();
lcd.init();
lcd.setCursor(4, 0);//////////////////////////////////////////////////////
lcd.print("HH:MM:SS"); //////////////////////////////////////////////////
lcd.clear(); // Clear the screen
lcd.setCursor(0, 0);
lcd.print("Aero_Pump V3");
delay(1000);
lcd.setCursor(0, 1);
lcd.print("By Alex");
delay(1000);
pinMode (beeper_pin, OUTPUT); //Setting outputs
pinMode (resetGarden_pin, OUTPUT); //Setting outputs
pinMode (pump_pin, OUTPUT); //Setting outputs
lcd.clear(); // Clear the screen
digitalWrite(resetGarden_pin, LOW); //Turning off the reset garden light
beepWarning(); //Beeps a warning
pumpOn(); //Turns on the pump
delay(3000); //Adds a delay of 24000 milliseconds
pumpOff(); //Turns off the pump
weekDelay(); //Waits a week
beepWarning(); //Beeps a warning
pumpOn(); //Turns on the pump
delay(135000); //Adds a delay of 48000 milliseconds
pumpOff(); //Turns off the pump
weekDelay(); //Waits a week
}
void loop() {
SOSWarning(); //Beeps an SOS warning
pumpOn(); //Turns on the pump
delay(48000); //Adds a delay of 48000 milliseconds
pumpOff(); //Turns off the pump
for (int x = 0; x < 3024000; x++) {
lcd.backlight(); // turn on backlight.
delay(100);
lcd.noBacklight(); // turn off backlight
delay(100);
}
lcd.backlight(); // turn on backlight.
}
This is more specifically what needs to be fixed:
long hour = 23, minute = 59, second = 49;//second //////////////////////////
long countdown_time = (hour * 3600) + (minute * 60) + second; ///////////////////////////////////////////////////////////////////////////
long countdowntime_seconds = countdown_time - (millis() / 1000); /////////
if (countdowntime_seconds >= 0) {
long countdown_hour = countdowntime_seconds / 3600;
long countdown_minute = ((countdowntime_seconds / 60) % 60);
long countdown_sec = countdowntime_seconds % 60;
lcd.setCursor(4, 1);
if (countdown_hour < 10) {
lcd.print("0");
}
lcd.print(countdown_hour);
lcd.print(":");
if (countdown_minute < 10) {
lcd.print("0");
}
lcd.print(countdown_minute);
lcd.print(":");
if (countdown_sec < 10) {
lcd.print("0");
}
lcd.print(countdown_sec);
}
This is some edited code that I have tried but might have made a mistake on because it does 0 days instead of 7 and (Hours/Min/Sec) 04:09:36.
void weekDelay() { //Makes waiting for a week a subroutine
clearLCDLine(1);
clearLCDLine(0);
lcd.setCursor(0, 0);
lcd.print("Waiting One Week");
unsigned long start = millis();
unsigned long week_secs = 7 * 24 * 3600;
unsigned long countdowntime_seconds;
while (countdowntime_seconds = week_secs - (millis() - start)/1000){
char buff[80];
unsigned long countdown_day = countdowntime_seconds / 3600 / 24;
int countdown_hour = (countdowntime_seconds / 3600) % 24;
int countdown_minute = ((countdowntime_seconds / 60) % 60);
int countdown_sec = countdowntime_seconds % 60;
sprintf(buff,"%1d days, %02d:%02d:%02d",
(int) countdown_day,
countdown_hour,
countdown_minute,
countdown_sec
);
Serial.print(buff);
clearLCDLine(1);
lcd.setCursor(2, 1);
lcd.print(buff);
delay(1000);
}
}
1 Answer 1
I'd try something with a while(){}
loop and a sprintf()
, like:
void weekDelay() { //Makes waiting for a week a subroutine
unsigned long start = millis();
unsigned long week_secs = 7 * 24 * 3600;
unsigned long countdowntime_seconds;
while (countdowntime_seconds = week_secs - (millis() - start)/1000){
char buff[80];
unsigned long countdown_day = countdowntime_seconds / 3600 / 24;
// or maybe
//int countdown_day = (int)(countdowntime_seconds / 3600UL / 24UL);
int countdown_hour = (countdowntime_seconds / 3600) % 24;
int countdown_minute = ((countdowntime_seconds / 60) % 60);
int countdown_sec = countdowntime_seconds % 60;
sprintf(buff,"%1d days, %02d:%02d:%02d",
(int) countdown_day,
countdown_hour,
countdown_minute,
countdown_sec
);
clearLCDLine(1);
lcd.setCursor(0, 0);
lcd.print(buff);
delay(1000);
}
}
Or make it more general and start it off like:
void coundownDelay(unsigned long seconds) { //Makes waiting for a week a subroutine
unsigned long start = millis();
unsigned long countdowntime_seconds;
while (countdowntime_seconds = seconds - (millis() - start)/1000){
...
}
and call like:
...
countdownDelay(7 * 24 * 3600); //Waits a week
...
-
It is incredibly close and I thank you a lot for your contribution.alexlikesallthegamez– alexlikesallthegamez2021年12月11日 06:07:57 +00:00Commented Dec 11, 2021 at 6:07
-
1Sorry -- I had the sense of direction wrong. I edited the math. For debugging, you might want to try smaller delays so you can see if and where things go wrong in less than 9 hours.Dave X– Dave X2021年12月11日 16:19:03 +00:00Commented Dec 11, 2021 at 16:19
-
1Ah, it is the integer math interacting with the size of
days
. 04:09:36 = 4*3600+9*60+36 = 14976 which happens to be equal to 7*24*3600 % 32768. See gammon.com.au/forum/?id=12146 and wiki.sei.cmu.edu/confluence/display/c/… for what's happening. I added some casting and types to theday=
line. Alternately, one could define days asunsigned long days
and then print it withsprintf(buff,"%1d days, %02lu:%02d:%02d",
Dave X– Dave X2021年12月11日 22:54:41 +00:00Commented Dec 11, 2021 at 22:54 -
I changed my code to
int countdown_day = countdowntime_seconds / 3600 / 24;
to have two divides instead of a multiply and divide. I don't have an arduino available, so it is still untested there. In C, the several versions worked.Dave X– Dave X2021年12月12日 06:58:47 +00:00Commented Dec 12, 2021 at 6:58 -
1That particular number, 04:09:36 is special, it is 14976 seconds, which is what a week work of seconds (7*24*3600=604800) forced into a signed int that can only hold numbers in −32768, +32767. This indicating problems doing the math with 16 bit ints. Right now I can only test code bits with gcc on a Mac, where default math is done with 32 bit ints. I added two options to the code, one doing the math with unsigned longs all the way through (and casting it to an int for the sprintf) an another attempting to keep the math in ULs and casting it into an int for storage.Dave X– Dave X2021年12月13日 00:36:52 +00:00Commented Dec 13, 2021 at 0:36
Explore related questions
See similar questions with these tags.
delay()
s in your code. Here's a simplemillis
based count down timer if you are interested. arduino.stackexchange.com/a/82217/37523user manual
first. Can you give me a description of your project, what it does, when it does it, etc.?weekDelay()
function, which looks like it has several problems. What do you expectweekDelay()
to do?weekDelay
looks like it only does two day-longdelay(86400000);
pauses. You could replace lots of its code withchar buff[80]; sprintf(buff,"%02d:%02d:%02d",countdowntime_hour,countdowntime_minute,countdowntime_secs); lcd.print(buff);
It also doesn't seem to have any countdown logic--From this code I see no loops inweekDelay()
that could count down even 9 seconds, let alone the 604800 seconds in a week.