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:
Sat Nov 21 10:00:28 2015 +0000
Revision:
2:a18375196723
Parent:
1:0668893c1c6f
Child:
3:58f5afbd24cd
Updated

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 0:af43d5d263e7 7 This is a software implemented Clock.
hudakz 0:af43d5d263e7 8 No external parts are needed.
hudakz 0:af43d5d263e7 9
hudakz 1:0668893c1c6f 10 For how to use it have a look at <http://developer.mbed.org/users/hudakz/code/Hello_Clock/>
hudakz 0:af43d5d263e7 11
hudakz 0:af43d5d263e7 12 Copyright (c) 2015 Zoltan Hudak <hudakz@inbox.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
hudakz 0:af43d5d263e7 29 #include "mbed.h"
hudakz 0:af43d5d263e7 30 #include "Clock.h"
hudakz 0:af43d5d263e7 31
hudakz 0:af43d5d263e7 32 // static member initialization
hudakz 0:af43d5d263e7 33 time_t Clock::_time = 0;
hudakz 0:af43d5d263e7 34 tm Clock::_tm = {0, 0, 0, 0, 0, 0, -1};
hudakz 0:af43d5d263e7 35 ClockFnc_t Clock::_onTick = NULL;
hudakz 0:af43d5d263e7 36
hudakz 0:af43d5d263e7 37 /**
hudakz 0:af43d5d263e7 38 * @brief Constructs a Clock.
hudakz 0:af43d5d263e7 39 * @note The clock is driven by a Ticker.
hudakz 0:af43d5d263e7 40 * Since the Clock is attached as an external RTC
hudakz 0:af43d5d263e7 41 * standard C time functions can be called as well.
hudakz 0:af43d5d263e7 42 * @param year: long format (for instance 2015)
hudakz 0:af43d5d263e7 43 * mon: month (1 stands for January etc.)
hudakz 0:af43d5d263e7 44 * mday: day of month
hudakz 0:af43d5d263e7 45 * hour: 24hour format
hudakz 0:af43d5d263e7 46 * min: minutes
hudakz 0:af43d5d263e7 47 * ser: seconds
hudakz 0:af43d5d263e7 48 * @retval
hudakz 0:af43d5d263e7 49 */
hudakz 0:af43d5d263e7 50 Clock::Clock(int year, int mon, int mday, int hour, int min, int sec) {
hudakz 0:af43d5d263e7 51 _ticker.attach(&tick, 1.0); // a Ticker ticking at 1s rate
hudakz 2:a18375196723 52 set(year, mon, mday, hour, min, sec); // set date and time as requested
hudakz 2:a18375196723 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 0:af43d5d263e7 65 Clock::Clock() {
hudakz 0:af43d5d263e7 66 _ticker.attach(&tick, 1.0); // a Ticker ticking at 1s rate
hudakz 2:a18375196723 67 set(1970, 1, 1, 0, 0, 0); // set date and time to the begin of Epoch
hudakz 2:a18375196723 68 attach_rtc(time, NULL, NULL, NULL); // attach for C time functions
hudakz 0:af43d5d263e7 69 }
hudakz 0:af43d5d263e7 70
hudakz 0:af43d5d263e7 71 /**
hudakz 0:af43d5d263e7 72 * @brief Sets Clock time using human readable inputs
hudakz 0:af43d5d263e7 73 * @note
hudakz 0:af43d5d263e7 74 * @param year: long format (for instance 2015)
hudakz 0:af43d5d263e7 75 * mon: month (1 stands for January etc.)
hudakz 0:af43d5d263e7 76 * mday: day of month
hudakz 0:af43d5d263e7 77 * hour: 24hour format
hudakz 0:af43d5d263e7 78 * min: minutes
hudakz 0:af43d5d263e7 79 * ser: seconds
hudakz 0:af43d5d263e7 80 * @retval
hudakz 0:af43d5d263e7 81 */
hudakz 0:af43d5d263e7 82 void Clock::set(int year, int mon, int mday, int hour, int min, int sec) {
hudakz 0:af43d5d263e7 83 _ticker.detach(); // suspend ticks
hudakz 0:af43d5d263e7 84
hudakz 0:af43d5d263e7 85 _tm.tm_year = year - 1900;
hudakz 0:af43d5d263e7 86 _tm.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 87 _tm.tm_mday = mday;
hudakz 0:af43d5d263e7 88 _tm.tm_hour = hour;
hudakz 0:af43d5d263e7 89 _tm.tm_min = min;
hudakz 0:af43d5d263e7 90 _tm.tm_sec = sec;
hudakz 0:af43d5d263e7 91 _tm.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 0:af43d5d263e7 92
hudakz 0:af43d5d263e7 93 _time = mktime(&_tm); // convert to seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 94 set_time(_time); // set time
hudakz 0:af43d5d263e7 95
hudakz 0:af43d5d263e7 96 _ticker.attach(&tick, 1.0); // renew ticks
hudakz 0:af43d5d263e7 97 }
hudakz 0:af43d5d263e7 98
hudakz 0:af43d5d263e7 99 /**
hudakz 0:af43d5d263e7 100 * @brief Sets Clock to tm value
hudakz 0:af43d5d263e7 101 * @note
hudakz 0:af43d5d263e7 102 * @param val: tm structure
hudakz 0:af43d5d263e7 103 * @retval
hudakz 0:af43d5d263e7 104 */
hudakz 0:af43d5d263e7 105 void Clock::set(tm& val) {
hudakz 0:af43d5d263e7 106 _ticker.detach(); // suspend ticks
hudakz 0:af43d5d263e7 107 _tm = val;
hudakz 0:af43d5d263e7 108 _ticker.attach(&tick, 1.0); // renew ticks
hudakz 0:af43d5d263e7 109 }
hudakz 0:af43d5d263e7 110
hudakz 0:af43d5d263e7 111 /**
hudakz 1:0668893c1c6f 112 * @brief Sets Clock to time_t value
hudakz 1:0668893c1c6f 113 * @note
hudakz 1:0668893c1c6f 114 * @param val: time_t structure (Number of seconds elapsed since January 1, 1970)
hudakz 1:0668893c1c6f 115 * @retval
hudakz 1:0668893c1c6f 116 */
hudakz 1:0668893c1c6f 117 void Clock::set(time_t val) {
hudakz 1:0668893c1c6f 118 _ticker.detach(); // suspend ticks
hudakz 1:0668893c1c6f 119 _time = val;
hudakz 1:0668893c1c6f 120 _tm = *::localtime(&_time);
hudakz 1:0668893c1c6f 121 _ticker.attach(&tick, 1.0); // renew ticks
hudakz 1:0668893c1c6f 122 }
hudakz 1:0668893c1c6f 123
hudakz 1:0668893c1c6f 124 /**
hudakz 0:af43d5d263e7 125 * @brief Current time
hudakz 0:af43d5d263e7 126 * @note
hudakz 0:af43d5d263e7 127 * @param
hudakz 0:af43d5d263e7 128 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 129 */
hudakz 0:af43d5d263e7 130 time_t Clock::time(void) {
hudakz 0:af43d5d263e7 131 return _time;
hudakz 0:af43d5d263e7 132 }
hudakz 0:af43d5d263e7 133
hudakz 0:af43d5d263e7 134 /**
hudakz 0:af43d5d263e7 135 * @brief Year
hudakz 0:af43d5d263e7 136 * @note
hudakz 0:af43d5d263e7 137 * @param
hudakz 0:af43d5d263e7 138 * @retval Year
hudakz 0:af43d5d263e7 139 */
hudakz 0:af43d5d263e7 140 int Clock::year(void) {
hudakz 0:af43d5d263e7 141 return (_tm.tm_year + 1900);
hudakz 0:af43d5d263e7 142 }
hudakz 0:af43d5d263e7 143
hudakz 0:af43d5d263e7 144 /**
hudakz 0:af43d5d263e7 145 * @brief Month
hudakz 0:af43d5d263e7 146 * @note
hudakz 0:af43d5d263e7 147 * @param
hudakz 0:af43d5d263e7 148 * @retval Month
hudakz 0:af43d5d263e7 149 */
hudakz 0:af43d5d263e7 150 int Clock::mon(void) {
hudakz 0:af43d5d263e7 151 return (_tm.tm_mon + 1);
hudakz 0:af43d5d263e7 152 }
hudakz 0:af43d5d263e7 153
hudakz 0:af43d5d263e7 154 /**
hudakz 0:af43d5d263e7 155 * @brief Day of month
hudakz 0:af43d5d263e7 156 * @note
hudakz 0:af43d5d263e7 157 * @param
hudakz 0:af43d5d263e7 158 * @retval Day of the month
hudakz 0:af43d5d263e7 159 */
hudakz 0:af43d5d263e7 160 int Clock::mday(void) {
hudakz 0:af43d5d263e7 161 return _tm.tm_mday;
hudakz 0:af43d5d263e7 162 }
hudakz 0:af43d5d263e7 163
hudakz 0:af43d5d263e7 164 /**
hudakz 0:af43d5d263e7 165 * @brief Hour
hudakz 0:af43d5d263e7 166 * @note
hudakz 0:af43d5d263e7 167 * @param
hudakz 0:af43d5d263e7 168 * @retval Hour
hudakz 0:af43d5d263e7 169 */
hudakz 0:af43d5d263e7 170 int Clock::hour(void) {
hudakz 0:af43d5d263e7 171 return _tm.tm_hour;
hudakz 0:af43d5d263e7 172 }
hudakz 0:af43d5d263e7 173
hudakz 0:af43d5d263e7 174 /**
hudakz 0:af43d5d263e7 175 * @brief Minutes
hudakz 0:af43d5d263e7 176 * @note
hudakz 0:af43d5d263e7 177 * @param
hudakz 0:af43d5d263e7 178 * @retval Minutes
hudakz 0:af43d5d263e7 179 */
hudakz 0:af43d5d263e7 180 int Clock::min(void) {
hudakz 0:af43d5d263e7 181 return _tm.tm_min;
hudakz 0:af43d5d263e7 182 }
hudakz 0:af43d5d263e7 183
hudakz 0:af43d5d263e7 184 /**
hudakz 0:af43d5d263e7 185 * @brief Seconds
hudakz 0:af43d5d263e7 186 * @note
hudakz 0:af43d5d263e7 187 * @param
hudakz 0:af43d5d263e7 188 * @retval Seconds
hudakz 0:af43d5d263e7 189 */
hudakz 0:af43d5d263e7 190 int Clock::sec(void) {
hudakz 0:af43d5d263e7 191 return _tm.tm_sec;
hudakz 0:af43d5d263e7 192 }
hudakz 0:af43d5d263e7 193
hudakz 0:af43d5d263e7 194 /**
hudakz 0:af43d5d263e7 195 * @brief Clock tick handler
hudakz 0:af43d5d263e7 196 * @note Called by the _ticker once per second
hudakz 0:af43d5d263e7 197 * Calls event handler if attached one by the user
hudakz 0:af43d5d263e7 198 * @param
hudakz 0:af43d5d263e7 199 * @retval
hudakz 0:af43d5d263e7 200 */
hudakz 0:af43d5d263e7 201 void Clock::tick(void) {
hudakz 0:af43d5d263e7 202 _tm = *::localtime(&(++_time));
hudakz 0:af43d5d263e7 203
hudakz 0:af43d5d263e7 204 if(_onTick != NULL) // if a handler was attached by the user
hudakz 0:af43d5d263e7 205 _onTick(); // call it
hudakz 0:af43d5d263e7 206 }
hudakz 0:af43d5d263e7 207
hudakz 0:af43d5d263e7 208
hudakz 0:af43d5d263e7 209 /**
hudakz 0:af43d5d263e7 210 * @brief Attaches a handler to the onTick event
hudakz 0:af43d5d263e7 211 * @note onTick event occurs each second
hudakz 0:af43d5d263e7 212 * @param fnc: User defined handler function of type void fnc(void)
hudakz 0:af43d5d263e7 213 * @retval
hudakz 0:af43d5d263e7 214 */
hudakz 0:af43d5d263e7 215 void Clock::attach(ClockFnc_t fnc) {
hudakz 0:af43d5d263e7 216 _onTick = fnc;
hudakz 0:af43d5d263e7 217 }
hudakz 0:af43d5d263e7 218
hudakz 0:af43d5d263e7 219 /**
hudakz 0:af43d5d263e7 220 * @brief Detaches handler function from the onTick event
hudakz 0:af43d5d263e7 221 * @note
hudakz 0:af43d5d263e7 222 * @param
hudakz 0:af43d5d263e7 223 * @retval
hudakz 0:af43d5d263e7 224 */
hudakz 0:af43d5d263e7 225 void Clock::detach() {
hudakz 0:af43d5d263e7 226 _onTick = NULL;
hudakz 0:af43d5d263e7 227 }
hudakz 0:af43d5d263e7 228
hudakz 0:af43d5d263e7 229 /**
hudakz 0:af43d5d263e7 230 * @brief Converts human readable time to seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 231 * @note It's a static helper function.
hudakz 0:af43d5d263e7 232 * @param year: long format (for instance 2015)
hudakz 0:af43d5d263e7 233 * mon: month (1 stands for January etc.)
hudakz 0:af43d5d263e7 234 * mday: day of month
hudakz 0:af43d5d263e7 235 * hour: 24hour format
hudakz 0:af43d5d263e7 236 * min: minutes
hudakz 0:af43d5d263e7 237 * ser: seconds
hudakz 0:af43d5d263e7 238 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 239 */
hudakz 0:af43d5d263e7 240 time_t Clock::asTime(int year, int mon, int mday, int hour, int min, int sec) {
hudakz 0:af43d5d263e7 241 struct tm t;
hudakz 0:af43d5d263e7 242 t.tm_year = year - 1900;
hudakz 0:af43d5d263e7 243 t.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 244 t.tm_mday = mday;
hudakz 0:af43d5d263e7 245 t.tm_hour = hour;
hudakz 0:af43d5d263e7 246 t.tm_min = min;
hudakz 0:af43d5d263e7 247 t.tm_sec = sec;
hudakz 0:af43d5d263e7 248 t.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 0:af43d5d263e7 249
hudakz 0:af43d5d263e7 250 return mktime(&t); // returns seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 251 }