-1

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);
 }
}
asked Dec 6, 2021 at 23:12
9
  • You sure have a lot of delay()s in your code. Here's a simple millis based count down timer if you are interested. arduino.stackexchange.com/a/82217/37523 Commented Dec 6, 2021 at 23:46
  • It seems like the countdown is just skipped for some reason. Commented Dec 7, 2021 at 0:17
  • 1
    I would be happy to help you. Before writing any code, it's better to write the user manual first. Can you give me a description of your project, what it does, when it does it, etc.? Commented Dec 7, 2021 at 0:48
  • Your code is in the middle of the weekDelay() function, which looks like it has several problems. What do you expect weekDelay() to do? Commented Dec 7, 2021 at 2:12
  • 1
    Is it supposed to wait a week? As is, weekDelay looks like it only does two day-long delay(86400000); pauses. You could replace lots of its code with char 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 in weekDelay() that could count down even 9 seconds, let alone the 604800 seconds in a week. Commented Dec 10, 2021 at 3:18

1 Answer 1

0

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
 ...
answered Dec 10, 2021 at 19:21
7
  • It is incredibly close and I thank you a lot for your contribution. Commented Dec 11, 2021 at 6:07
  • 1
    Sorry -- 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. Commented Dec 11, 2021 at 16:19
  • 1
    Ah, 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 the day= line. Alternately, one could define days as unsigned long days and then print it with sprintf(buff,"%1d days, %02lu:%02d:%02d", Commented 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. Commented Dec 12, 2021 at 6:58
  • 1
    That 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. Commented Dec 13, 2021 at 0:36

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.