Hello. Please help me fix my code. I made a countdown timer program that accepts input from the serial monitor. Basically, the user opens the serial monitor and inputs the values to it. The timer takes hours, minutes and seconds as arguments. The program converts the input to seconds which the Arduino UNO uses to count down to zero. A relay switches to a closed state while the timer is active, allowing current to pass through whatever is connected to the relay (I connected an LED to check if the relay is active).
I’ve been testing the program and so far it works. My only problem is that whenever I open the serial monitor, the UNO flickers before going stable. This shouldn’t be a problem but in effect, the relay connected to it (and by extension the LED) flickers as well. This could pose a problem especially when I start connecting the relay to other, more complicated devices. This is the problem I’m trying to eliminate.
I suspect this has something to do with noise entering the serial monitor (correct me if I’m wrong on this one). I don’t have any code that blocks noise from entering the serial monitor nor the input while the timer is active.
I’ll start with the setup function.
void setup() {
pinMode(RELAY, OUTPUT);
Serial.begin(9600);
while(!Serial) {;};
lcd.begin(16, 2);
lcd.clear();
}
Setup initializes the relay, serial monitor and lcd. The while statement above is supposed to block noise from entering the serial monitor whenever I open it. Here’s the other function for when I take in input from the serial monitor. This, and the code snippet above it, are the only functions that’ll make use of the serial monitor. It doesn’t have a way to block noise as well.
void inputPrompt() {
lcd.clear();
lcd.home();
lcd.print("Set Time(H:M:S):");
Serial.print("\nHRS = ");
while(Serial.available() == 0) {}
cd.hrs = Serial.parseInt();
Serial.print("\nMIN = ");
while(Serial.available() == 0) {}
cd.mins = Serial.parseInt();
Serial.print("\nSEC = ");
while(Serial.available() == 0) {}
cd.secs = Serial.parseInt();
}
I have a hunch this is is purely the code’s problem although I could be wrong. I’m posting the full code below just in case anyone’s interested.
#include <LiquidCrystal_I2C.h>
#define RELAY 13 // Changed pin assignments to define statements
const short HRS = 6;
const short MINS = 59;
const short SECS = 59;
struct set_countdown {
unsigned int raw;
int hrs;
int mins;
int secs;
};
struct set_countdown cd;
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void setup() {
pinMode(RELAY, OUTPUT);
Serial.begin(9600);
while(!Serial) {;};
lcd.begin(16, 2);
lcd.clear();
}
void loop() {
digitalWrite(RELAY, HIGH);
inputPrompt();
if ((cd.hrs < HRS) && (cd.mins <= MINS) && (cd.secs <= SECS)) {
char char_buffer[6] = "";
sprintf(char_buffer, "%02d:%02d:%02d", cd.hrs, cd.mins, cd.secs);
Serial.print("\nTime has been set to ");
Serial.println(char_buffer);
cd.raw = (cd.hrs * 3600) + (cd.mins * 60) + cd.secs;
executeCountDown();
} else {
Serial.println("\nTime set denied. Set value out of bounds!");
}
}
void inputPrompt() {
lcd.clear();
lcd.home();
lcd.print("Set Time(H:M:S):");
Serial.print("\nHRS = ");
while(Serial.available() == 0) {}
cd.hrs = Serial.parseInt();
Serial.print("\nMIN = ");
while(Serial.available() == 0) {}
cd.mins = Serial.parseInt();
Serial.print("\nSEC = ");
while(Serial.available() == 0) {}
cd.secs = Serial.parseInt();
}
void executeCountDown() {
unsigned long previous_millis = 0;
const int interval_sec = 1000;
char lcd_buffer[8] = "";
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Time Remaining");
while(cd.raw > 0) {
digitalWrite(RELAY, LOW);
lcd.setCursor(4, 1);
sprintf(lcd_buffer, "%02d:%02d:%02d", cd.hrs, cd.mins, cd.secs);
unsigned long current_millis = millis();
if ((current_millis - previous_millis) >= interval_sec) {
if ((cd.secs > 0) && (cd.mins >= 0) && (cd.hrs >= 0)) {
// Seconds countdown to zero
cd.secs--;
cd.raw--;
lcd.setCursor(4, 1);
lcd.print(lcd_buffer);
previous_millis = current_millis;
} else if ((cd.secs == 0) && (cd.mins > 0) && (cd.hrs >= 0)) {
// Seconds reach zero, decrement minute
cd.mins--;
cd.secs = 59;
cd.raw--;
lcd.setCursor(4, 1);
lcd.print(lcd_buffer);
previous_millis = current_millis;
} else if ((cd.secs == 0) && (cd.mins == 0) && (cd.hrs > 0)) {
// Minutes reach zero, seconds reach zero, decrement hour
cd.hrs--;
cd.mins = 59;
cd.secs = 59;
cd.raw--;
lcd.setCursor(4, 1);
lcd.print(lcd_buffer);
previous_millis = current_millis;
}
}
}
Serial.println("Set time has reached zero...");
}
Much help would be appreciated. Thank you and good day.