So my goal with this project is for the timer to countdown to and stop at zero which triggers a buzzer sound and to have a button that resets the timer back to its initial starting time and counts down again.
I am using an Arduino Uno and a 16x2 LCD display. I have attached a TinkerCAD screenshot that is a recreation of my circuitry so far. I want to incorporate an active buzzer and reset button once I have figured out how do so properly.
Below is my existing code. Currently it counts down from the starting time and once it hits zero there is a 10 second delay and it restarts counting from the starting time again on an infinite loop. Again, I want this to stop at zero and sound a buzzer and I want a button to manually restart the countdown. I can't seem to figure out how to code this. Can someone please help me out???
#include <LiquidCrystal.h>
int S = 00; // count seconds
int M = 01; // count minutes
int H = 00; // count hours
//initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,6,10,11,12,13); // pins connected to LCD
void setup()
{
lcd.begin(16,2);//set up the LCD's number of columns and rows
}
void loop()
{
lcd.setCursor(1,0);
lcd.print ("Countdown");
lcd.setCursor(6,1);
lcd.print(":");
lcd.setCursor(9,1);
lcd.print(":");
S--;
delay(1000);
if(S<0)
{
M--;
S=59;
}
if(M<0)
{
H--;
M=59;
}
if(H<0) {
delay(10000);
H=00;
M=01;
S=00;
}
if(H<0) { H=00; M=01; S=00; } if(M>9)
{
lcd.setCursor(7,1);
lcd.print(M);
}
else
{
lcd.setCursor(7,1);
lcd.print("0");
lcd.setCursor(8,1);
lcd.print(M);
lcd.setCursor(9,1);
lcd.print(":");
}
if(S>9)
{
lcd.setCursor(10,1);
lcd.print(S);
}
else
{
lcd.setCursor(10,1);
lcd.print("0");
lcd.setCursor(11,1);
lcd.print(S);
lcd.setCursor(12,1);
lcd.print(" ");
}
if(H>9)
{
lcd.setCursor(4,1);
lcd.print (H);
}
else
{
lcd.setCursor(4,1);
lcd.print("0");
lcd.setCursor(5,1);
lcd.print(H);
lcd.setCursor(6,1);
lcd.print(":");
}
}
Please post the code inside code tags, </>. That makes it easier to ready.
I can't see any reading of the button. How will the code wait for the button being pressed?
You can try something with the concepts presented here, change it as you need.
#include <LiquidCrystal.h>
#define DELAY_TIME 59999ul //play with this to get the initial value behavior you want
#define BUZZER_ON_TIME 10000ul //10-second buzzer sound
#define SW_READ_INTERVAL 50ul //50mS switch read interval
// state names
#define WAIT_RESET 0 //wait for user to start reset
#define COUNT_DOWN 1 //counting down
#define SOUND_BUZZER 2 //timing buzzer on
//
int
Hours,
LastHours,
Minutes,
LastMinutes,
Seconds,
LastSeconds;
byte
lastSw,
stateCD = WAIT_RESET;
unsigned long
timeLeft,
timeNow;
unsigned long
timeStart;
const byte pinReset = 2;
const byte pinBuzzer = 3;
//initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4, 6, 10, 11, 12, 13); // pins connected to LCD
void setup()
{
Serial.begin( 9600 );
pinMode( pinReset, INPUT_PULLUP );
pinMode( pinBuzzer, OUTPUT );
lcd.begin(16, 2); //set up the LCD's number of columns and rows
lcd.setCursor(1, 0);
lcd.print ("Countdown");
Serial.println( "Countdown" );
lcd.setCursor(1, 1);
lcd.print( "Press reset... ");
Serial.println( "Press reset... " );
lastSw = digitalRead( pinReset );
}//setup
void loop()
{
//get the millis count now
timeNow = millis();
switch( stateCD )
{
case WAIT_RESET:
//did we sense a switch press?
if( ReadSwitch() == true )
{
//yes; begin countdown
timeStart = timeNow; //save millis when countdown started
LastHours = LastMinutes = LastSeconds = -1; //set last values to force initial LCD update
//move to countdown state
stateCD = COUNT_DOWN;
}//if
break;
case COUNT_DOWN:
if( ReadSwitch() == true )
{
//user pressed reset while counting down. Stop countdown and go back to WAIT_RESET state
//ask user to hit reset again
lcd.setCursor( 1, 1 );
lcd.print( "Press reset... " );
Serial.println( "Press reset... " );
//
stateCD = WAIT_RESET;
}
else
{
//timeLeft gives us the number of mS left in the countdown
timeLeft = DELAY_TIME - (timeNow - timeStart);
Hours = (int)(timeLeft / 3600000ul);
timeLeft = timeLeft - Hours * 3600000ul;
Minutes = (int)(timeLeft / 60000ul);
timeLeft = timeLeft - Minutes * 60000ul;
Seconds = (int)(timeLeft / 1000ul);
//if hours, minutes or seconds has changed, update the display
if( Hours != LastHours || Minutes != LastMinutes || Seconds != LastSeconds )
{
LastHours = Hours;
LastMinutes = Minutes;
LastSeconds = Seconds;
UpdateDisplay();
//on that change, check to see if all have hit zero
//if so, sound alarm and move to that state
if( Hours == 0 && Minutes == 0 && Seconds == 0 )
{
lcd.setCursor( 1, 1 );
lcd.print( " **ALARM** " );
Serial.println( " **ALARM** " );
//
digitalWrite( pinBuzzer, HIGH );
timeStart = timeNow;
stateCD = SOUND_BUZZER;
}//if
}//if
}//else
break;
case SOUND_BUZZER:
//wait for duration of buzzer sound (or user to hit reset switch...)
if( timeNow - timeStart >= BUZZER_ON_TIME || (ReadSwitch() == true) )
{
//then turn it off
digitalWrite( pinBuzzer, LOW );
//ask user to hit reset again
lcd.setCursor( 1, 1 );
lcd.print( "Press reset... " );
Serial.println( "Press reset... " );
//and go back and wait for it
stateCD = WAIT_RESET;
}//if
break;
}//switch
}//loop
void UpdateDisplay( void )
{
char
szStr[15];
//form a simple hh:mm:ss NULL-term string and print it to the LCD
sprintf( szStr, "%02d:%02d:%02d", Hours, Minutes, Seconds );
lcd.setCursor( 1, 1 );
lcd.print( szStr );
//debug
Serial.println( szStr );
}//UpdateDisplay
bool ReadSwitch( void )
{
byte
currSw;
static unsigned long
timeRead = 0;
unsigned long
timeNow;
timeNow = millis();
if( (timeNow - timeRead) < SW_READ_INTERVAL )
return false;
timeRead = timeNow;
//waiting to start the countdown; has used pressed button "down"?
currSw = digitalRead( pinReset );
if( currSw != lastSw )
{
lastSw = currSw;
if( currSw == LOW )
{
if( digitalRead( pinReset ) == LOW )
{
return true;
}//if
}//if
}//if
return false;
}//ReadSwitch
This is exactly what I needed! Thank you a ton for your help!
Wisharam:
This is exactly what I needed! Thank you a ton for your help!
Good to hear. I encourage you to go through it and understand what's going on so the next time you face a similar challenge you can draw on the learning experience.