modulo and time: how to calculate

A program uses an RTC for time related tasks. A controller needs to do a specific task every 20 minutes. Depending on the controller ID (there are four different controllers doing the same task but at different times) there is a starting offset. This offset is either 0, 5, 10 or 15 minutes.

These tasks need to be performed at minutes (past the hour) 0, 20 and 40 for ID = A, at minutes 5, 25, 45 for ID = B, at minutes 10, 30, 50 for ID = C, and at minutes 15, 30, 55 for ID = D.

The issue I have is that at start-up I want each controller to start at its nearest next allocated timeslot.
For example, if ID = C is started at minute = 7 then it should start its first performance at minute = 10.

I subsequently use following to set RTC alarms (this code runs fine):

  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, startTime, 0, 0);

..and this to increment the alarmtime with the offset of 20 minutes:

  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, ((now.minute() + 20) % 60), 0, 0);

If the actual minute is read into variable x, and the resulting time taskTime at which the task must next be performed then I currently use this formula:

taskTime =  ((((x / 20) * 20) + 20) % 60) + 10; // offset 10 for ID = C

This however results in a taskTime = 30 for any value x between 0 and 19, taskTime = 50 for x between 20 and 39, taskTime = 10 for x between 40 and 59.

How should this formula be written so that for ID = C (for example) the startup between minute 50 and minute 9 results in taskTime to be 10; if startup is between minute 10 and minute 29, the taskTime is calculated to be 30, etc.. ?

The same should apply in that formula for the other ID's, taking care of their respective offsets.

brice3010:
For example, if ID = C is started at minute = 7 then it should start its first performance at minute = 10.

I don’t follow that logic… You just told it should start at 15.

How does that mix in with 7 becoming 10 (rounding up to the nearest multiple of 5?)

septillion:
I don't follow that logic... You just told it should start at 15.

How does that mix in with 7 becoming 10 (rounding up to the nearest multiple of 5?)

My apologies!! You are right: ID = C should then start at 10.

However, for ID = C, if the controller is powered up any time between minute 50 and minute 9, then the variable taskTime should be 10. If the controller is powered up any time between minute 10 and 29 then taskTime should be
30, etc..

Powering up the controller makes it read the RTC, from which it takes the actual minute. From there the value for minute is used for calculation of timeTask.

Ahh, yeah, read it wrong.

Think it should be:

taskMinute = ( (StartMinute + interval - offset) / interval * interval + offset) % 60;

septillion:
Ahh, yeah, read it wrong.

Think it should be:

taskMinute = ( (StartMinute + interval - offset) / interval * interval + offset) % 60;

x/interval*interval = x

Did you forget a parenthesis?

For human readability, maybe. For the Arduino I did not. It will do that left to right:

Example:
x = 32
interval = 20:
x / interval => 32 / 20 = 1

  • interval => 1 * 20 = 20

septillion:
For human readability, maybe. For the Arduino I did not. It will do that left to right:

Example:
x = 32
interval = 20:
x / interval => 32 / 20 = 1

  • interval => 1 * 20 = 20

Thanks! Great solution!