Problem Adjusting Alarm time on Alarm Clock

Hello everyone,

I am currently working on building an alarm clock that will open my window blinds when the alarm goes off. I have everything wired up correctly so there is no problem there, but the problem is in my code. (At least I am pretty sure it is :confused: ) I am using the time.h library and the time alarms.h library to setup the clock portion and alarm portion. As you will see in my code..I have 4 push buttons in my alarm clock. The first push button opens the blinds and the second one closes them. The third sets the alarm hours and the fourth sets the alarm minutes.

The problem I ran into is I can set the alarm in the computer, but once I try to use the buttons to set the alarm hours and minutes, it no longer works. Can anyone help?? Here is my code!

#include <Time.h>									//Include Time library
#include <TimeAlarms.h>								//Include Time Alarms library
#include <LiquidCrystal.h>							//Include Liquid Crystal library
#include <Servo.h>									//Include Servo library
Servo servoMain;									// Define Servo


LiquidCrystal lcd(7, 6, 5, 4, 3, 2);				//Initialize the LCD

const int buttonPin = 9;    						// the number of the pushbutton pin
int buttonState = 0;         						// variable for reading the pushbutton status

int ahours = 8;										//Declare variable alarm hours
int amins = 31;										
int asecs = 0;

int hours = 8;										//Declare time variables
int mins = 30;
int secs = 50;




void setup()
{
  servoMain.attach(12); 							//Servo on digital pin 10
  servoMain.write(0);  								//Turn Servo back to center position (90 degrees)
	
  pinMode(13, INPUT);								//Initialize push button 13
  digitalWrite(13, HIGH);
  pinMode(11, INPUT);								//Initialize push button 11
  digitalWrite(11, HIGH);
  pinMode(10, INPUT);								//Initialize push button 10
  digitalWrite(10, HIGH);
  pinMode(8, INPUT);								//Initialize push button 8
  digitalWrite(8, HIGH);
  pinMode(9, INPUT);								//Initialize push button A0
  digitalWrite(9, HIGH);
  
  
   
  setTime(hours,mins,secs,8,8,15); 				    //Set time to Saturday 8:29:00am Jan 1 2011
  lcd.begin(16,2);									//Setup LCD Screen
  lcd.clear();										//Lcd clear
  lcd.setCursor(0,0);							    //Lcd cursor (0,0)


Alarm.alarmRepeat(ahours,amins,asecs, MorningAlarm);// 8:30am every day
}
      
void  loop()
{ 
 
  lcd.setCursor(0,0);
  lcd.print("Time:");								//Lcd print "Time:"
  lcd.setCursor(10,0);								//Lcd set cursor (10,0)
  lcd.print("Alarm:");								//Lcd print "Alarm:"								
  digitalClockDisplay();							//Digital clocl display
  Alarm.delay(1000); 								//wait one second between clock display


if(digitalRead(11) == LOW)							//Push button to change alarm hours
    {
     ahours++;										//Add 1 to Alarm hours
     delay(100);									//Delay
    } 
  if(digitalRead(13) == LOW)						//Push button to change alarm mimutes
    {
     amins++;										//Add 1 to alarm minutes
     delay(100);
    } 
    
    
  lcd.setCursor(10,1);								//Lcd set cursor(12,1)
  
  if(ahours < 10)
    {
     lcd.print("0");								//Lcd print "0"
     lcd.print(ahours);								//Lcd print alarm hours
    }
  else
    {
     lcd.print(ahours);								//Lcd print alarm hours
    }
    
  lcd.print(":");									//Lcd print ":"
    
  if (amins < 10)
    {
     lcd.print("0");								//Lcd Print "0"
     lcd.print(amins);								//Lcd print alarm minutes
    }
  else
    {
     lcd.print(amins);								//Lcd print alarm minutes
    }
 if(amins > 59)
    {
     ahours++;										//Alarm hours
     amins = 0;										//Alarm minutes = 0
    } 
 if(ahours > 23)
    {
     ahours = 0; 							     	//Alarm hours = 0
    }

  }


void MorningAlarm()								    //Morning Alarm
{
	servoMain.write(160);                           // Turn Servo back to center position
	
	
}


void digitalClockDisplay()
{
  lcd.setCursor(0,1);								//Lcd set cursor (0,1)
  lcd.print(hour());								// digital clock display of the time
  printDigits(minute());							//^
  printDigits(second());							//^
  
  
 
}

void printDigits(int digits)
{

  lcd.print(":");									//Lcd print ":"
  if(digits < 10)			
  lcd.print('0');									//Lcd print "0"
  lcd.print(digits);								//Lcd print "digits"
  

    if (digitalRead(8) == LOW) 						//Push button to move servo to close position
  {     
    servoMain.write(0);  							//Turn Servo back to close
  }
  
  
  
  if (digitalRead(10) == LOW) 						//Push button to move servo to open position
  {     
    servoMain.write(160);						    //Turn Servo back to open position
  }

  
}

In loop(), you may be changing aHours and/or aMins. But, you never do anything with the new values. What are you expecting to happen, magically, when you change them?

PaulS:
In loop(), you may be changing aHours and/or aMins. But, you never do anything with the new values. What are you expecting to happen, magically, when you change them?

Whoops! you are right. How could I use those new values I get in loop(); and have them go into the Alarm.alarmRepeat? So when I change the alarm time the alarm will actually work?

Hi PaulS,
I tried just a simple

 int ahours = ahours++;

right below

amins++;

but that still did not work. I am very confused!

You need to do the

Alarm.alarmRepeat(ahours,amins,asecs, MorningAlarm);

After you have finished adjusting ahours and amins. For that you need some method of the program knowing that you have finished updating the values. A pushbutton, maybe.

I tried just a simple

 int ahours = ahours++;

but that still did not work. I am very confused!

I'm not surprised. First, that is NOT valid code. The correct code is either

ahours = ahours + 1;

or

ahours++;

Second, you passed data to the Alarm class BY VALUE. The alarm instance is NOT bound to the values in some variables.

You MUST delete the alarm, and create a new one, with the modified values.

Hi guys! Sorry I've been offline a while, but I'll look into it and experiment with it! If I have any more problems I'll come back here

UKHeliBob:
You need to do the

Alarm.alarmRepeat(ahours,amins,asecs, MorningAlarm);

After you have finished adjusting ahours and amins. For that you need some method of the program knowing that you have finished updating the values. A pushbutton, maybe.

Hi UKHeliBob,

I tried doing this and incorporating the push button idea, but I do not know where I am going wrong. I'm really trying to learn C++, so thank you for all your patience! Here is my updated code with the push button that doesn't work.

#include <Time.h>									//Include Time library
#include <TimeAlarms.h>								//Include Time Alarms library
#include <LiquidCrystal.h>							//Include Liquid Crystal library
#include <Servo.h>									//Include Servo library
Servo servoMain;									// Define Servo
Servo servo2;

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);				//Initialize the LCD

const int buttonPin = 9;    						// the number of the pushbutton pin
int buttonState = 0;         						// variable for reading the pushbutton status



int hours = 8;										//Declare time variables
int mins = 30;
int secs = 50;

int ahours = 8;										//Declare variable alarm hours
int amins = 31;										
int asecs = 0;
int ah = 8;
int am = 31;


void setup()
{
  servoMain.attach(12); 							//Servo on digital pin 10
  servoMain.write(0);  								//Turn Servo back to center position (90 degrees)
	
  pinMode(13, INPUT);								//Initialize push button 13
  digitalWrite(13, HIGH);
  pinMode(11, INPUT);								//Initialize push button 11
  digitalWrite(11, HIGH);
  pinMode(10, INPUT);								//Initialize push button 10
  digitalWrite(10, HIGH);
  pinMode(8, INPUT);								//Initialize push button 8
  digitalWrite(8, HIGH);
  pinMode(9, INPUT);								//Initialize push button A0
  digitalWrite(9, HIGH);
  
  
   
  setTime(hours,mins,secs,8,8,15); 				    //Set time to Saturday 8:29:00am Jan 1 2011
  lcd.begin(16,2);									//Setup LCD Screen
  lcd.clear();										//Lcd clear
  lcd.setCursor(0,0);							    //Lcd cursor (0,0)



}
      
void  loop()
{ 


 
  lcd.setCursor(0,0);
  lcd.print("Time:");								//Lcd print "Time:"
  lcd.setCursor(10,0);								//Lcd set cursor (10,0)
  lcd.print("Alarm:");								//Lcd print "Alarm:"								
  digitalClockDisplay();							//Digital clocl display
  Alarm.delay(1000); 								//wait one second between clock display



  if(digitalRead(11) == LOW)							//Push button to change alarm hours
    {
     ahours++;										//Add 1 to Alarm hours
     delay(100);									//Delay
    } 
    
    
  if(digitalRead(13) == LOW)						//Push button to change alarm mimutes
    {
     amins++;										//Add 1 to alarm minutes
     delay(100);
    }
  
     
    if(digitalRead(9) == LOW)
    {
   
    	ahours = ah;
    	amins = am;
    }

 
  lcd.setCursor(10,1);								//Lcd set cursor(12,1)
  
  if(ahours < 10)
    {
     lcd.print("0");								//Lcd print "0"
     lcd.print(ahours);								//Lcd print alarm hours
    }
  else
    {
     lcd.print(ahours);								//Lcd print alarm hours
    }
    
  lcd.print(":");									//Lcd print ":"
    
  if (amins < 10)
    {
     lcd.print("0");								//Lcd Print "0"
     lcd.print(amins);								//Lcd print alarm minutes
    }
  else
    {
     lcd.print(amins);								//Lcd print alarm minutes
    }
 if(amins > 59)
    {
     ahours++;										//Alarm hours
     amins = 0;										//Alarm minutes = 0
    } 
 if(ahours > 23)
    {
     ahours = 0; 							     	//Alarm hours = 0
    }
 
 Alarm.alarmRepeat(ah, am, asecs, theAlarm);
 
   
}

void theAlarm()
{
	servoMain.write(160);
}



void digitalClockDisplay()
{
  lcd.setCursor(0,1);								//Lcd set cursor (0,1)
  lcd.print(hour());								// digital clock display of the time
  printDigits(minute());							//^
  printDigits(second());							//^
 
}

void printDigits(int digits)
{

  lcd.print(":");									//Lcd print ":"
  if(digits < 10)			
  lcd.print('0');									//Lcd print "0"
  lcd.print(digits);								//Lcd print "digits"
  
if (digitalRead(8) == LOW) 						//Push button to move servo to close position
  {     
    servoMain.write(0);  							//Turn Servo back to close
  }
  
  
  if (digitalRead(10) == LOW) 						//Push button to move servo to open position
  {     
    servoMain.write(160);						    //Turn Servo back to open position
  }
  

  
}

What is happening is I can set the time on the screen, but when I try to press the push button it shows the time I set for the integer "am" and "ah". I am very lost so please help!! Thanks!

The first thing that I notice is that you are setting a repeat alarm each time through loop(). That cannot be right. What you should be doing is only creating the alarm when the set button is pressed. You could also use the same button to start the alarm time setting process. I find it difficult to follow your code because you have not given the inputs names.

With named buttons the code would look something like this.

start of loop()
  if the setAlarm button becomes pressed
    call the setAlarm function
  end if
  display the time
end of loop()

start of setAlarm function
  while the setAlarm button has not become pressed
    check the setAlarm button
    code here to read the setHours and setMinutes buttons and update variables
  end while
  create the alarm using updated variables
end of setAlarm function

Thanks for your help! I know its not the neatest code, but I will tidy it up. I will work on my project and get back to you if anything else happens! Thanks for the help!

UKHeliBob:
The first thing that I notice is that you are setting a repeat alarm each time through loop(). That cannot be right. What you should be doing is only creating the alarm when the set button is pressed. You could also use the same button to start the alarm time setting process. I find it difficult to follow your code because you have not given the inputs names.

With named buttons the code would look something like this.

start of loop()

if the setAlarm button becomes pressed
    call the setAlarm function
  end if
  display the time
end of loop()

start of setAlarm function
  while the setAlarm button has not become pressed
    check the setAlarm button
    code here to read the setHours and setMinutes buttons and update variables
  end while
  create the alarm using updated variables
end of setAlarm function

Quick question. So I have this code

void setAlarm()
{
	while(digitalRead(9) == HIGH)
	{
	   	  lcd.setCursor(9,0);
		  lcd.print("+");
		  if(digitalRead(11) == LOW)							//Push button to change alarm hours
    		{
     			ahours++;										//Add 1 to Alarm hours
     			delay(100);									//Delay
			} 
    
  		  if(digitalRead(13) == LOW)						//Push button to change alarm mimutes
    		{
     			amins++;										//Add 1 to alarm minutes
     			delay(100);
    		}
  
	}
	 Alarm.alarmRepeat(ahours, amins, asecs, theAlarm);
	
}

for my setAlarm function, but I do not know what to do with updated the variables (ahours and amins) and how to create the alarm with these updated varables. How can I do so? Or is what I have fine? Thanks!

Your general approach seems OK but there are problems.

Firstly you have no check on whether the hours and minutes stay in a reasonable range.

Then, although

Alarm.alarmRepeat(ahours, amins, asecs, theAlarm);

sets an alarm, you are not cancelling any that you previously set so several may be active.

UKHeliBob:
Your general approach seems OK but there are problems.

Firstly you have no check on whether the hours and minutes stay in a reasonable range.

Then, although

Alarm.alarmRepeat(ahours, amins, asecs, theAlarm);

sets an alarm, you are not cancelling any that you previously set so several may be active.

I was planning on adding this code into the setAlarm() while statement

if(ahours < 10)
    {
     lcd.print("0");								//Lcd print "0"
     lcd.print(ahours);								//Lcd print alarm hours
    }
  else
    {
     lcd.print(ahours);								//Lcd print alarm hours
    }
    
  lcd.print(":");									//Lcd print ":"
    
  if (amins < 10)
    {
     lcd.print("0");								//Lcd Print "0"
     lcd.print(amins);								//Lcd print alarm minutes
    }
  else
    {
     lcd.print(amins);								//Lcd print alarm minutes
    }
 if(amins > 59)
    {
     ahours++;										//Alarm hours
     amins = 0;										//Alarm minutes = 0
    } 
 if(ahours > 23)
    {
     ahours = 0; 							     	//Alarm hours = 0
    }

in there. But just to see if I set it up right, I left it out

The part you talk about with the alarm is the part I feel I struggle with the most. I am confused on how to cancel previous alarms and update the values. I feel I can get every other part, but the part where the set values go into alarm and the alarm works. Thank you for your patience!

First of all, I would lose the TimeAlarms library. It looks too complicated for what you're doing.

Instead, I would put in my loop something like:

if ((hours==ahours)&&(mins==amins)&&(aready==true)) {
  //  Time for the "alarm" to do its thing!
  //  The code to ring a bell (or open a window, or however you
  //  prefer to wake up) should go here
  
  // Once we've rung the bell or opened the window or whatever,
  // then we do this:
  aready = false;
  // so the alarm doesn't do its thing twice in one minute.
}
else {
  //  Since it *isn't* time for the alarm to do its thing,
  //  we get the alarm ready for the next day, like so:
  aready = true;
  //  If you don't want the alarm to repeat every day,
  //  then get rid of this "else" statement.
}

This is very simple, and whenever you change the value of ahours or amins, that automatically changes the alarm time.
Oh, and my example code here uses one more variable, aready. That is a boolean which is used to keep the alarm from doing its thing more than once in one minute. For my code to work, you would need to declare at the beginning of your sketch:

boolean aready = true; // get the alarm ready for use

odometer:
First of all, I would lose the TimeAlarms library. It looks too complicated for what you're doing.

Instead, I would put in my loop something like:

if ((hours==ahours)&&(mins==amins)&&(aready==true)) {

//  Time for the "alarm" to do its thing!
  //  The code to ring a bell (or open a window, or however you
  //  prefer to wake up) should go here
 
  // Once we've rung the bell or opened the window or whatever,
  // then we do this:
  aready = false;
  // so the alarm doesn't do its thing twice in one minute.
}
else {
  //  Since it isn't time for the alarm to do its thing,
  //  we get the alarm ready for the next day, like so:
  aready = true;
  //  If you don't want the alarm to repeat every day,
  //  then get rid of this "else" statement.
}




This is very simple, and whenever you change the value of `ahours` or `amins`, that *automatically* changes the alarm time.
Oh, and my example code here uses one more variable, `aready`. That is a boolean which is used to keep the alarm from doing its thing more than once in one minute. For my code to work, you would need to declare at the beginning of your sketch:


boolean aready = true; // get the alarm ready for use

Alright so here is what I ran into. This is my set alarm code and I have the boolean aready defined. When I press the push button leading to digital pin 9 the alarm pops up on the screen. I can not set the alarm and the alarm will not go off.

void setAlarm()
{
  lcd.setCursor(10,1);								//Lcd set cursor(12,1)
  
  if(ahours < 10)
    {
     lcd.print("0");								//Lcd print "0"
     lcd.print(ahours);								//Lcd print alarm hours
    }
  else
    {
     lcd.print(ahours);								//Lcd print alarm hours
    }
    
  lcd.print(":");									//Lcd print ":"
    
  if (amins < 10)
    {
     lcd.print("0");								//Lcd Print "0"
     lcd.print(amins);								//Lcd print alarm minutes
    }
  else
    {
     lcd.print(amins);								//Lcd print alarm minutes
    }
 if(amins > 59)
    {
     ahours++;										//Alarm hours
     amins = 0;										//Alarm minutes = 0
    } 
 if(ahours > 23)
    {
     ahours = 0; 							     	//Alarm hours = 0
    }

	while(digitalRead(9) == LOW)
	{
	   	  lcd.setCursor(9,0);
		  lcd.print("+");
		  if(digitalRead(11) == LOW)							//Push button to change alarm hours
    		{
     			ahours++;										//Add 1 to Alarm hours
     			delay(100);									//Delay
			} 
    
  		  if(digitalRead(13) == LOW)						//Push button to change alarm mimutes
    		{
     			amins++;										//Add 1 to alarm minutes
     			delay(100);
    		}
    	
	}
    	 
  
 

	if ((hours==ahours)&&(mins==amins)&&(aready==true)) 
    	{
    		servoMain.write(160);
    		aready = false;
    	}
  	else 
  		{
  			aready = true;
  		}

I tried putting that alarm restraining code that keeps it in the 24 hour window in that while statement, but it only shows the change after I let go of the button.

What I wrote isn't for setting the alarm.

It's for using the alarm once you've set it.

In your situation, you're better off if you don't use the TimeAlarms library.
You have told us that you want to be able to change the time of an alarm.
The TimeAlarms library allows you to create alarms, but it does not allow you to change the time of an already existing alarm. I'm sure there are ways to work around this limitation, but why bother when it is this simple to create a substitute?

My example code is meant as a substitute for the TimeAlarms library.
The TimeAlarms library has certain features that are necessary for other projects. But right now, you're not working on those other projects, you're working on this project, and for this project, TimeAlarms is not the right tool for the job.

I misinterpreted the sample code! My apologies, I will go back and work again