Using the Time library what would be the best way ofsetting the time using menus on an lcd?
I'll have one menu for the hour and one menu for the minute
And how could i compared a set alarm time with the time 'now'
Basically, i want to manually set the clock time when i turn the arduino on and then set an On time and an Off time for running a thermostat.
So i need to compare 'now' with On and Off to determine whether to perform whatever action i need.
i tried starting out with this time business by having the time set (just using the time set function with a set of values bunged in) and then shown on the screen, i can't even do that!
(or put it out via serial)
there is a companion library in the Time download called TimeAlarm that provides the capability to set on and off times. Perhaps that does what you want.
yes i subsequently discovered that and have been experimenting.
I'm thinking of having the 'on' alarm in the main loop function and the 'off 'alarm inside the loop that the 'on' alarm triggers.
So that while it is performing the action needed for alarmOn, if alarmOff triggers it then exits the loop and returns to normal programming.
Alarms are processed in the order they are triggered and subsequent alarms are deferred until the active alarm completes.
This prevents error conditions where an 'On' alarm is in the middle of processing and if interrupted by an 'Off' alarm, would try and resume handling the 'On' code even if the alarm was now off. (This also results in more memory efficient code than if the simultaneous alarms where stacked.)
You can get the functionality you describe by using a flag that is set by the On and Off alarms that controls what your loop code does.
Your loop code can monitor the state of the flag and call an 'On' processing function if its set. The On processing function would periodically check the flag to see if the 'Off' alarm had triggered and exit (after doing any necessary cleanup) if so.
However, if all you want to do is turn a thermostat on or off (as described in your first post) then you could do this directly within the alarm functions.
I've included the bits relevant, obviously i've declared all the variables used. I have the alarms setting a flag, i need to test the state of this flag somewhere during the boilerOn function so that if the off time comes along the code stops running the boiler
void loop()
{
if (programSet == 1)
{
Alarm.alarmRepeat(onHour,onMin,0, onNow); // daily alarm to start scheduled program and set Hour and Minute
Alarm.alarmRepeat(offHour,offMin,0, offNow); // alarm to turn program off
}
}
void onNow()
{
progIsOn = 1;
boilerOn(waterrequest);
}
void offNow()
{
progIsOn = 0;
}
void boilerOn(char* waterrequest)
{
char* newtemp;
char* oldtemp;
readsensors();
oldtemp = shower;
while (oldtemp < waterrequest)
{
//delay(1000);
displaytemps();
lcd.writeString(10, 2, "HEATING", MENU_NORMAL);
digitalWrite(relayPin, HIGH);
newtemp = shower;
oldtemp = newtemp;
}
current_menu_num = 0;
current_menu_item = 0;
}
I am not sure what your programSet code is intended to do but you do not need to repeatedly set the alarms.
It would be easier to make suggestions on your code if you described in words the full logic you want to implement. However the sketch below is perhaps a little closer to what you have in mind
void loop()
{
if (programSet == 1)
{
Alarm.alarmRepeat(onHour,onMin,0, onNow); // daily alarm to start scheduled program and set Hour and Minute
Alarm.alarmRepeat(offHour,offMin,0, offNow); // alarm to turn program off
}
if(progIsOn)
{
boilerOn(waterrequest);
}
}
void onNow()
{
progIsOn = 1;
boilerOn(waterrequest);
}
void offNow()
{
progIsOn = 0;
}
void boilerOn(char* waterrequest)
{
char* newtemp;
char* oldtemp;
readsensors();
oldtemp = shower;
while (oldtemp < waterrequest)
{
if (progIsOn == 0)
{
// perhaps add code to clear the lcd display and indicate that heating is turned off
return; // return to loop
}
//delay(1000);
displaytemps();
lcd.writeString(10, 2, "HEATING", MENU_NORMAL);
digitalWrite(relayPin, HIGH);
newtemp = shower;
oldtemp = newtemp;
}
current_menu_num = 0;
current_menu_item = 0;
}
thanks for that.
I misunderstood the usage of the alarm code. i thought it had to be repeatedly checked against to see if the time had been hit yet.
programSet is a boolean variable that i can toggle to decide if i want the programming feature on or off, some days i might want to time the hot water and other days i might not bother (might be on holiday, etc...)
logic should be this:
if the program feature is on then run the alarms
when alarmOn time is hit change program flag to show the program is running and run the heating loop
when the alarmOff time is hit stop the heating loop (unless it has been previously stopped by hitting the required temperature)
The code below is closer to what you want. Note that Alarm.delay is called in loop and in the boilerOn function - this services the Alarm triggers. You can set the delay to 0 if you want, but in the code you posted it may be better to have the refresh of the lcd set to something like 100ms.
void setup()
{
Alarm.alarmRepeat(onHour,onMin,0, onNow); // daily alarm to start scheduled program and set Hour and Minute
Alarm.alarmRepeat(offHour,offMin,0, offNow); // alarm to turn program off
// other setup stuff here
}
void loop()
{
if( programSet && progIsOn)
{
boilerOn(waterrequest);
}
Alarm.delay(100); //Alarm.delay() services the alarm triggers
// Alarm precision is one second so any value less than 1000 ms is ok
}
void onNow()
{
progIsOn = true;
if (programSet)
{
boilerOn(waterrequest);
}
}
void offNow()
{
progIsOn = false;
}
void boilerOn(char* waterrequest)
{
char* newtemp;
char* oldtemp;
readsensors();
oldtemp = shower;
while (oldtemp < waterrequest)
{
if (progIsOn )
{
// perhaps add code to clear the lcd display and indicate that heating is turned off
return; // return to loop
}
displaytemps();
lcd.writeString(10, 2, "HEATING", MENU_NORMAL);
digitalWrite(relayPin, HIGH);
newtemp = shower;
oldtemp = newtemp;
Alarm.delay(100); // function added to service alarm triggers
}
current_menu_num = 0;
current_menu_item = 0;
}
I find all this hours and minutes business confusing, I find it easier to work in native 'Milliseconds since start' 3.6 million for an hour and 86400000 in a day