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).

Committer:
hudakz
Date:
Tue Jan 15 14:46:57 2019 +0000
Revision:
6:7edabed68b0f
Parent:
5:d65fc7060635
fixed constructor, added destructor, FunctionPointer replaced with Callback

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:af43d5d263e7 1 /*
hudakz 0:af43d5d263e7 2 Clock.cpp
hudakz 0:af43d5d263e7 3
hudakz 0:af43d5d263e7 4 Created on: Mar 24, 2015
hudakz 0:af43d5d263e7 5 Author: Zoltan Hudak
hudakz 0:af43d5d263e7 6
hudakz 4:bbe7d7474acd 7 This is a software implemented Real Time Clock driven by a Ticker.
hudakz 4:bbe7d7474acd 8 No external parts (like DS1307 or DS3231 or etc.) are needed.
hudakz 0:af43d5d263e7 9
hudakz 4:bbe7d7474acd 10 See demo <http://developer.mbed.org/users/hudakz/code/Clock_Hello/>
hudakz 0:af43d5d263e7 11
hudakz 6:7edabed68b0f 12 Copyright (c) 2015 Zoltan Hudak <hudakz@outlook.com>
hudakz 0:af43d5d263e7 13 All rights reserved.
hudakz 0:af43d5d263e7 14
hudakz 0:af43d5d263e7 15 This program is free software: you can redistribute it and/or modify
hudakz 0:af43d5d263e7 16 it under the terms of the GNU General Public License as published by
hudakz 0:af43d5d263e7 17 the Free Software Foundation, either version 3 of the License, or
hudakz 0:af43d5d263e7 18 (at your option) any later version.
hudakz 0:af43d5d263e7 19
hudakz 0:af43d5d263e7 20 This program is distributed in the hope that it will be useful,
hudakz 0:af43d5d263e7 21 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:af43d5d263e7 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:af43d5d263e7 23 GNU General Public License for more details.
hudakz 0:af43d5d263e7 24
hudakz 0:af43d5d263e7 25 You should have received a copy of the GNU General Public License
hudakz 0:af43d5d263e7 26 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 0:af43d5d263e7 27 */
hudakz 0:af43d5d263e7 28 #include "mbed.h"
hudakz 0:af43d5d263e7 29 #include "Clock.h"
hudakz 0:af43d5d263e7 30
hudakz 5:d65fc7060635 31 // Static member initialization
hudakz 6:7edabed68b0f 32 time_t Clock::_time = 0;
hudakz 6:7edabed68b0f 33 tm Clock::_tm = { 0, 0, 0, 0, 0, 0, 0, 0, -1 };
hudakz 6:7edabed68b0f 34 Callback<void ()> Clock::_onTick = NULL;
hudakz 0:af43d5d263e7 35
hudakz 0:af43d5d263e7 36 /**
hudakz 0:af43d5d263e7 37 * @brief Constructs a Clock.
hudakz 0:af43d5d263e7 38 * @note The clock is driven by a Ticker.
hudakz 0:af43d5d263e7 39 * Since the Clock is attached as an external RTC
hudakz 0:af43d5d263e7 40 * standard C time functions can be called as well.
hudakz 0:af43d5d263e7 41 * @param year: long format (for instance 2015)
hudakz 6:7edabed68b0f 42 * @param mon: month (1 stands for January etc.)
hudakz 6:7edabed68b0f 43 * @param mday: day of month
hudakz 6:7edabed68b0f 44 * @param hour: 24hour format
hudakz 6:7edabed68b0f 45 * @param min: minutes
hudakz 6:7edabed68b0f 46 * @param ser: seconds
hudakz 0:af43d5d263e7 47 * @retval
hudakz 0:af43d5d263e7 48 */
hudakz 6:7edabed68b0f 49 Clock::Clock(int year, int mon, int mday, int hour, int min, int sec) :
hudakz 6:7edabed68b0f 50 _ticker(new Ticker)
hudakz 6:7edabed68b0f 51 {
hudakz 6:7edabed68b0f 52 _ticker->attach_us(&tick, 1000000); // a Ticker ticking at 1s rate
hudakz 6:7edabed68b0f 53 attach_rtc(time, NULL, NULL, NULL); // attach for C time functions
hudakz 0:af43d5d263e7 54 }
hudakz 0:af43d5d263e7 55
hudakz 0:af43d5d263e7 56 /**
hudakz 0:af43d5d263e7 57 * @brief Constructs a Clock.
hudakz 0:af43d5d263e7 58 * @note The clock is driven by a Ticker.
hudakz 0:af43d5d263e7 59 * Since the Clock is attached as an external RTC
hudakz 0:af43d5d263e7 60 * standard C time functions can be called as well.
hudakz 2:a18375196723 61 * Time is set to the begin of Epoch: 00:00:00 January 1, 1970
hudakz 0:af43d5d263e7 62 * @param
hudakz 0:af43d5d263e7 63 * @retval
hudakz 0:af43d5d263e7 64 */
hudakz 6:7edabed68b0f 65 Clock::Clock() :
hudakz 6:7edabed68b0f 66 _ticker(new Ticker)
hudakz 6:7edabed68b0f 67 {
hudakz 6:7edabed68b0f 68 _ticker->attach_us(&tick, 1000000); // a Ticker ticking at 1s rate
hudakz 6:7edabed68b0f 69 attach_rtc(time, NULL, NULL, NULL); // attach for C time functions
hudakz 6:7edabed68b0f 70 }
hudakz 6:7edabed68b0f 71
hudakz 6:7edabed68b0f 72 /**
hudakz 6:7edabed68b0f 73 * @brief Destroys a Clock.
hudakz 6:7edabed68b0f 74 * @note Destructor
hudakz 6:7edabed68b0f 75 * @param
hudakz 6:7edabed68b0f 76 * @retval
hudakz 6:7edabed68b0f 77 */
hudakz 6:7edabed68b0f 78 Clock::~Clock()
hudakz 6:7edabed68b0f 79 {
hudakz 6:7edabed68b0f 80 _ticker->detach(); // suspend ticks
hudakz 6:7edabed68b0f 81 delete _ticker; // distroys _ticker
hudakz 0:af43d5d263e7 82 }
hudakz 0:af43d5d263e7 83
hudakz 0:af43d5d263e7 84 /**
hudakz 0:af43d5d263e7 85 * @brief Sets Clock time using human readable inputs
hudakz 0:af43d5d263e7 86 * @note
hudakz 0:af43d5d263e7 87 * @param year: long format (for instance 2015)
hudakz 6:7edabed68b0f 88 * @param mon: month (1 stands for January etc.)
hudakz 6:7edabed68b0f 89 * @param mday: day of month
hudakz 6:7edabed68b0f 90 * @param hour: 24hour format
hudakz 6:7edabed68b0f 91 * @param min: minutes
hudakz 6:7edabed68b0f 92 * @param ser: seconds
hudakz 0:af43d5d263e7 93 * @retval
hudakz 0:af43d5d263e7 94 */
hudakz 6:7edabed68b0f 95 void Clock::set(int year, int mon, int mday, int hour, int min, int sec)
hudakz 6:7edabed68b0f 96 {
hudakz 6:7edabed68b0f 97 _ticker->detach(); // suspend ticks
hudakz 0:af43d5d263e7 98 _tm.tm_year = year - 1900;
hudakz 6:7edabed68b0f 99 _tm.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 100 _tm.tm_mday = mday;
hudakz 0:af43d5d263e7 101 _tm.tm_hour = hour;
hudakz 0:af43d5d263e7 102 _tm.tm_min = min;
hudakz 0:af43d5d263e7 103 _tm.tm_sec = sec;
hudakz 6:7edabed68b0f 104 _tm.tm_isdst = -1;
hudakz 6:7edabed68b0f 105
hudakz 6:7edabed68b0f 106 // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 5:d65fc7060635 107 _time = mktime(&_tm); // convert to seconds elapsed since January 1, 1970
hudakz 5:d65fc7060635 108 set_time(_time); // set time
hudakz 6:7edabed68b0f 109 _ticker->attach_us(&tick, 1000000); // resume ticks
hudakz 0:af43d5d263e7 110 }
hudakz 0:af43d5d263e7 111
hudakz 0:af43d5d263e7 112 /**
hudakz 0:af43d5d263e7 113 * @brief Sets Clock to tm value
hudakz 0:af43d5d263e7 114 * @note
hudakz 0:af43d5d263e7 115 * @param val: tm structure
hudakz 0:af43d5d263e7 116 * @retval
hudakz 0:af43d5d263e7 117 */
hudakz 6:7edabed68b0f 118 void Clock::set(tm& val)
hudakz 6:7edabed68b0f 119 {
hudakz 6:7edabed68b0f 120 _ticker->detach(); // suspend ticks
hudakz 0:af43d5d263e7 121 _tm = val;
hudakz 6:7edabed68b0f 122 _ticker->attach_us(&tick, 1000000); // resume ticks
hudakz 0:af43d5d263e7 123 }
hudakz 0:af43d5d263e7 124
hudakz 0:af43d5d263e7 125 /**
hudakz 1:0668893c1c6f 126 * @brief Sets Clock to time_t value
hudakz 1:0668893c1c6f 127 * @note
hudakz 1:0668893c1c6f 128 * @param val: time_t structure (Number of seconds elapsed since January 1, 1970)
hudakz 1:0668893c1c6f 129 * @retval
hudakz 1:0668893c1c6f 130 */
hudakz 6:7edabed68b0f 131 void Clock::set(time_t val)
hudakz 6:7edabed68b0f 132 {
hudakz 6:7edabed68b0f 133 _ticker->detach(); // suspend ticks
hudakz 1:0668893c1c6f 134 _time = val;
hudakz 1:0668893c1c6f 135 _tm = *::localtime(&_time);
hudakz 6:7edabed68b0f 136 _ticker->attach_us(&tick, 1000000); // resume ticks
hudakz 1:0668893c1c6f 137 }
hudakz 1:0668893c1c6f 138
hudakz 1:0668893c1c6f 139 /**
hudakz 0:af43d5d263e7 140 * @brief Current time
hudakz 0:af43d5d263e7 141 * @note
hudakz 0:af43d5d263e7 142 * @param
hudakz 0:af43d5d263e7 143 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 144 */
hudakz 6:7edabed68b0f 145 time_t Clock::time(void)
hudakz 6:7edabed68b0f 146 {
hudakz 0:af43d5d263e7 147 return _time;
hudakz 0:af43d5d263e7 148 }
hudakz 0:af43d5d263e7 149
hudakz 0:af43d5d263e7 150 /**
hudakz 0:af43d5d263e7 151 * @brief Year
hudakz 0:af43d5d263e7 152 * @note
hudakz 0:af43d5d263e7 153 * @param
hudakz 0:af43d5d263e7 154 * @retval Year
hudakz 0:af43d5d263e7 155 */
hudakz 6:7edabed68b0f 156 int Clock::year(void)
hudakz 6:7edabed68b0f 157 {
hudakz 6:7edabed68b0f 158 return(_tm.tm_year + 1900);
hudakz 0:af43d5d263e7 159 }
hudakz 0:af43d5d263e7 160
hudakz 0:af43d5d263e7 161 /**
hudakz 0:af43d5d263e7 162 * @brief Month
hudakz 0:af43d5d263e7 163 * @note
hudakz 0:af43d5d263e7 164 * @param
hudakz 0:af43d5d263e7 165 * @retval Month
hudakz 0:af43d5d263e7 166 */
hudakz 6:7edabed68b0f 167 int Clock::mon(void)
hudakz 6:7edabed68b0f 168 {
hudakz 6:7edabed68b0f 169 return(_tm.tm_mon + 1);
hudakz 0:af43d5d263e7 170 }
hudakz 0:af43d5d263e7 171
hudakz 0:af43d5d263e7 172 /**
hudakz 0:af43d5d263e7 173 * @brief Day of month
hudakz 0:af43d5d263e7 174 * @note
hudakz 0:af43d5d263e7 175 * @param
hudakz 0:af43d5d263e7 176 * @retval Day of the month
hudakz 0:af43d5d263e7 177 */
hudakz 6:7edabed68b0f 178 int Clock::mday(void)
hudakz 6:7edabed68b0f 179 {
hudakz 0:af43d5d263e7 180 return _tm.tm_mday;
hudakz 0:af43d5d263e7 181 }
hudakz 0:af43d5d263e7 182
hudakz 0:af43d5d263e7 183 /**
hudakz 3:58f5afbd24cd 184 * @brief Day of week
hudakz 3:58f5afbd24cd 185 * @note
hudakz 3:58f5afbd24cd 186 * @param
hudakz 3:58f5afbd24cd 187 * @retval Day of week (Sunday = 0, Monday = 1, etc.)
hudakz 3:58f5afbd24cd 188 */
hudakz 6:7edabed68b0f 189 int Clock::wday(void)
hudakz 6:7edabed68b0f 190 {
hudakz 3:58f5afbd24cd 191 return _tm.tm_wday; // Sunday = 0, Monday = 1, etc.
hudakz 3:58f5afbd24cd 192 }
hudakz 3:58f5afbd24cd 193
hudakz 3:58f5afbd24cd 194 /**
hudakz 0:af43d5d263e7 195 * @brief Hour
hudakz 0:af43d5d263e7 196 * @note
hudakz 0:af43d5d263e7 197 * @param
hudakz 0:af43d5d263e7 198 * @retval Hour
hudakz 0:af43d5d263e7 199 */
hudakz 6:7edabed68b0f 200 int Clock::hour(void)
hudakz 6:7edabed68b0f 201 {
hudakz 0:af43d5d263e7 202 return _tm.tm_hour;
hudakz 0:af43d5d263e7 203 }
hudakz 0:af43d5d263e7 204
hudakz 0:af43d5d263e7 205 /**
hudakz 0:af43d5d263e7 206 * @brief Minutes
hudakz 0:af43d5d263e7 207 * @note
hudakz 0:af43d5d263e7 208 * @param
hudakz 0:af43d5d263e7 209 * @retval Minutes
hudakz 0:af43d5d263e7 210 */
hudakz 6:7edabed68b0f 211 int Clock::min(void)
hudakz 6:7edabed68b0f 212 {
hudakz 0:af43d5d263e7 213 return _tm.tm_min;
hudakz 0:af43d5d263e7 214 }
hudakz 0:af43d5d263e7 215
hudakz 0:af43d5d263e7 216 /**
hudakz 0:af43d5d263e7 217 * @brief Seconds
hudakz 0:af43d5d263e7 218 * @note
hudakz 0:af43d5d263e7 219 * @param
hudakz 0:af43d5d263e7 220 * @retval Seconds
hudakz 0:af43d5d263e7 221 */
hudakz 6:7edabed68b0f 222 int Clock::sec(void)
hudakz 6:7edabed68b0f 223 {
hudakz 0:af43d5d263e7 224 return _tm.tm_sec;
hudakz 0:af43d5d263e7 225 }
hudakz 0:af43d5d263e7 226
hudakz 0:af43d5d263e7 227 /**
hudakz 0:af43d5d263e7 228 * @brief Clock tick handler
hudakz 0:af43d5d263e7 229 * @note Called by the _ticker once per second
hudakz 0:af43d5d263e7 230 * Calls event handler if attached one by the user
hudakz 0:af43d5d263e7 231 * @param
hudakz 0:af43d5d263e7 232 * @retval
hudakz 0:af43d5d263e7 233 */
hudakz 6:7edabed68b0f 234 void Clock::tick(void)
hudakz 6:7edabed68b0f 235 {
hudakz 0:af43d5d263e7 236 _tm = *::localtime(&(++_time));
hudakz 5:d65fc7060635 237 _onTick.call();
hudakz 0:af43d5d263e7 238 }
hudakz 0:af43d5d263e7 239
hudakz 0:af43d5d263e7 240 /**
hudakz 0:af43d5d263e7 241 * @brief Attaches a handler to the onTick event
hudakz 0:af43d5d263e7 242 * @note onTick event occurs each second
hudakz 6:7edabed68b0f 243 * @param fnc User defined handler function of type 'void fnc(void)'
hudakz 0:af43d5d263e7 244 * @retval
hudakz 0:af43d5d263e7 245 */
hudakz 6:7edabed68b0f 246 void Clock::attach(void (*fptr) (void))
hudakz 6:7edabed68b0f 247 {
hudakz 6:7edabed68b0f 248 if (fptr)
hudakz 6:7edabed68b0f 249 _onTick = fptr;
hudakz 0:af43d5d263e7 250 }
hudakz 0:af43d5d263e7 251
hudakz 6:7edabed68b0f 252 /**
hudakz 6:7edabed68b0f 253 * @brief Attaches a class method as handler to the onTick event
hudakz 6:7edabed68b0f 254 * @note onTick event occurs each second
hudakz 6:7edabed68b0f 255 * @param tptr Pointer a class
hudakz 6:7edabed68b0f 256 * @param mptr Poiter to a 'void fnc(void)' method
hudakz 6:7edabed68b0f 257 * @retval
hudakz 6:7edabed68b0f 258 */
hudakz 6:7edabed68b0f 259 template<typename T>
hudakz 6:7edabed68b0f 260 void Clock::attach(T* tptr, void (T::*mptr) (void))
hudakz 6:7edabed68b0f 261 {
hudakz 6:7edabed68b0f 262 if ((tptr != NULL) && (mptr != NULL))
hudakz 6:7edabed68b0f 263 _onTick.attach(tptr, mptr);
hudakz 6:7edabed68b0f 264 }
hudakz 5:d65fc7060635 265
hudakz 0:af43d5d263e7 266 /**
hudakz 0:af43d5d263e7 267 * @brief Detaches handler function from the onTick event
hudakz 0:af43d5d263e7 268 * @note
hudakz 0:af43d5d263e7 269 * @param
hudakz 0:af43d5d263e7 270 * @retval
hudakz 0:af43d5d263e7 271 */
hudakz 6:7edabed68b0f 272 void Clock::detach()
hudakz 6:7edabed68b0f 273 {
hudakz 6:7edabed68b0f 274 _onTick = NULL;
hudakz 0:af43d5d263e7 275 }
hudakz 0:af43d5d263e7 276
hudakz 0:af43d5d263e7 277 /**
hudakz 0:af43d5d263e7 278 * @brief Converts human readable time to seconds elapsed since January 1, 1970
hudakz 6:7edabed68b0f 279 * @note A static helper function.
hudakz 0:af43d5d263e7 280 * @param year: long format (for instance 2015)
hudakz 6:7edabed68b0f 281 * @param mon: month (1 stands for January etc.)
hudakz 6:7edabed68b0f 282 * @param mday: day of month
hudakz 6:7edabed68b0f 283 * @param hour: 24hour format
hudakz 6:7edabed68b0f 284 * @param min: minutes
hudakz 6:7edabed68b0f 285 * @param ser: seconds
hudakz 0:af43d5d263e7 286 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 287 */
hudakz 6:7edabed68b0f 288 time_t Clock::asTime(int year, int mon, int mday, int hour, int min, int sec)
hudakz 6:7edabed68b0f 289 {
hudakz 0:af43d5d263e7 290 struct tm t;
hudakz 0:af43d5d263e7 291 t.tm_year = year - 1900;
hudakz 6:7edabed68b0f 292 t.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 293 t.tm_mday = mday;
hudakz 0:af43d5d263e7 294 t.tm_hour = hour;
hudakz 0:af43d5d263e7 295 t.tm_min = min;
hudakz 0:af43d5d263e7 296 t.tm_sec = sec;
hudakz 6:7edabed68b0f 297 t.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 6:7edabed68b0f 298 return mktime(&t); // returns seconds elapsed since January 1, 1970
hudakz 6:7edabed68b0f 299 }
hudakz 0:af43d5d263e7 300