I have used TimeAlarms successfully on another project where I alarm 5 times a day, every day. This project I want to alarm on certain days as well as every day, however, for some reason, it has been alarming inappropriately on the incorrect day (as well as on the correct day). I've exhausted my troubleshooting capability, so I'd appreciate some help.
I've made a full featured plant waterer that waters 2 separate plants at different times as well providing a means to water manually. Additionally, I can place it in Auto made that then reads sensors to determine if it needs watering, so it will then water on an as needed basis. My problem here is in the Timer mode. It shows that the correct time is set, including the day, however it will water at the correct time but not the correct day. Additionally, I am using ARDUINO 0022 IDE. I have not taken the time to learn how to modify Time.h to use with the version 1.0 IDE. I'm using Sparkfun's Real Time Clock module.
Here's my code with only the salient lines (out of a total of 1000) reprinted. I am not a proficient coder so I'm sure it can be done more efficiently.
Can anyone tell why it is not working properly? It does not fail consistently so I'm having difficulty troubleshooting it.
/* USE ARDUINO 0022 ONLY WITH THIS SKETCH */
#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h> //For DS1037
#define DS1307_ADDRESS 0x68//For DS1037
timeDayOfWeek_t Water1aDay = dowWednesday; //Time for first watering for Plant1 -Day
int Water1aHr = 8; //Time for first watering for Plant1 -HR
int Water1aMin = 00; //Time for first watering for Plant1 - Min
timeDayOfWeek_t Water1bDay = dowSaturday; //Time for second watering for Plant1 -Day
int Water1bHr = 20; //Time for second watering for Plant1 -HR
int Water1bMin = 00; //Time for second watering for Plant1 - Min
timeDayOfWeek_t Water2aDay = dowWednesday; //Time for first watering for Plant2 -Day
int Water2aHr = 9; //Time for first watering for Plant2 -HR
int Water2aMin = 00; //Time for first watering for Plant2 - Min
timeDayOfWeek_t Water2bDay = dowSaturday; //Time for second watering for Plant2 -Day
int Water2bHr = 21; //Time for second watering for Plant2 -HR
int Water2bMin = 00; //Time for second watering for Plant2 - Min
// Convert binary coded decimal to normal decimal numbers for DS1037
byte bcdToDec(byte val) {
return ( (val/16*10) + (val%16) );
}
unsigned long asec = millis();
unsigned long lastOn = millis();
unsigned long lastOff = millis();
unsigned long timer=millis(); //timer for returning to top
void setup()
{
Serial.begin(9600);
Wire.begin();
//setDateTime(); //sets time on DS1037 Comment out this after
//running one time. Set time in Subroutine at end of code
// Reset the register pointer
Wire.beginTransmission(DS1307_ADDRESS);
Wire.send(0);
Wire.endTransmission();
//Get time from DS1037
Wire.requestFrom(DS1307_ADDRESS, 7);
int asecond = bcdToDec(Wire.receive());
int aminute = bcdToDec(Wire.receive());
int ahour = bcdToDec(Wire.receive() & 0b111111); //24 hour time
int aweekDay = bcdToDec(Wire.receive()); //1-7 -> sunday - Saturday
int amonthDay = bcdToDec(Wire.receive()); //1-31??
int amonth = bcdToDec(Wire.receive());
int ayear = bcdToDec(Wire.receive());
int StartHr = ahour;
int StartMn = aminute;
int StartSe = asecond;
int StartMth = amonth;
int StartWeek = aweekDay;
int StartDay = amonthDay;
int StartYr = ayear;
// Set up Time.h to current time based on DS1037
setTime(StartHr,StartMn,StartSe,StartDay,StartMth,StartYr);
//From TimeAlarm example:(changed header as described in readme
//to include 20 or 23 alarms instead of the 6 in the original file
Alarm.alarmRepeat(Water1aDay,Water1aHr,Water1aMin,0, Timer1); // First watering per week
Alarm.alarmRepeat(Water1bDay,Water1bHr,Water1bMin,0, Timer1); // Second watering per week
Alarm.alarmRepeat(Water2aDay,Water2aHr,Water2aMin,0, Timer2); // First watering per week
Alarm.alarmRepeat(Water2bDay,Water2bHr,Water2bMin,0, Timer2); // Second watering per week
//Check moisture level 3X per day for Auto Mode at 10/11AM, 2/3PM and 6/7PM
Alarm.alarmRepeat( 10,0,0, Auto1); // First check
Alarm.alarmRepeat(14,0,0, Auto1); // Second check
Alarm.alarmRepeat(18,0,0, Auto1); // third check
Alarm.alarmRepeat( 11,0,0, Auto2); // First check
Alarm.alarmRepeat(15,0,0, Auto2); // Second check
Alarm.alarmRepeat(19,0,0, Auto2); // third check
//The following alarm code has not worked properly so I have commented it out
//reset internal clock once a week since internal clock isn't as accurate as DS1037
//Alarm.alarmRepeat(dowSunday, 0,0,0, SetInternalClock); // Change time to = DS1037 every sunday at midmight
//LED blinks faster just before watering time
Alarm.alarmRepeat(Water1aDay,Water1aHr,Water1aMin-5,0, LEDblk5); // Fastest blink rate
Alarm.alarmRepeat(Water1bDay,Water1bHr,Water1bMin-5,0, LEDblk5); // Fastest blink rate
Alarm.alarmRepeat(Water2aDay,Water2aHr,Water2aMin-5,0, LEDblk5); // Fastest blink rate
Alarm.alarmRepeat(Water2bDay,Water2bHr,Water2bMin-5,0, LEDblk5); // Fastest blink rate
}
void loop()
{
/***************************************************************/
Alarm.delay(100); //Check alarms
digitalClockDisplay(); //display clock on Serial Port
//Check if switch is off;
if(digitalRead(AutoMode) && digitalRead(TimerMode) == 1) //is switch is off? ie both open
// 1=open. 0=grounded
{
OFF();
}
// Is a pump active?
if (AlarmFlag1 ==1) //If 1 is active, go to sub to see if time to shut off
{
Timer1();
}
if (AlarmFlag2 ==1) //If 2 is active, go to sub to see if time to shut off
{
Timer2();
}
if (ActiveAutoMode1 ==1) //If auto is active, go to sub to see if time to shut off
{
Auto1();
}
if (ActiveAutoMode2 ==1) //If auto is active, go to sub to see if time to shut off
{
Auto2();
}
} //end Void loop
// Timer1 Mode subroutine. Sub is called when a timer alarm is activated
void Timer1()
{
//Is it in Timer Mode? If not, skip to end
if(digitalRead(TimerMode) == LOW)
{
//Timer mode operation here
if (AlarmFlag1 == 0) // is this the first time?
{
AlarmFlag1 = 1; //Alarm just occured
TimeOn1 = millis(); //start timer
blkOn = 750; //slow LED blink
blkOff = 750; //slow LED blink
digitalWrite(valve1,HIGH); //turn the valve on
digitalWrite(pump,HIGH); //turn on pump
}
else //if not the first time
{
if ( millis() - pumpTime1>TimeOn1 ) // is it time to turn off?
{
blkOn = 0; //no LED blink
blkOff = 0; //no LED blink
digitalWrite(ledPin, HIGH); //turn on LED
digitalWrite (pump,LOW); //turn pump off
digitalWrite(valve1,LOW); //turn off valve
AlarmFlag1 = 0; //turn off flag
TimeOn1 = 0; //reset timer
}
}
} //in Timer Mode?
} //end of timer1
/**************************************************************/
// Timer2 Mode subroutine
void Timer2()
{
/* Same as Timer1() */
}
void setDateTime(){//for setting time on DS1037 from bildr.org/?s=ds1307
Serial.println("setDateTime called");
byte second = 0; //0-59
byte minute = 4; //0-59
byte hour = 18; //0-23
byte weekDay = 3; //1-7 ALWAYS SET ACCORDING TO monthDay
byte monthDay = 14; //1-31
byte month = 4; //1-12
byte year = 15; //0-99
Wire.beginTransmission(DS1307_ADDRESS);
Wire.send(0); //stop Oscillator
Wire.send(decToBcd(second));
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(weekDay));
Wire.send(decToBcd(monthDay));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.send(0); //start
Wire.endTransmission();
}