erratic behavior with alarms

After uploading and setting the RTC to 15:59:55, the alarms are likely to appear on the serial monitor starting at 16:00:00. At 16:10:00, the SM shows only the time. If I reset the RTC to 15:59:55, the SM shows nothing but the time at 16:00:00.

I have a similar set of alarms for every hour of the day but removed most of them for simplicity. When all alarms were installed, when I reset the RTC to 15:59:55 the SM would sometimes immediately spit out a bunch of alarms and when 16:00:00 rolled around only the time appeared.

I thought it must be a bad UNO but I get the same thing with a new Uno.
I’m trying to automate calcium hydroxide and food dosage to my fish tank.

#include <Time.h>
#include <TimeAlarms.h>
#include <DS3232RTC.h>
#include <Wire.h> 
 
long secondsInMs(int s){ 
  return s*1000L;            //values will be expressed in seconds

}

 long minutesInMs(int m){ 
  return m*60000L;           //values will be expressed in minutes 
}
int DryFood = 7;
int RpumpA = 8;
int RpumpB = 9;
int KalkStir = 10;
int KalkDose = 11;
int FoodStir = 12;
int FoodDose = 13;

void setup() {
  Serial.begin(9600);

  pinMode(DryFood, OUTPUT);
  pinMode(RpumpA, OUTPUT);
  pinMode(RpumpB, OUTPUT);
  pinMode(KalkStir, OUTPUT);
  pinMode(KalkDose, OUTPUT);
  pinMode(FoodStir, OUTPUT);
  pinMode(FoodDose, OUTPUT);
  
 
  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");      
  
                                                              // create the alarms                                                         
  

 Alarm.alarmRepeat(16, 0, 0, StopRpumpAAlarm);                    //Stop return pumps
  Alarm.alarmRepeat(16, 0, 1, StopRpumpBAlarm);

  Alarm.alarmRepeat(16, 0, 2, FoodStirAlarm);
  Alarm.alarmRepeat(16, 0, 17, FoodDoseAlarm);                  //Dose frozen food at 4:00 PM
  Alarm.alarmRepeat(16, 0, 21, StopFoodDoseAlarm);
  Alarm.alarmRepeat(16, 0, 22, StopFoodStirAlarm);

  Alarm.alarmRepeat(16, 0, 27, KalkStirAlarm);
  Alarm.alarmRepeat(16, 0, 34, KalkDoseAlarm);
  Alarm.alarmRepeat(16, 0, 46, StopKalkDoseAlarm);              //kalk at 4:00 PM
  Alarm.alarmRepeat(16, 1, 26, StopKalkStirAlarm);

  Alarm.alarmRepeat(16, 10, 0, StartRpumpAAlarm);                    //Start return pumps after a 10 minute pause
  Alarm.alarmRepeat(16, 10, 1, StartRpumpBAlarm);

  
 }

void loop()

{

  adjustRTC();                                                      //remove comments if adjustment required for debugging 

  
 digitalClockDisplay();
  Alarm.delay(1000);                                                 // wait one second between clock display
}
 

void StopRpumpBAlarm()                                               // functions to be called when an alarm triggers:
{  
   
 digitalWrite(RpumpB, LOW);
 Serial.println("stop return pump B");
}
                                                
                                                  

void StartRpumpBAlarm() 
{  
   
 digitalWrite(RpumpB, HIGH);
 Serial.println("run return pump B");
}


 void StopRpumpAAlarm()                                                
{  
   
 digitalWrite(RpumpA, LOW);
 Serial.println("stop return pump A");
}
                                                
                                                  

void StartRpumpAAlarm() 
{  
   
 digitalWrite(RpumpA, HIGH);
 Serial.println("run return pump A");
}

void StopDryFoodAlarm() 
{  
   
 digitalWrite(DryFood, LOW);
 Serial.println("stop feeding dry food");
}
                                                 
                                                  
void StartDryFoodAlarm() 
{  
   
 digitalWrite(DryFood, HIGH);
 Serial.println("feed dry food");
}

void KalkStirAlarm() 
{  
   
 digitalWrite(KalkStir, HIGH);
 Serial.println("stirring kalk");
}

void KalkDoseAlarm() 
{   
digitalWrite(KalkDose, HIGH);
Serial.println("dosing kalk");
}

void StopKalkDoseAlarm() 
{  
  
digitalWrite(KalkDose, LOW);
Serial.println("stopped dosing kalk");
}

void StopKalkStirAlarm() 
{   
digitalWrite(KalkStir, LOW);
Serial.println("stopped stirring kalk");
}


void FoodStirAlarm() 
{  
   
digitalWrite(FoodStir, HIGH);
Serial.println("stir food");
}

void StopFoodStirAlarm() 
{  
  
digitalWrite(FoodStir, LOW);
Serial.println("stopped stirring food");
}

void FoodDoseAlarm() 
{  
   
digitalWrite(FoodDose, HIGH);
Serial.println(" dosing food");
}

void StopFoodDoseAlarm() 
{  
   
digitalWrite(FoodDose, LOW);
Serial.println("stopped dosing food");
}

 

 void digitalClockDisplay()               // digital clock display of the time
{
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void printDigits(int digits)
{
  Serial.print(":");
  if (digits < 10)
  Serial.print('0');
  Serial.print(digits);
}
void adjustRTC()
{
  // check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
  if (Serial.available() >= 12)
  {
    time_t t;
    tmElements_t tm;
    // note that the tmElements_t Year member is an offset from 1970,
    // but the RTC wants the last two digits of the calendar year.
    // use the convenience macros from the Time Library to do the conversions.
    int y = Serial.parseInt();
    if (y >= 100 && y < 1000)
      //Serial << F("Error: Year must be two digits or four digits!") << endl;
      Serial.println("Error: Year must be two digits or four digits!");
    else {
      if (y >= 1000)
        tm.Year = CalendarYrToTm(y);
      else    // (y < 100)
        tm.Year = y2kYearToTm(y);
      tm.Month = Serial.parseInt();
      tm.Day = Serial.parseInt();
      tm.Hour = Serial.parseInt();
      tm.Minute = Serial.parseInt();
      tm.Second = Serial.parseInt();
      t = makeTime(tm);
      RTC.set(t);        // use the time_t value to ensure correct weekday is set
      setTime(t);
      Serial.println("RTC time adjusted.");
      // dump any extraneous input
      while (Serial.available() > 0) Serial.read();
    }
  }
}

I think you’re confusing the timeAlarms library with your testing method of setting the clock back.
If you look in the library code in updateNextTrigger you’ll see that it sets daily triggers to the next day, or at least that’s what this piece suggests it’s doing:

        //if this is a daily alarm
        if (value + previousMidnight(now()) <= time) {
          // if time has passed then set for tomorrow
          nextTrigger = value + nextMidnight(time);

So I suspect that if the alarm has fired and you set the clock time back, the library is still holding state that tells it that the alarm for today is already done.

Thanks wildbill but what about the alarms to turn pumps back on at 16:10:00 not showing up?

I have not used that library, so pure conjecture, but I suspect that it's related - your alarms are set when you have used network time to set the clock. If you then adjust it manually, I'm not surprised that alarms misbehave.

I'd suggest that you manually set the time for testing in setup before the alarms are created and run your test that way. At least it'll help establish whether my suggestion holds water.

edit: grammar.

I highlighted the { after void setup so the corresponding } would also be highlighted and didn't see where I could set time in setup.

Where to do it? Right before this line:

    // create the alarms

How? Either populate a tmElements_t struct with constants and use it to set the time as you do in your adjustRTC routine (preferable as it takes adjustRTC out of consideration) or wait until Serial.available has enough characters and call adjustRTC.

I googled tmElements_t struct and will work on inserting it either later today or tomorrow. Thanks.

I'm not certain what you are attempting to do. Why do you want alarms to repeat when the clock is reset? You could double dose or repeat actions which should only run once.

With the next trigger management, the Time Alarms library is designed to not retrigger an alarm which has been fired, and then the time is adjusted back. There are times when this could happen without your intervention based on the sync interval and the mismatch between the RTC and the system clock.

If you are using a DS3231 it should not need frequent resetting. Resetting can certainly be done in set up, as well as in loop if you want to pause the program until the data entered. You could also use a separate program to set the RTC.

what about the alarms to turn pumps back on at 16:10:00 not showing up?

I don't understand this. The pumps are set to turn off at 16:00:00 and 16:00:01. Are you saying that if the time is 16:05:00 and you reset to 15:59:55 the 16:10:00 alarm to turn them back on does not trigger? What if you set back to 16:01:00?If future alarms do not trigger after an rtc reset we need to focus on this, and not the behaviour of past alarms.

I think it's a need to test the alarms without waiting 24 hours to ensure they're all working.

There is a limit to how many alarms you can create using TimeAlarms but it can be increased

From the TimeAlarms readme.txt

Q: How many alarms can be created? A: Up to six alarms can be scheduled. The number of alarms can be changed in the TimeAlarms header file (set by the constant dtNBR_ALARMS, note that the RAM used equals dtNBR_ALARMS * 11)

I think it’s a need to test the alarms without waiting 24 hours to ensure they’re all working.

For debug in this mode, the Arduino needs to go through a reset to restart the Time Alarms.

As suggested, move the RTC time setting into setup() ahead of the code setting up the alarms.

If Salty Joe want to use the keyboard in setup, he’ll need to use some blocking code like this

Serial.println("Enter time setting: yy,m,d,h,m,s and press enter");
while(Serial.available()<12) {}//wait until all setting information is in buffer
adjustRTC();

First of all, thanks very much all you guys for taking a look at this.

I'm not hooked up to pumps yet, just trying to get things right according to the serial monitor. I didn't realize their is a memory for alarms.

I also had no idea only 6 alarms could be scheduled. I have 12 alarms for the single hour in the shortened sketch I posted. That explains why only the first 6 alarms appear on the SM. I had a number of alarms set for every hour for a total of 152 alarms. :o

I assume I'm asking too much of Arduino and need to start over with my dosing plan.

Could the RTC be used for a single daily time alarm and then use block code to dose every hour? The idea is to use the RTC to set time every day. A few minutes drift in a day is completely tolerable-the accumulative effect over weeks and months would not be good.

I also had no idea only 6 alarms could be scheduled. I have 12 alarms for the single hour in the shortened sketch I posted. That explains why only the first 6 alarms appear on the SM. I had a number of alarms set for every hour for a total of 152 alarms.

In TimeAlarms.h find this line and modify it to your number of alarms. Make sure you save the changed library file.

#define dtNBR_ALARMS 6   // max is 255

Note,the RAM used equals dtNBR_ALARMS * 11. I don't think you will be able to manage 152 alarms unless you have a Mega. Even then, I think it's better to modify the approach.

You can manage your alarms in ways to reduce the number. For example, say you have 24 instances of Alarm.alarmRepeat() to run at 10 minutes past every hour to turn a pump ON. It looks like you would might also have 24 instances of an alarm to turn the pump off 5 minutes later.

You should be able to replace them all with an .alarmOnce(), and each time it triggers, you can create a new alarmOnce().

Here's the idea for running a pump every hour. Set up some global time variables for the alarm

////set starting time for first turn on
byte pumpHour = 10;
byte pumpMinute = 10;
byte pumpSecond = 0; 
byte pumpState = 0; //0==off 1==on

Set up an alarm

Alarm.alarmOnce(pumpHour,pumpMinute, pumpSecond, runPump);

Call this alarm function

void runPump()
{
  if (pumpState == 0)//pump is off
  {
    //turn pump on digitalWrite()
    pumpState = 1;
    pumpMinute += 5; // next alarm in 5 minutes to turn pump off
    //set next alarm 
    Alarm.alarmOnce(pumpHour, pumpMinute, pumpSecond, runPump);
  }

  if (pump state == 1) //pump is on
  {
    //turn pump off digitalWrite()
    pumpState = 0;
    pumpMinute -= 5;
    pumpHour += 1;
    if (pumpHour == 24)
    {
      pumpOnHour = 0;
    }
    Alarm.alarmOnce(pumpOnHour, pumpOnMinute, pumpOnSecond, runPump);
  }

Why are you using TimeAlarms in the first place ? Why not read the time from the RTC about every second and test the hour and minute data directly to see whether it is time to trigger something ?

Why are you using TimeAlarms in the first place ? Why not read the time from the RTC about every second and test the hour and minute data directly to see whether it is time to trigger something ?

I also had no idea only 6 alarms could be scheduled. I have 12 alarms for the single hour in the shortened sketch I posted. That explains why only the first 6 alarms appear on the SM. I had a number of alarms set for every hour for a total of 152 alarms. :o

I assume I'm asking too much of Arduino and need to start over with my dosing plan.

There are likely several ways to achieve what you want to do. First order of business is to define the outputs and the schedule in detail.

Do you have more than 7 outputs to be scheduled?

pinMode(DryFood, OUTPUT);
  pinMode(RpumpA, OUTPUT);
  pinMode(RpumpB, OUTPUT);
  pinMode(KalkStir, OUTPUT);
  pinMode(KalkDose, OUTPUT);
  pinMode(FoodStir, OUTPUT);
  pinMode(FoodDose, OUTPUT);

Can you get all the outputs and the schedule into a table or spreadsheet for us?

Just those 7 outputs.

cattledog, I ended up working today so didn’t have much time to find the place in TimeAlarms to increase number of alarms. I couldn’t find it in the Time example and I couldn’t figure out how to open Time from the library.

First thing tomorrow, I’ll see about a table or spreadsheet.

UKheliBob, I’m using time alarms because that’s the only way I know of to make Arduino keep accurate time. The only way I know to make the RTC trigger something is with alarms. I lifted RTC triggering alarms from another sketch…

so didn't have much time to find the place in TimeAlarms to increase number of alarms. I couldn't find it in the Time example and I couldn't figure out how to open Time from the library.

You will need to use a text editor. The library file should be in the documents folder with your sketches. You should find a folder in there called Libraries and within that should be another one called TimeAlarms where TimeAlarms.h lives.

saltyjoe: UKheliBob, I'm using time alarms because that's the only way I know of to make Arduino keep accurate time. The only way I know to make the RTC trigger something is with alarms. I lifted RTC triggering alarms from another sketch...

Well, that is simply wrong. It was pointed out to you clearly in #13 that you simply repeatedly read the time from the RTC and compare it to your next scheduled event.

Your code if correctly written, spends the vast majority of its time(sic) cycling through the loop(), generally many times each millisecond and reading the RTC neither involves a meaningful wait or affects the accuracy of the RTC timekeeping.

The only necessity ever to use the alarm functionality of the RTC is if you wish to "sleep" the Arduino in order to save power when using a battery to power the Arduino itself, and use the alarm to wake it for an event.

When I opened the libraries folder, there was not a TimeAlarms folder. I did find a folder called TimerOne but there was not this in it, #define dtNBR_ALARMS 6 // max is 255.

If this list of alarms lifted from the sketch is not in a format you like, please let me know.

Paul__B, I'll try to think about this from a different point of view. Just trying to automate dosage for my fish tank in a reliable way.

HAPPY NEW YEAR!

Alarm.alarmRepeat(1, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(1, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(1, 0, 19, StopKalkDoseAlarm); //kalk at 1:00 AM Alarm.alarmRepeat(1, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(2, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(2, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(2, 0, 19, StopKalkDoseAlarm); //kalk at 2:00 AM Alarm.alarmRepeat(2, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(3, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(3, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(3, 0, 19, StopKalkDoseAlarm); //kalk at 3:00 AM Alarm.alarmRepeat(3, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(4, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(4, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(4, 0, 19, StopKalkDoseAlarm); //kalk at 4:00 AM Alarm.alarmRepeat(4, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(5, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(5, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(5, 0, 19, StopKalkDoseAlarm); //kalk at 5:00 AM Alarm.alarmRepeat(5, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(6, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(6, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(6, 0, 19, StopKalkDoseAlarm); //kalk at 6:00 AM Alarm.alarmRepeat(6, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(7, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(7, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(7, 0, 19, StopKalkDoseAlarm); //kalk at 7:00 AM Alarm.alarmRepeat(7, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(8, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(8, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(8, 0, 19, StopKalkDoseAlarm); //kalk at 8:00 AM Alarm.alarmRepeat(8, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(8, 30, 0, StopRpumpAAlarm); //Stop return pumps Alarm.alarmRepeat(8, 30, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(8, 30, 2, StartDryFoodAlarm); //Dry food at 8:30 Alarm.alarmRepeat(8, 30, 12, StopDryFoodAlarm);

Alarm.alarmRepeat(8, 40, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause Alarm.alarmRepeat(8, 40, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(9, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(9, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(9, 0, 19, StopKalkDoseAlarm); //kalk at 9:00 AM Alarm.alarmRepeat(9, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(10, 0, 0, StopRpumpAAlarm); //Stop return pumps Alarm.alarmRepeat(10, 0, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(10, 0, 2, FoodStirAlarm); Alarm.alarmRepeat(10, 0, 18, FoodDoseAlarm); //Dose frozen food at 10:00 AM Alarm.alarmRepeat(10, 0, 22, StopFoodDoseAlarm); Alarm.alarmRepeat(10, 0, 23, StopFoodStirAlarm);

Alarm.alarmRepeat(10, 0, 27, KalkStirAlarm); Alarm.alarmRepeat(10, 0, 34, KalkDoseAlarm); Alarm.alarmRepeat(10, 0, 46, StopKalkDoseAlarm); //kalk at 10:00 AM Alarm.alarmRepeat(10, 1, 26, StopKalkStirAlarm);

Alarm.alarmRepeat(10, 10, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause Alarm.alarmRepeat(10, 10, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(11, 0, 0, KalkStirAlarm); Alarm.alarmRepeat(11, 0, 7, KalkDoseAlarm); Alarm.alarmRepeat(11, 0, 19, StopKalkDoseAlarm); //kalk at 11:00 AM Alarm.alarmRepeat(11, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(11, 30, 0, StopRpumpAAlarm); //Stop return pumps Alarm.alarmRepeat(11, 30, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(11, 30, 2, StartDryFoodAlarm); //Dry food at 11:30 Alarm.alarmRepeat(11, 30, 12, StopDryFoodAlarm);

Alarm.alarmRepeat(11, 40, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause Alarm.alarmRepeat(11, 40, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(12, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(12, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(12, 0, 19, StopKalkDoseAlarm); //kalk at noon
Alarm.alarmRepeat(12, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(13, 0, 0, StopRpumpAAlarm); //Stop return pumps
Alarm.alarmRepeat(13, 0, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(13, 0, 2, FoodStirAlarm);
Alarm.alarmRepeat(13, 0, 17, FoodDoseAlarm); //Dose frozen food at 1:00 PM
Alarm.alarmRepeat(13, 0, 21, StopFoodDoseAlarm);
Alarm.alarmRepeat(13, 0, 22, StopFoodStirAlarm);

Alarm.alarmRepeat(13, 0, 27, KalkStirAlarm);
Alarm.alarmRepeat(13, 0, 34, KalkDoseAlarm);
Alarm.alarmRepeat(13, 0, 46, StopKalkDoseAlarm); //kalk at 1:00 PM
Alarm.alarmRepeat(13, 1, 26, StopKalkStirAlarm);

Alarm.alarmRepeat(13, 10, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause
Alarm.alarmRepeat(13, 10, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(14, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(14, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(14, 0, 19, StopKalkDoseAlarm); //kalk at 2:00 PM
Alarm.alarmRepeat(14, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(14, 30, 0, StopRpumpAAlarm); //Stop return pumps
Alarm.alarmRepeat(14, 30, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(14, 30, 2, StartDryFoodAlarm); //Dry food at 2:30
Alarm.alarmRepeat(14, 30, 12, StopDryFoodAlarm);

Alarm.alarmRepeat(14, 40, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause
Alarm.alarmRepeat(14, 40, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(15, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(15, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(15, 0, 19, StopKalkDoseAlarm); //kalk at 3:00 PM
Alarm.alarmRepeat(15, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(16, 0, 0, StopRpumpAAlarm); //Stop return pumps
Alarm.alarmRepeat(16, 0, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(16, 0, 2, FoodStirAlarm);
Alarm.alarmRepeat(16, 0, 17, FoodDoseAlarm); //Dose frozen food at 4:00 PM
Alarm.alarmRepeat(16, 0, 21, StopFoodDoseAlarm);
Alarm.alarmRepeat(16, 0, 22, StopFoodStirAlarm);

Alarm.alarmRepeat(16, 0, 27, KalkStirAlarm);
Alarm.alarmRepeat(16, 0, 34, KalkDoseAlarm);
Alarm.alarmRepeat(16, 0, 46, StopKalkDoseAlarm); //kalk at 4:00 PM
Alarm.alarmRepeat(16, 1, 26, StopKalkStirAlarm);

Alarm.alarmRepeat(16, 10, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause
Alarm.alarmRepeat(16, 10, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(17, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(17, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(17, 0, 19, StopKalkDoseAlarm); //kalk at 5:00 PM
Alarm.alarmRepeat(17, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(17, 30, 0, StopRpumpAAlarm); //Stop return pumps
Alarm.alarmRepeat(17, 30, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(17, 30, 2, StartDryFoodAlarm); //Dry food at 5:30
Alarm.alarmRepeat(17, 30, 12, StopDryFoodAlarm);

Alarm.alarmRepeat(17, 40, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause
Alarm.alarmRepeat(17, 40, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(18, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(18, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(18, 0, 19, StopKalkDoseAlarm); //kalk at 6:00 PM
Alarm.alarmRepeat(18, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(19, 0, 0, StopRpumpAAlarm); //Stop return pumps
Alarm.alarmRepeat(19, 0, 1, StopRpumpBAlarm);

Alarm.alarmRepeat(19, 0, 2, FoodStirAlarm);
Alarm.alarmRepeat(19, 0, 17, FoodDoseAlarm); //Dose frozen food at 7:00 PM
Alarm.alarmRepeat(19, 0, 21, StopFoodDoseAlarm);
Alarm.alarmRepeat(19, 0, 22, StopFoodStirAlarm);

Alarm.alarmRepeat(19, 0, 27, KalkStirAlarm);
Alarm.alarmRepeat(19, 0, 34, KalkDoseAlarm);
Alarm.alarmRepeat(19, 0, 46, StopKalkDoseAlarm); //kalk at 7:00 PM
Alarm.alarmRepeat(19, 1, 26, StopKalkStirAlarm);

Alarm.alarmRepeat(19, 10, 0, StartRpumpAAlarm); //Start return pumps after a 10 minute pause
Alarm.alarmRepeat(19, 10, 1, StartRpumpBAlarm);

Alarm.alarmRepeat(20, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(20, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(20, 0, 19, StopKalkDoseAlarm); //kalk at 8:00 PM
Alarm.alarmRepeat(20, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(21, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(21, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(21, 0, 19, StopKalkDoseAlarm); //kalk at 9:00 PM
Alarm.alarmRepeat(21, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(22, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(22, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(22, 0, 19, StopKalkDoseAlarm); //kalk at 10:00 PM
Alarm.alarmRepeat(22, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(23, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(23, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(23, 0, 19, StopKalkDoseAlarm); //kalk at 11:00 PM
Alarm.alarmRepeat(23, 1, 0, StopKalkStirAlarm);

Alarm.alarmRepeat(24, 0, 0, KalkStirAlarm);
Alarm.alarmRepeat(24, 0, 7, KalkDoseAlarm);
Alarm.alarmRepeat(24, 0, 19, StopKalkDoseAlarm); //kalk at midnight
Alarm.alarmRepeat(24, 1, 0, StopKalkStirAlarm);