Before we address your alarm question, you should change the sketch so all references to time are using the time libary instead of the RTC. This is because the TimeAlarms ignores the RTC once it has been set so if the Arduino time drifts from the RTC time (which it will) then the time the alarm is triggered will slowly drift from the time you display.
You can fix this by replacing th ecod eto dislay the RTC time with the digitalClockDisplay function form the TimeAlarmExample sketch (you also need the printDigits function from that example).
Once you have that code in you sketch, you can call the digitalClockDisplay function from Start1 to show the actual alarm time.
When you have that working, post the output from the serial monitor that show the times the alarms are triggered.
HI!mem
i have made changes to my code and here is the code
#include <Time.h>
#include <TimeAlarms.h>
#define PJG_DATA 5
#define INT_SLAVE 'I'
byte hourStart1 = 0;
byte minuteStart1 = 0;
AlarmID_t alarmStart1; //ID for interval Slave 1
void setup()
{
Serial.begin(9600);
setTime(8,0,0,16,7,14);
alarmStart1= Alarm.alarmRepeat(8,1,00, Start1); //==start alarm mode interval slave 1
}
void loop(){
if(Serial.available())
{
char header = Serial.read();
if (header == INT_SLAVE)
Interval();}
Serial.print("Current Date / Time: ");
digitalClockDisplay();
Alarm.delay(1000);
}
void Interval()
{
char setString[PJG_DATA];
int index = 0;
for (int i = 0; i < PJG_DATA - 1; i++)
{
char d = Serial.read();
setString[index++] = d - '0';
}
int count = index;
int element = 0;
for( index = 0; index < count; index += 2)
{
byte val = setString[index] * 10 + setString[index+1];
switch (element++){
case 0:
hourStart1 = val;
break;
case 1:
minuteStart1 = val;
break;
}
}
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.write (alarmStart1, newStart1);
Serial.println(hourStart1, DEC);
Serial.println(minuteStart1, DEC);
}
void Start1(){
Serial.println("alarm time is going to set now...");
digitalClockDisplay();
}
one problem which i am facing in this is that the time is set again and again when i run this code , and i dont want this. and when i remove this statement the code dont run. and the next problem is that when i set new alarm time by sending command serially then the alarm will turn on first on the previous alarm set then on the new...plz help me out in this
Does the Arduino have a built-in RTC, or are you using an external RTC? If external, which one and where did you get it? I've been looking for an RTC that includes both serial read/write and an alarm that I could use to drive interrupts on the Arduino.
ash124:
hi everyone !
actually i am working on a project in which i am stuck in one task ...and the task is to set the alarm time of rtc through my smart phone here is the code for this task .. #include <Time.h> #include <TimeAlarms.h> #include <virtuabotixRTC.h>
virtuabotixRTC myRTC(6, 7, smiley-cool;
int led=13;
char h=8 ;
char m=30;
char s=0;
void setup()
{
Serial.begin(9600);
pinMode(led,OUTPUT);
setTime(8,0,0,16,7,14);
myRTC.setDS1302Time(00, 00, 8, 3, 14, 7, 2014);}
void loop()
{
myRTC.updateTime();
// Start printing elements as individuals
Serial.print("Current Date / Time: ");
Serial.print(myRTC.dayofmonth);
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
Alarm.delay(1000); // wait one second between clock display
if (Serial.available() >0)
{ h= Serial.read(); //dont know how to make
m=Serial.read();// these three commands to
s=Serial.read();//work properly through proper programming command
Alarm.alarmRepeat(h,m,s, morningalarm); // alarm set through smartphone
}
else{
Serial.println('nothing have been sent');
}}
// functions to be called when an alarm triggers:
void morningalarm(){
Serial.println("Alarm: - turn lights off");
digitalWrite(led, HIGH);
}
plz do help me out in this ...how should i receive hour minute and seconds at a time serially and put them all together in alarm command so the alarm is set to a new time which is specified by the user through his smart phone
/* you need to uncomment or add the following line to TimeAlarms.h
#define USE_SPECIALIST_METHODS // define this for testing
*/
#include <Time.h>
#include <TimeAlarms.h>
#define PJG_DATA 5
#define INT_SLAVE 'I'
byte hourStart1 = 0;
byte minuteStart1 = 0;
AlarmID_t alarmStart1; //ID for interval Slave 1
void setup()
{
Serial.begin(9600);
setTime(8, 0, 0, 16, 7, 14);
alarmStart1 = Alarm.alarmRepeat(8, 1, 00, Start1); //==start alarm mode interval slave 1
setTestTime(); // just for testing - advances the clock near to the next alarm time
}
void loop() {
if (Serial.available())
{
char header = Serial.read();
if (header == INT_SLAVE)
Interval();
}
Serial.print("Current Date / Time: ");
time_t t = now();
digitalClockDisplay(t);
Alarm.delay(1000);
}
// sets the start time from a Serial message of the format:
// Ih,m\n
// where I is the header, h is the start hour, m is the start minute
// \n is the newline character
void Interval()
{
int hourStart1 = Serial.parseInt();
int minuteStart1 = Serial.parseInt();
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.free(alarmStart1); // remove the old alarm
alarmStart1 = Alarm.alarmRepeat( newStart1,Start1); // create the new alarm
Serial.print("New alarm set for ");
Serial.print(hourStart1);
Serial.print(":");
Serial.println(minuteStart1);
setTestTime(); // advance the clock to near the next alarm time
}
void Start1() {
time_t t = now();
Serial.print("alarm time is ...");
digitalClockDisplay(t);
setTestTime(); // advance the clock to near the next alarm time
}
void digitalClockDisplay(time_t t)
{
// digital clock display of the time
Serial.print(hour(t));
printDigits(minute(t));
printDigits(second(t));
Serial.println();
}
void printDigits(int digits)
{
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void setTestTime()
{
// temp function for testing
time_t t = Alarm.getNextTrigger();
if( t > now() + 10) {
setTime(t -5); // set time to 5 seconds before next trigger
Serial.println("... advancing clock ...");
}
}
I have simplified the code to read the alarm time from serial, if that is not the format you want then you can modify the Interval code to suit.
I have added a function to advance the clock to a time close to the next alarm time to make testing faster. You should remove the calls to setTestTime when you have your functionality working as you want and are ready to add the RTC code back in. You may you need to uncomment or add the following line to TimeAlarms.h to get this to compile:
#define USE_SPECIALIST_METHODS // define this for testing
If you want to cancel the old alarm time when a new alarm is set then you need to free the alarm. See the Interval code for an example.
I hope this gives you enough information to enable you to continue making progress.
Hi Mem!
i have made changes to my code which you have suggested me and the problem solved by putting one statement in my code that was
Alarm.free(alarmStart1); // remove the old alarm
thanks alot for your help mem
now the next problem which i am facing is that i was using RTC DS1302 first in my project but you have told me that RTC library doesn't work properly with the time alarm library so i removed the RTC DS1302 from arduino and also removed the library for rtc from my code so the time alarm library work properly
and now the problem which i am facing due to their removal is that when i try to compile the code the clock starts from 08:00 o'clock every time.but in my project i need to set the alarm time of a real time clock so that if i remove the arduino from power, still the real time clock should maintain its time and when i read the time from serail monitor it should display the new time like 09:00 o'clcok if i give power to the arduino after 1 o'clock
in this way i should be able to set the alarm time properly and also i dont have to configure the time again if my arduino doesn't recieve power
what i have to do is to just give power to arduino and and set the alarm time via bluetooth.
To sort out this problem i think i have to use a real time clock like RTC DS1302 or DS1307,or i have to include the code for set time through serial command i-e
void setup() {
Serial.begin(9600);
while (!Serial) ; // Needed for Leonardo only
pinMode(13, OUTPUT);
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
}
void loop(){
if (Serial.available()) {
processSyncMessage();
}
if (timeStatus()!= timeNotSet) {
digitalClockDisplay();
}
if (timeStatus() == timeSet) {
digitalWrite(13, HIGH); // LED on if synced
} else {
digitalWrite(13, LOW); // LED off if needs refresh
}
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void processSyncMessage() {
unsigned long pctime;
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
if(Serial.find(TIME_HEADER)) {
pctime = Serial.parseInt();
if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
setTime(pctime); // Sync Arduino clock to the time received on the serial port
}
}
}
time_t requestSync()
{
Serial.write(TIME_REQUEST);
return 0; // the time will be sent later in response to serial mesg
}
but according to this code i have to set time serially by sending a command which contain a unix time , and its quite difficult for every one to set this unix time. so there should be some way to set the time through simple way like one should set time by sending command 09:00
one more thing which i wanna ask from you mem i-e if i dont use external rtc clock with arduino then at that time does arduino use the internal built in clock and does it function the same as that of external rtc clock ???
please mem suggest me something thet what should i do now ...
mem here is my whole code ..
#include <Time.h>
#include <TimeAlarms.h>
#define PJG_DATA 5
#define INT_SLAVE 'I'
byte hourStart1 = 0;
byte minuteStart1 = 0;
AlarmID_t alarmStart1; //ID for interval Slave 1
void setup()
{
Serial.begin(9600);
setTime(8, 0, 0, 16, 7, 14);
alarmStart1 = Alarm.alarmRepeat(8, 1, 00, Start1); //==start alarm mode interval slave 1
}
void loop() {
if (Serial.available())
{
char header = Serial.read();
if (header == INT_SLAVE)
Interval();
}
Serial.print("Current Date / Time: ");
time_t t = now();
digitalClockDisplay(t);
Alarm.delay(1000);
}
void Interval()
{
char setString[PJG_DATA];
int index = 0;
for (int i = 0; i < PJG_DATA - 1; i++)
{
char d = Serial.read();
setString[index++] = d - '0';
}
int count = index;
int element = 0;
for( index = 0; index < count; index += 2)
{
byte val = setString[index] * 10 + setString[index+1];
switch (element++){
case 0:
hourStart1 = val;
break;
case 1:
minuteStart1 = val;
break;
}
}
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.free(alarmStart1); // remove the old alarm
alarmStart1 = Alarm.alarmRepeat( newStart1,Start1); // create the new alarm
Serial.print("New alarm set for ");
Serial.print(hourStart1);
Serial.print(":");
Serial.println(minuteStart1);
}
void Start1() {
time_t t = now();
Serial.print("alarm time is ...");
}
void digitalClockDisplay(time_t t)
{
// digital clock display of the time
Serial.print(hour(t));
printDigits(minute(t));
printDigits(second(t));
Serial.println();
}
void printDigits(int digits)
{
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
Although its easier using a DS1307 RTC because the code to set the arduino clock from the RTC is already built into the DS1307RTC library, you can add the code you need to read your RTC into your sketch.
To do this, you need to include the virtuabotixRTC library in your sketch and then in setup call the setTime method:
When using the time and time alarm libraries, the purpose of the DS1302 is to set the arduino time library at startup. After that, all access to time should be using the time library, not the DS1302. The reason for this was given in an earlier post.
The code to set the time was in my previous post. I suggest you go back to the code you posted this morning and add into setup the code from my post to set the arduino time.
hi mem
i have tried the code as recommended by you but failed to sort out my problem so i have made another code which is using RTCDS1307 as recommended by you but still my problem has not solved here is my code
#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527
#include <Time.h>
#include <TimeAlarms.h>
#define PJG_DATA 5
#define INT_SLAVE 'I'
byte hourStart1 = 0;
byte minuteStart1 = 0;
AlarmID_t alarmStart1; //ID for interval Slave 1
int led=13;
void setup(){
Wire.begin();
Serial.begin(9600);
setDateTime(); //MUST CONFIGURE IN FUNCTION
alarmStart1 = Alarm.alarmRepeat(8, 1, 00, Start1); //==start alarm mode interval slave 1
}
void loop(){
printDate();
delay(1000);
if (Serial.available())
{
char header = Serial.read();
if (header == INT_SLAVE)
Interval();
}
printDate();
delay(1000);
//Alarm.delay(1000);
}
void Interval()
{
char setString[PJG_DATA];
int index = 0;
for (int i = 0; i < PJG_DATA - 1; i++)
{
char d = Serial.read();
setString[index++] = d - '0';
}
int count = index;
int element = 0;
for( index = 0; index < count; index += 2)
{
byte val = setString[index] * 10 + setString[index+1];
switch (element++){
case 0:
hourStart1 = val;
break;
case 1:
minuteStart1 = val;
break;
}
}
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.free(alarmStart1); // remove the old alarm
alarmStart1 = Alarm.alarmRepeat( newStart1,Start1); // create the new alarm
Serial.print("New alarm set for ");
Serial.print(hourStart1);
Serial.print(":");
Serial.println(minuteStart1);
// setTestTime(); // advance the clock to near the next alarm time
}
void Start1() {
time_t t = now();
Serial.print("alarm time is ...");
}
void setDateTime(){
byte second = 00; //0-59
byte minute = 24; //0-59
byte hour = 12; //0-23
byte weekDay = 3; //1-7
byte monthDay = 12; //1-31
byte month = 8; //1-12
byte year = 14; //0-99
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(zero); //stop Oscillator
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(weekDay));
Wire.write(decToBcd(monthDay));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(zero); //start
Wire.endTransmission();
}
byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}
void printDate(){
// Reset the register pointer
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(zero);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
int second = bcdToDec(Wire.read());
int minute = bcdToDec(Wire.read());
int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
int monthDay = bcdToDec(Wire.read());
int month = bcdToDec(Wire.read());
int year = bcdToDec(Wire.read());
//print the date EG 3/1/11 23:59:59
Serial.print(month);
Serial.print("/");
Serial.print(monthDay);
Serial.print("/");
Serial.print(year);
Serial.print(" ");
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
}
i have also attached the pic of serial monitor please check this out and help me out in this
Did you get the RTC working with the time library before trying to add the alarms?
If not, start with the example sketches that come with the time library.
running the timeRTC sketch will tell you if you have the RTC connected up and working correctly. You can run the TimeRtcSet example sketch to set the RTC time if that is not already set.
when you have the sketch displaying the correct time, you can add in code to set alarms.. All you should need to add to the example code to get an alarm working is :
the include statement for the TimeAlarm library #include <TimeAlarms.h>
a statement in setup to set an alarm time ( but use a time close to the current time):
alarmStart1 = Alarm.alarmRepeat(8, 1, 0, Start1);
an alarm handler function , for example:
void Start1() {
Serial.print("alarm time is ... ");
digitalClockDisplay();
}
yes mem i have tried the TIME RTC code but my RTC DS1307 is not working with the time library due to which i have used another program which i have posted earlier , but for the confirmation i have tried the TIME RTC code again ..which is given below ..
/*
* TimeRTC.pde
* example code illustrating Time library with Real Time Clock.
*
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop()
{
if (timeStatus() == timeSet) {
digitalClockDisplay();
} else {
Serial.println("The time has not been set. Please run the Time");
Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
Serial.println();
delay(4000);
}
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
and i get the following errors ..
TimeRTC.pde: In function 'void setup()':
TimeRTC:14: error: 'RTC' was not declared in this scope
and why the code which i have posted earlier is not working with the time library mem... need your suggestion please...
Have you installed the DS1307RC library in the libraries directory? Although it can be used with the Time and TimeAlarms libraries, it is a stand-alone library and needs to be installed in the libraries folder.
yes mem i have installed that library but its was not working at that time but now its working but still my problem has not solved i have tried the following code from example, in which the time has been set to 17:45
/*
* TimeRTC.pde
* example code illustrating Time library with Real Time Clock.
*
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <TimeAlarms.h>
#define PJG_DATA 5
#define INT_SLAVE 'I'
byte hourStart1 = 0;
byte minuteStart1 = 0;
AlarmID_t alarmStart1; //ID for interval Slave 1
int led=13;
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
alarmStart1 = Alarm.alarmRepeat(8, 1, 00, Start1);
}
void loop()
{
if (timeStatus() == timeSet) {
digitalClockDisplay();
} else {
Serial.println("The time has not been set. Please run the Time");
Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
Serial.println();
delay(4000);
}
delay(1000);
if (Serial.available())
{
char header = Serial.read();
if (header == INT_SLAVE)
Interval();
}
}
void Interval()
{
char setString[PJG_DATA];
int index = 0;
for (int i = 0; i < PJG_DATA - 1; i++)
{
char d = Serial.read();
setString[index++] = d - '0';
}
int count = index;
int element = 0;
for( index = 0; index < count; index += 2)
{
byte val = setString[index] * 10 + setString[index+1];
switch (element++){
case 0:
hourStart1 = val;
break;
case 1:
minuteStart1 = val;
break;
}
}
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.free(alarmStart1); // remove the old alarm
alarmStart1 = Alarm.alarmRepeat( newStart1,Start1); // create the new alarm
Serial.print("New alarm set for ");
Serial.print(hourStart1);
Serial.print(":");
Serial.println(minuteStart1);
// setTestTime(); // advance the clock to near the next alarm time
}
void Start1() {
time_t t = now();
Serial.print("alarm time is ...");
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
i also attached the picture of serial monitor, please check it
void Interval()
{
char setString[PJG_DATA];
int index = 0;
for (int i = 0; i < PJG_DATA - 1; i++)
{
char d = Serial.read();
setString[index++] = d - '0';
}
Rubbish! Just because ONE character has arrived does NOT mean that ALL characters have arrived.
you can simplify the code to read alarm times by using the Arduino parseInt construct. Something like the following should get you going in the right directon:
void Interval()
{
// here if header has been detected
int hourStart1 = Serial.parseInt();
int minuteStart1 = Serial.parseInt();
time_t newStart1 = AlarmHMS (hourStart1, minuteStart1, 0);
Alarm.free(alarmStart1); // remove the old alarm
alarmStart1 = Alarm.alarmRepeat( newStart1,Start1); // create the new alarm
Serial.print("New alarm set for ");
Serial.print(hourStart1);
Serial.print(":");
Serial.println(minuteStart1);
// setTestTime(); // advance the clock to near the next alarm time
}
hi mem!
again i need your help in my alarm code .. mem in your earlier post u have suggested to use the following statements in my alarm program
int hourStart1 = Serial.parseInt();
int minuteStart1 = Serial.parseInt();
i have used this statement in my code but this is working only with the serial.read() not with sms.read()..plz tell me how should i set the alarm time through msg in the same way as i have set the alarm time using serial command .. i have attached the code of my alarm ..
Are we to guess what sms is an instance of? Does that class derive from Stream? If so, you can use sms.parseInt(). If not, you'll need to collect the data in a container of some sort (NULL terminated char array is best). Then, parse the container, looking for the start and end of the value. The atoi() function may be useful.