Software implemented real time clock driven by a Ticker. No external hardware (like DS1307 or DS3231 or etc.) is needed. Should work on any mbed platform where Ticker works.

Dependents:   Clock_Hello

See demo:

Import programClock_Hello

Demo for the Clock library (real time clock driven by a Ticker).

Revision:
6:7edabed68b0f
Parent:
5:d65fc7060635
--- a/Clock.cpp	Fri May 20 18:14:34 2016 +0000
+++ b/Clock.cpp	Tue Jan 15 14:46:57 2019 +0000
@@ -9,7 +9,7 @@
  
  See demo <http://developer.mbed.org/users/hudakz/code/Clock_Hello/>
  
- Copyright (c) 2015 Zoltan Hudak <hudakz@inbox.com>
+ Copyright (c) 2015 Zoltan Hudak <hudakz@outlook.com>
  All rights reserved.
 
  This program is free software: you can redistribute it and/or modify
@@ -25,14 +25,13 @@
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
- 
 #include "mbed.h"
 #include "Clock.h"
 
 // Static member initialization
-time_t          Clock::_time = 0;
-tm              Clock::_tm = {0, 0, 0, 0, 0, 0, -1};
-FunctionPointer Clock::_onTick = NULL;
+time_t              Clock::_time = 0;
+tm                  Clock::_tm = { 0, 0, 0, 0, 0, 0, 0, 0, -1 };
+Callback<void ()>   Clock::_onTick = NULL;
 
 /**
  * @brief   Constructs a Clock.
@@ -40,17 +39,18 @@
  *          Since the Clock is attached as an external RTC
  *          standard C time functions can be called as well.
  * @param   year:   long format (for instance 2015)
- *          mon:    month (1 stands for January etc.)
- *          mday:   day of month
- *          hour:   24hour format
- *          min:    minutes
- *          ser:    seconds
+ * @param   mon:    month (1 stands for January etc.)
+ * @param   mday:   day of month
+ * @param   hour:   24hour format
+ * @param   min:    minutes
+ * @param   ser:    seconds
  * @retval
  */
-Clock::Clock(int year, int mon, int mday, int hour, int min, int sec) {
-    _ticker.attach_us(&tick, 1000000);      // a Ticker ticking at 1s rate
-    set(year, mon, mday, hour, min, sec);   // set date and time as requested
-    attach_rtc(time, NULL, NULL, NULL);     // attach for C time functions
+Clock::Clock(int year, int mon, int mday, int hour, int min, int sec) :
+    _ticker(new Ticker)
+{
+    _ticker->attach_us(&tick, 1000000); // a Ticker ticking at 1s rate
+    attach_rtc(time, NULL, NULL, NULL); // attach for C time functions
 }
 
 /**
@@ -62,35 +62,51 @@
  * @param
  * @retval
  */
-Clock::Clock() {
-    _ticker.attach_us(&tick, 1000000);      // a Ticker ticking at 1s rate
-    set(1970, 1, 1, 0, 0, 0);               // set date and time to the begin of Epoch
-    attach_rtc(time, NULL, NULL, NULL);     // attach for C time functions
+Clock::Clock() :
+    _ticker(new Ticker)
+{
+    _ticker->attach_us(&tick, 1000000); // a Ticker ticking at 1s rate
+    attach_rtc(time, NULL, NULL, NULL); // attach for C time functions
+}
+
+/**
+ * @brief   Destroys a Clock.
+ * @note    Destructor
+ * @param
+ * @retval
+ */
+Clock::~Clock()
+{
+    _ticker->detach();  // suspend ticks
+    delete _ticker;     // distroys _ticker
 }
 
 /**
  * @brief   Sets Clock time using human readable inputs
  * @note
  * @param   year:   long format (for instance 2015)
- *          mon:    month (1 stands for January etc.)
- *          mday:   day of month
- *          hour:   24hour format
- *          min:    minutes
- *          ser:    seconds
+ * @param   mon:    month (1 stands for January etc.)
+ * @param   mday:   day of month
+ * @param   hour:   24hour format
+ * @param   min:    minutes
+ * @param   ser:    seconds
  * @retval
  */
-void Clock::set(int year, int mon, int mday, int hour, int min, int sec) {
-    _ticker.detach();                   // suspend ticks
+void Clock::set(int year, int mon, int mday, int hour, int min, int sec)
+{
+    _ticker->detach();                  // suspend ticks
     _tm.tm_year = year - 1900;
-    _tm.tm_mon =  mon - 1;              // convert to 0 based month
+    _tm.tm_mon = mon - 1;               // convert to 0 based month
     _tm.tm_mday = mday;
     _tm.tm_hour = hour;
     _tm.tm_min = min;
     _tm.tm_sec = sec;
-    _tm.tm_isdst = -1;                  // Is DST on? 1 = yes, 0 = no, -1 = unknown
+    _tm.tm_isdst = -1;
+
+    // Is DST on? 1 = yes, 0 = no, -1 = unknown
     _time = mktime(&_tm);               // convert to seconds elapsed since January 1, 1970
     set_time(_time);                    // set time
-    _ticker.attach_us(&tick, 1000000);  // resume ticks
+    _ticker->attach_us(&tick, 1000000); // resume ticks
 }
 
 /**
@@ -99,10 +115,11 @@
  * @param   val:    tm structure
  * @retval
  */
-void Clock::set(tm& val) {
-    _ticker.detach();                   // suspend ticks
+void Clock::set(tm& val)
+{
+    _ticker->detach();                  // suspend ticks
     _tm = val;
-    _ticker.attach_us(&tick, 1000000);  // resume ticks
+    _ticker->attach_us(&tick, 1000000); // resume ticks
 }
 
 /**
@@ -111,11 +128,12 @@
  * @param   val:    time_t structure (Number of seconds elapsed since January 1, 1970)
  * @retval
  */
-void Clock::set(time_t val) {
-    _ticker.detach();                   // suspend ticks
+void Clock::set(time_t val)
+{
+    _ticker->detach();                  // suspend ticks
     _time = val;
     _tm = *::localtime(&_time);
-    _ticker.attach_us(&tick, 1000000);  // resume ticks
+    _ticker->attach_us(&tick, 1000000); // resume ticks
 }
 
 /**
@@ -124,7 +142,8 @@
  * @param
  * @retval  Number of seconds elapsed since January 1, 1970
  */
-time_t Clock::time(void) {
+time_t Clock::time(void)
+{
     return _time;
 }
 
@@ -134,8 +153,9 @@
  * @param
  * @retval  Year
  */
-int Clock::year(void) {
-    return (_tm.tm_year + 1900);
+int Clock::year(void)
+{
+    return(_tm.tm_year + 1900);
 }
 
 /**
@@ -144,8 +164,9 @@
  * @param
  * @retval  Month
  */
-int Clock::mon(void) {
-    return (_tm.tm_mon + 1);
+int Clock::mon(void)
+{
+    return(_tm.tm_mon + 1);
 }
 
 /**
@@ -154,7 +175,8 @@
  * @param
  * @retval  Day of the month
  */
-int Clock::mday(void) {
+int Clock::mday(void)
+{
     return _tm.tm_mday;
 }
 
@@ -164,7 +186,8 @@
  * @param
  * @retval  Day of week (Sunday = 0, Monday = 1, etc.)
  */
-int Clock::wday(void) {
+int Clock::wday(void)
+{
     return _tm.tm_wday; // Sunday = 0, Monday = 1, etc.
 }
 
@@ -174,7 +197,8 @@
  * @param
  * @retval  Hour
  */
-int Clock::hour(void) {
+int Clock::hour(void)
+{
     return _tm.tm_hour;
 }
 
@@ -184,7 +208,8 @@
  * @param
  * @retval  Minutes
  */
-int Clock::min(void) {
+int Clock::min(void)
+{
     return _tm.tm_min;
 }
 
@@ -194,7 +219,8 @@
  * @param
  * @retval  Seconds
  */
-int Clock::sec(void) {
+int Clock::sec(void)
+{
     return _tm.tm_sec;
 }
 
@@ -205,23 +231,37 @@
  * @param
  * @retval
  */
-void Clock::tick(void) {
+void Clock::tick(void)
+{
     _tm = *::localtime(&(++_time));
     _onTick.call();
 }
 
-
 /**
  * @brief   Attaches a handler to the onTick event
  * @note    onTick event occurs each second
- * @param   fnc:    User defined handler function of type void fnc(void)
+ * @param   fnc  User defined handler function of type 'void fnc(void)'
  * @retval
  */
-void Clock::attach(void (*fptr)(void)) {
-    if(fptr)
-        _onTick.attach(fptr);
+void Clock::attach(void (*fptr) (void))
+{
+    if (fptr)
+        _onTick = fptr;
 }
 
+/**
+ * @brief   Attaches a class method as handler to the onTick event
+ * @note    onTick event occurs each second
+ * @param   tptr  Pointer a class
+ * @param   mptr  Poiter to a 'void fnc(void)' method
+ * @retval
+ */
+template<typename T>
+void Clock::attach(T* tptr, void (T::*mptr) (void))
+{
+    if ((tptr != NULL) && (mptr != NULL))
+        _onTick.attach(tptr, mptr);
+}
 
 /**
  * @brief   Detaches handler function from the onTick event
@@ -229,30 +269,32 @@
  * @param
  * @retval
  */
-void Clock::detach() {
-    _onTick.attach(NULL);
+void Clock::detach()
+{
+    _onTick = NULL;
 }
 
 /**
  * @brief   Converts human readable time to seconds elapsed since January 1, 1970
- * @note    It's a static helper function.
+ * @note    A static helper function.
  * @param   year:   long format (for instance 2015)
- *          mon:    month (1 stands for January etc.)
- *          mday:   day of month
- *          hour:   24hour format
- *          min:    minutes
- *          ser:    seconds
+ * @param   mon:    month (1 stands for January etc.)
+ * @param   mday:   day of month
+ * @param   hour:   24hour format
+ * @param   min:    minutes
+ * @param   ser:    seconds
  * @retval  Number of seconds elapsed since January 1, 1970
  */
-time_t Clock::asTime(int year, int mon, int mday, int hour, int min, int sec) {
+time_t Clock::asTime(int year, int mon, int mday, int hour, int min, int sec)
+{
     struct tm   t;
     t.tm_year = year - 1900;
-    t.tm_mon =  mon - 1;        // convert to 0 based month
+    t.tm_mon = mon - 1; // convert to 0 based month
     t.tm_mday = mday;
     t.tm_hour = hour;
     t.tm_min = min;
     t.tm_sec = sec;
-    t.tm_isdst = -1;            // Is DST on? 1 = yes, 0 = no, -1 = unknown
+    t.tm_isdst = -1;    // Is DST on? 1 = yes, 0 = no, -1 = unknown
+    return mktime(&t);  // returns seconds elapsed since January 1, 1970
+}
 
-    return mktime(&t);          // returns seconds elapsed since January 1, 1970
-}