10 dates scheduled alarm with each day having 5 different alarm

I am designing a project with ESP32 and an external DS3231 RTC where I want to schedule alarm for 10 dates where each dates will have 5 on time and 5 off time of a digital pin.

The system panel will have a graphical display and buttons where I can set the alarm times.

Guide me with the path to find the easiest method/way for setting the variables

DAY, MONTH, YEAR, HOUR, MIN

Then I can check the rtc time to match with the set variables to switch on and off the alarm.

Do you mean as a user interface?

No no.. I have already designed the hardware interface.

Just unable to make out after setting an alarm on the interface how to save so many data.

If it was 1 date with 1 to 2 alarms it was fine..
But with so many I am confused if I try the simple way it will be very very long.

One thing that will make it waaaay easier is to convert all times to a "minutes since midnight" concept, or "seconds since midnight" if you are looking for tighter timing.

Then all times are just one number, seeing if a time is current, or has passed, is a simple test

  if (now >= timeForLunch) ringBell();

timeForLunch might be 60 * 12 + 30 minutes since midnight. Since there are 1440 minutes in a day, those time numbers can just be 16 bit integers.

You could have a 10 by 5 two dimensional array of such numbers, 5 times each for ten days, or double that you meant five on and off sets each day for ten.

a7

1 Like

he wants dates in the future - so seconds since midnight does not cut it (at least that's how I understood it)

an array of DateTime (from the RTCLib from Adafruit) would work in a nice way

1 Like

That's a good way, something out of the box I never thought of.

The dirty part is I cannot hard code any alarm.
The user needs to set it from the user interface.

Like on
01/01/2024
the user should be able to set an alarm for
10/02/2024

also on 10/02/2024 there should be 5 ON alarm and 5 OFF alarm, so that makes total 10 alarms each day.

That's what in my mind yet.
To set the alarm time on the interface and then save it as an array. In that way I will have to save only 1 data for each alarm.

I don't see why not. On a given date in some distant future, the times in that date can be stored as seconds since midnight.

Or… OP could switch to seconds since 1970, or whenever. I think some libraries will do that for you.

The storage required would be greater, but that isn't alarming yet. See what I did there?

@nemo4all do you want complete flexibility, maybe even beyond the inflexible 10 dates 5 control periods?

Or is there any regularity to exploit, like all periods are 12 minutes long?

a7

1 Like

Yes.. All the 5 alarm on the future date will have different durations. Few are for 1 hour few are for 2.5 hours and 3 hours. Else things would have been little easier

DateTime :wink:

Yes you need to store the date on top of the seconds since midnight. I did not get this is what you suggested

If you want the easiest way of setting those, I suggest you split day, year, hour, and minute each into two digits. So, for the date, you would set day tens, then day ones, then month, then year tens, then year ones.

You would need two buttons: a "plus" button, and a "move to next digit" button. Your "plus" button would increase the selected digit by 1, except if it would be greater than 9 (for the months, greater than 12), in which case the digit would go back to 0 (or, for the months, back to 1).

You might want an array with 5 elements for setting the date. Element 0 would be day tens, element 1 would be day ones, element 2 would be month, and so forth. Then, when you are done setting the date, you would combine those 5 elements into 3 variables for day, month, and year, using arithmetic. Something like:

myDay = (10 * setDigit[0]) + setDigit[1];
myMonth = setDigit[2];
myYear = (10 * setDigit[3]) + setDigit[4];

In order to do any of this, though, you need to know how to read a button, and you probably also need to know how to debounce a button.

Are you able to write a simple sketch that just counts how many times a button is pressed and shows the number on the display? That would be the first step towards making your project work.

That's not a problem at all..
Currently I was working on the UI and the MENU is ready.

All controlled by 3 buttons.

I am just confused about how to save so many times.

10 day with 10 alarms each.
will have to save 100 array

byte myAlarmDates[10][3];

10 days * (day + month + year = 3 numbers)
EDIT: Year cannot fit in a byte if four digits (like 2024). You may need to subtract 2000 first, before storing it.

byte myAlarmTimes[10][2][5][2];

10 days * (ON + OFF = 2 states) * 5 alarms per day per state * (hour + minute = 2 numbers per alarm)

With the Adafruit RTCLib

const size_t maxDateRecords = 10;
DateTime dateRecords[maxDateRecords];

You can create a DateTime from the various variables you got from your interface with
DateTime( year, month, day, hour, min, sec );

If you save the full date time or DateTime for all one hundred events, then yes 32 bits * 100 is 400 bytes.

Which may not be a problem?

Or ten dates as days since 1 JAN 2024 as unsigned 16 bit integers 160 bytes

and 100 times of day as 16 bit integers 160 bytes.

That's still 320 bytes.

Since these are going to be set and/or changed by humans, it seems like you could write them into EEPROM, which you prolly want to do anyway in order that the device behave well across power outrages.

a7

1 Like

There is a library called TimeAlarms, which is made for this sort of thing. It might be useful.

I went through the library and found this.

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)

Yes, if you need the level of handholding given by, for example, bitRead().

Decided not to use any library.

but what's the easiest way to match the set time with the current time at one go..?
Rather than matching DATE, MONTH, HOUR, MIN separately, can I match the statement
(now.day, now.month, now.hour, now.minute)

instead of

if(DATE == now.day && MONTH == now.month && HOUR == now.hour, && MIN == now.minute){
// switch ON/OFF alarm
}

What leads you to believe that there is an easier way?