PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

TimeAlarms.h 7.1KB

3 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // TimeAlarms.h - Arduino Time alarms header for use with Time library
  2. #ifndef TimeAlarms_h
  3. #define TimeAlarms_h
  4. #include <Arduino.h>
  5. #include "TimeLib.h"
  6. #if !defined(dtNBR_ALARMS )
  7. #if defined(__AVR__)
  8. #define dtNBR_ALARMS 6 // max is 255
  9. #elif defined(ESP8266)
  10. #define dtNBR_ALARMS 20 // for esp8266 chip - max is 255
  11. #else
  12. #define dtNBR_ALARMS 12 // assume non-AVR has more memory
  13. #endif
  14. #endif
  15. #define USE_SPECIALIST_METHODS // define this for testing
  16. typedef enum {
  17. dtMillisecond,
  18. dtSecond,
  19. dtMinute,
  20. dtHour,
  21. dtDay
  22. } dtUnits_t;
  23. typedef struct {
  24. uint8_t alarmType :4 ; // enumeration of daily/weekly (in future:
  25. // biweekly/semimonthly/monthly/annual)
  26. // note that the current API only supports daily
  27. // or weekly alarm periods
  28. uint8_t isEnabled :1 ; // the timer is only actioned if isEnabled is true
  29. uint8_t isOneShot :1 ; // the timer will be de-allocated after trigger is processed
  30. } AlarmMode_t;
  31. // new time based alarms should be added just before dtLastAlarmType
  32. typedef enum {
  33. dtNotAllocated,
  34. dtTimer,
  35. dtExplicitAlarm,
  36. dtDailyAlarm,
  37. dtWeeklyAlarm,
  38. dtLastAlarmType
  39. } dtAlarmPeriod_t ; // in future: dtBiweekly, dtMonthly, dtAnnual
  40. // macro to return true if the given type is a time based alarm, false if timer or not allocated
  41. #define dtIsAlarm(_type_) (_type_ >= dtExplicitAlarm && _type_ < dtLastAlarmType)
  42. #define dtUseAbsoluteValue(_type_) (_type_ == dtTimer || _type_ == dtExplicitAlarm)
  43. typedef uint8_t AlarmID_t;
  44. typedef AlarmID_t AlarmId; // Arduino friendly name
  45. #define dtINVALID_ALARM_ID 255
  46. #define dtINVALID_TIME (time_t)(-1)
  47. #define AlarmHMS(_hr_, _min_, _sec_) (_hr_ * SECS_PER_HOUR + _min_ * SECS_PER_MIN + _sec_)
  48. typedef void (*OnTick_t)(); // alarm callback function typedef
  49. // class defining an alarm instance, only used by dtAlarmsClass
  50. class AlarmClass
  51. {
  52. public:
  53. AlarmClass();
  54. OnTick_t onTickHandler;
  55. void updateNextTrigger();
  56. time_t value;
  57. time_t nextTrigger;
  58. AlarmMode_t Mode;
  59. };
  60. // class containing the collection of alarms
  61. class TimeAlarmsClass
  62. {
  63. private:
  64. AlarmClass Alarm[dtNBR_ALARMS];
  65. void serviceAlarms();
  66. uint8_t isServicing;
  67. uint8_t servicedAlarmId; // the alarm currently being serviced
  68. AlarmID_t create(time_t value, OnTick_t onTickHandler, uint8_t isOneShot, dtAlarmPeriod_t alarmType);
  69. public:
  70. TimeAlarmsClass();
  71. // functions to create alarms and timers
  72. // trigger once at the given time in the future
  73. AlarmID_t triggerOnce(time_t value, OnTick_t onTickHandler) {
  74. if (value <= 0) return dtINVALID_ALARM_ID;
  75. return create(value, onTickHandler, true, dtExplicitAlarm);
  76. }
  77. // trigger once at given time of day
  78. AlarmID_t alarmOnce(time_t value, OnTick_t onTickHandler) {
  79. if (value <= 0 || value > SECS_PER_DAY) return dtINVALID_ALARM_ID;
  80. return create(value, onTickHandler, true, dtDailyAlarm);
  81. }
  82. AlarmID_t alarmOnce(const int H, const int M, const int S, OnTick_t onTickHandler) {
  83. return alarmOnce(AlarmHMS(H,M,S), onTickHandler);
  84. }
  85. // trigger once on a given day and time
  86. AlarmID_t alarmOnce(const timeDayOfWeek_t DOW, const int H, const int M, const int S, OnTick_t onTickHandler) {
  87. time_t value = (DOW-1) * SECS_PER_DAY + AlarmHMS(H,M,S);
  88. if (value <= 0) return dtINVALID_ALARM_ID;
  89. return create(value, onTickHandler, true, dtWeeklyAlarm);
  90. }
  91. // trigger daily at given time of day
  92. AlarmID_t alarmRepeat(time_t value, OnTick_t onTickHandler) {
  93. if (value > SECS_PER_DAY) return dtINVALID_ALARM_ID;
  94. return create(value, onTickHandler, false, dtDailyAlarm);
  95. }
  96. AlarmID_t alarmRepeat(const int H, const int M, const int S, OnTick_t onTickHandler) {
  97. return alarmRepeat(AlarmHMS(H,M,S), onTickHandler);
  98. }
  99. // trigger weekly at a specific day and time
  100. AlarmID_t alarmRepeat(const timeDayOfWeek_t DOW, const int H, const int M, const int S, OnTick_t onTickHandler) {
  101. time_t value = (DOW-1) * SECS_PER_DAY + AlarmHMS(H,M,S);
  102. if (value <= 0) return dtINVALID_ALARM_ID;
  103. return create(value, onTickHandler, false, dtWeeklyAlarm);
  104. }
  105. // trigger once after the given number of seconds
  106. AlarmID_t timerOnce(time_t value, OnTick_t onTickHandler) {
  107. if (value <= 0) return dtINVALID_ALARM_ID;
  108. return create(value, onTickHandler, true, dtTimer);
  109. }
  110. AlarmID_t timerOnce(const int H, const int M, const int S, OnTick_t onTickHandler) {
  111. return timerOnce(AlarmHMS(H,M,S), onTickHandler);
  112. }
  113. // trigger at a regular interval
  114. AlarmID_t timerRepeat(time_t value, OnTick_t onTickHandler) {
  115. if (value <= 0) return dtINVALID_ALARM_ID;
  116. return create(value, onTickHandler, false, dtTimer);
  117. }
  118. AlarmID_t timerRepeat(const int H, const int M, const int S, OnTick_t onTickHandler) {
  119. return timerRepeat(AlarmHMS(H,M,S), onTickHandler);
  120. }
  121. void delay(unsigned long ms);
  122. // utility methods
  123. uint8_t getDigitsNow( dtUnits_t Units) const; // returns the current digit value for the given time unit
  124. void waitForDigits( uint8_t Digits, dtUnits_t Units);
  125. void waitForRollover(dtUnits_t Units);
  126. // low level methods
  127. void enable(AlarmID_t ID); // enable the alarm to trigger
  128. void disable(AlarmID_t ID); // prevent the alarm from triggering
  129. AlarmID_t getTriggeredAlarmId() const; // returns the currently triggered alarm id
  130. bool getIsServicing() const; // returns isServicing
  131. void write(AlarmID_t ID, time_t value); // write the value (and enable) the alarm with the given ID
  132. time_t read(AlarmID_t ID) const; // return the value for the given timer
  133. dtAlarmPeriod_t readType(AlarmID_t ID) const; // return the alarm type for the given alarm ID
  134. void free(AlarmID_t ID); // free the id to allow its reuse
  135. #ifndef USE_SPECIALIST_METHODS
  136. private: // the following methods are for testing and are not documented as part of the standard library
  137. #endif
  138. uint8_t count() const; // returns the number of allocated timers
  139. time_t getNextTrigger() const; // returns the time of the next scheduled alarm
  140. time_t getNextTrigger(AlarmID_t ID) const; // returns the time of scheduled alarm
  141. bool isAllocated(AlarmID_t ID) const; // returns true if this id is allocated
  142. bool isAlarm(AlarmID_t ID) const; // returns true if id is for a time based alarm, false if its a timer or not allocated
  143. };
  144. extern TimeAlarmsClass Alarm; // make an instance for the user
  145. /*==============================================================================
  146. * MACROS
  147. *============================================================================*/
  148. /* public */
  149. #define waitUntilThisSecond(_val_) waitForDigits( _val_, dtSecond)
  150. #define waitUntilThisMinute(_val_) waitForDigits( _val_, dtMinute)
  151. #define waitUntilThisHour(_val_) waitForDigits( _val_, dtHour)
  152. #define waitUntilThisDay(_val_) waitForDigits( _val_, dtDay)
  153. #define waitMinuteRollover() waitForRollover(dtSecond)
  154. #define waitHourRollover() waitForRollover(dtMinute)
  155. #define waitDayRollover() waitForRollover(dtHour)
  156. #endif /* TimeAlarms_h */