Go Down

Topic: Perform time-based task once only, at set times per hour, every hour (Read 685 times) previous topic - next topic

brice3010

It must be nice to be psychic.
It helps.. and a good glass of wine is a start  :smiley-lol:

I didn't say alarms would necessarily be easier but all it would require is an alarm interrupt every minute. The code in loop() would look almost the same except that the alarm must be reset and there's no need to test if minute == lastMinute.


Pete
And you would need a library?

el_supremo

You've already got functions to read and set the time in the RTC. A little bit of browsing through the DS3231 datasheet would show you how to set and reset the alarms. Or you could google for code to do it.
Or use a library. No big deal.

Pete
Don't send me technical questions via Private Message.

larryd

So by the same token, if I have task A to be performed once at 3 instances per hour, is the following correct?
Code: [Select]

if((taskAflag == true && minute == 10) || (taskAflag == true && minute == 20) || (taskAflag == true && minute == 40))
{
taskAflag = false; //disable, do only one taskA
. . .
}

if((taskAflag == false && minute == (10+1)) || (taskAflag == false && minute == (20+1)) || (taskAflag == false && minute == (40+1)))
{
taskAflag = true; //enable taskA for next time
}


The good thing about the Arduino platform is you can test things out ;)

Sketch to check out algorithm.
Code: [Select]

bool taskAflag = true;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}
void loop()
{
  for (int x = 0; x < 6000; x++)
  {
    if (taskAflag == true && (x == 1000 ||  x == 2000  ||  x == 4000 ))
    {
      taskAflag = false; //disable, do only one taskA
      //call the task
      task(x);
      //. . .
    }

    if (taskAflag == false && (x == 1001 ||  x == 2001 ||  x == 4001 ))
    {
      taskAflag = true; //enable taskA for next time
    }
  }
}// END of loop()

void task(int x)
{
  //print test time
  Serial.println(x);
  //toggle LED
  digitalWrite(13, !digitalRead(13));
  delay(200);
  digitalWrite(13, !digitalRead(13));
}


Edit, updated code.
No technical PMs.
The last thing you did is where you should start looking.

brice3010

The good thing about the Arduino platform is you can test things out ;)

Sketch to check out algorithm.
Code: [Select]

bool taskAflag = true;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}
void loop()
{
  for (int x = 0; x < 6000; x++)
  {
    if (taskAflag == true && (x == 1000 ||  x == 2000  ||  x == 4000 ))
    {
      taskAflag = false; //disable, do only one taskA
      //call the task
      task(x);
      //. . .
    }

    if (taskAflag == false && (x == 1001 ||  x == 2001 ||  x == 4001 ))
    {
      taskAflag = true; //enable taskA for next time
    }
  }
}// END of loop()

void task(int x)
{
  //print test time
  Serial.println(x);
  //toggle LED
  digitalWrite(13, !digitalRead(13));
  delay(200);
  digitalWrite(13, !digitalRead(13));
}


Edit, updated code.
Hi larryd, thanks for your input; from what I read you do not use the DS3231? Or am I confused?

larryd

The example I gave is a quick and dirty way for checking the algorithm.

Yes I do, exclusively, use the DS3231 RTCs.

They are much much better than the DS1307.

You can change the 'x' in the sample sketch to 'minute' or whatever.

If you test the code out, you should find it does what you what you asked.


No technical PMs.
The last thing you did is where you should start looking.

brice3010

The example I gave is a quick and dirty way for checking the algorithm.

Yes I do, exclusively, use the DS3231 RTCs.

They are much much better than the DS1307.

You can change the 'x' in the sample sketch to 'minute' or whatever.

If you test the code out, you should find it does what you what you asked.



larryd I slightly modified your code, instead of 2 if conditions I use a static byte to remember the last time checked (in this case: every 5 minutes starting at minute 4 (first example without using RTC library):

Code: [Select]


  static byte lastMinute1;
  if ( minute == lastMinute1 ) {
    return;
  }


  lastMinute1 = minute; // remember what second (or minute) was last time we looked
  // minute has changed... what is it now?


  if (minute == 4 || minute == 9 || minute == 14 || minute == 19 || minute == 24 || minute == 29 || minute == 34 || minute == 39 || minute == 44 || minute == 49 || minute == 57 || minute == 59)
  {
    //    do something once
}



And when using a library (here RTClibExtended.h) I set the alarm ALM1 to start of, and once inside the code modify the alarmtime:

in setup:

Code: [Select]

  RTC.begin();
  RTC.armAlarm(1, false);
  RTC.clearAlarm(1);
  RTC.alarmInterrupt(1, false);
  RTC.writeSqwPinMode(DS3231_OFF);
  RTC.setAlarm(ALM1_MATCH_SECONDS, 01, 00, 0, 0);  //set your wake-up time here: 01 seconds past the minute
  RTC.alarmInterrupt(1, true); // assert the INT pin when Alarm1 occurs, set alarm1, if disable write false


in loop:

Code: [Select]

  if (goToSleepNow == 1) {                                 // value 1 = go to sleep
    attachInterrupt(0, wakeUp, LOW);                       //use interrupt 0 (pin PD2) and run function wakeUp when pin 2 gets LOW
    digitalWrite(ledPin, LOW);                             //switch-off the built-in led for indicating that we enter the sleep mode
    ledStatus = 0;                                         //set the led status accordingly
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
    detachInterrupt(0); //execution resumes from here after wake-up
    //When exiting the sleep mode we clear the alarm
    RTC.armAlarm(1, false);
    RTC.clearAlarm(1);
    RTC.alarmInterrupt(1, false);
    goToSleepNow = 0;                                      // value 0 = do not go to sleep
  }
// do whatever is needed during wake-up
  DateTime now = RTC.now();
// next two lines of code: either one of both, but only one of both
  // 1. set new wake-up time next line: every 5 minutes (and 10 seconds past that minute)
  RTC.setAlarm(ALM1_MATCH_MINUTES, 10, ((now.minute()+5)%60), 0, 0);
  // 2. set new wake-up time next line: every 5 seconds
  // RTC.setAlarm(ALM1_MATCH_SECONDS, ((now.second()+5)%60), 0, 0, 0);
  
  goToSleepNow = 1; // go back to sleep
  RTC.alarmInterrupt(1, true);

Go Up