The code I use probably has a math problem since an Arduino can only count a 16 bit integer. This problem is with the WeekDelay() function. The project is for an Aerogarden. It pumps water into the garden every week from information based on my collected data. It writes on the LCD information like if it is pumping, waiting (it should have the timer here and display on the LCD), and it can show when it is going to pump with a beep warning. After beeping, pumping, and waiting for a few times I run out of information and do a loop and show a warning message, blinking the LCD and pumping a set amount. More specifically WeekDelay() should be a delay for a week. It clears the LCD, Sets the cursor to 0,0 and prints "Waiting one week". It should then have a countdown of 24 hours on the screen and then just how many days it is waiting. It does that through clearing the LCD, Setting the cursor, printing days and waiting.
Because of the glitch it does not display any days even though it should show 7. It displays 04:09:36. Somebody was helping me out and said this:
Ah, it is the integer math interacting with the size of days. 04:09:36 = 43600+960+36 = 14976 which happens to be equal to 7243600 % 32768. See gammon.com.au/forum/?id=12146 and https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions for what's happening.
This is some cut-down version of my code:
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);
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];
int 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",
countdown_day,
countdown_hour,
countdown_minute,
countdown_sec
);
Serial.print(buff);
clearLCDLine(1);
lcd.setCursor(2, 1);
lcd.print(buff);
delay(1000);
}
}
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(1000);
}
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(12000); //Adds a delay of 24000 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 the function that needs to be fixed:
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];
int 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",
countdown_day,
countdown_hour,
countdown_minute,
countdown_sec
);
Serial.print(buff);
clearLCDLine(1);
lcd.setCursor(2, 1);
lcd.print(buff);
delay(1000);
}
}
lcd.print("WATER PUMP ACTIVE");
...delay(100);
...lcd.print(".");
... there is no need to clear LCD and print same line over and over