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:
Fri May 20 18:14:34 2016 +0000
Revision:
5:d65fc7060635
Parent:
4:bbe7d7474acd
Child:
6:7edabed68b0f
Added support for attaching member functions as interrupt handler.

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 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 5:d65fc7060635 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 5:d65fc7060635 35 FunctionPointer 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 5:d65fc7060635 51 _ticker.attach_us(&tick, 1000000); // 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 5:d65fc7060635 66 _ticker.attach_us(&tick, 1000000); // 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 5:d65fc7060635 83 _ticker.detach(); // suspend ticks
hudakz 0:af43d5d263e7 84 _tm.tm_year = year - 1900;
hudakz 5:d65fc7060635 85 _tm.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 86 _tm.tm_mday = mday;
hudakz 0:af43d5d263e7 87 _tm.tm_hour = hour;
hudakz 0:af43d5d263e7 88 _tm.tm_min = min;
hudakz 0:af43d5d263e7 89 _tm.tm_sec = sec;
hudakz 5:d65fc7060635 90 _tm.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 5:d65fc7060635 91 _time = mktime(&_tm); // convert to seconds elapsed since January 1, 1970
hudakz 5:d65fc7060635 92 set_time(_time); // set time
hudakz 5:d65fc7060635 93 _ticker.attach_us(&tick, 1000000); // resume ticks
hudakz 0:af43d5d263e7 94 }
hudakz 0:af43d5d263e7 95
hudakz 0:af43d5d263e7 96 /**
hudakz 0:af43d5d263e7 97 * @brief Sets Clock to tm value
hudakz 0:af43d5d263e7 98 * @note
hudakz 0:af43d5d263e7 99 * @param val: tm structure
hudakz 0:af43d5d263e7 100 * @retval
hudakz 0:af43d5d263e7 101 */
hudakz 0:af43d5d263e7 102 void Clock::set(tm& val) {
hudakz 5:d65fc7060635 103 _ticker.detach(); // suspend ticks
hudakz 0:af43d5d263e7 104 _tm = val;
hudakz 5:d65fc7060635 105 _ticker.attach_us(&tick, 1000000); // resume ticks
hudakz 0:af43d5d263e7 106 }
hudakz 0:af43d5d263e7 107
hudakz 0:af43d5d263e7 108 /**
hudakz 1:0668893c1c6f 109 * @brief Sets Clock to time_t value
hudakz 1:0668893c1c6f 110 * @note
hudakz 1:0668893c1c6f 111 * @param val: time_t structure (Number of seconds elapsed since January 1, 1970)
hudakz 1:0668893c1c6f 112 * @retval
hudakz 1:0668893c1c6f 113 */
hudakz 1:0668893c1c6f 114 void Clock::set(time_t val) {
hudakz 5:d65fc7060635 115 _ticker.detach(); // suspend ticks
hudakz 1:0668893c1c6f 116 _time = val;
hudakz 1:0668893c1c6f 117 _tm = *::localtime(&_time);
hudakz 5:d65fc7060635 118 _ticker.attach_us(&tick, 1000000); // resume ticks
hudakz 1:0668893c1c6f 119 }
hudakz 1:0668893c1c6f 120
hudakz 1:0668893c1c6f 121 /**
hudakz 0:af43d5d263e7 122 * @brief Current time
hudakz 0:af43d5d263e7 123 * @note
hudakz 0:af43d5d263e7 124 * @param
hudakz 0:af43d5d263e7 125 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 126 */
hudakz 0:af43d5d263e7 127 time_t Clock::time(void) {
hudakz 0:af43d5d263e7 128 return _time;
hudakz 0:af43d5d263e7 129 }
hudakz 0:af43d5d263e7 130
hudakz 0:af43d5d263e7 131 /**
hudakz 0:af43d5d263e7 132 * @brief Year
hudakz 0:af43d5d263e7 133 * @note
hudakz 0:af43d5d263e7 134 * @param
hudakz 0:af43d5d263e7 135 * @retval Year
hudakz 0:af43d5d263e7 136 */
hudakz 0:af43d5d263e7 137 int Clock::year(void) {
hudakz 0:af43d5d263e7 138 return (_tm.tm_year + 1900);
hudakz 0:af43d5d263e7 139 }
hudakz 0:af43d5d263e7 140
hudakz 0:af43d5d263e7 141 /**
hudakz 0:af43d5d263e7 142 * @brief Month
hudakz 0:af43d5d263e7 143 * @note
hudakz 0:af43d5d263e7 144 * @param
hudakz 0:af43d5d263e7 145 * @retval Month
hudakz 0:af43d5d263e7 146 */
hudakz 0:af43d5d263e7 147 int Clock::mon(void) {
hudakz 0:af43d5d263e7 148 return (_tm.tm_mon + 1);
hudakz 0:af43d5d263e7 149 }
hudakz 0:af43d5d263e7 150
hudakz 0:af43d5d263e7 151 /**
hudakz 0:af43d5d263e7 152 * @brief Day of month
hudakz 0:af43d5d263e7 153 * @note
hudakz 0:af43d5d263e7 154 * @param
hudakz 0:af43d5d263e7 155 * @retval Day of the month
hudakz 0:af43d5d263e7 156 */
hudakz 0:af43d5d263e7 157 int Clock::mday(void) {
hudakz 0:af43d5d263e7 158 return _tm.tm_mday;
hudakz 0:af43d5d263e7 159 }
hudakz 0:af43d5d263e7 160
hudakz 0:af43d5d263e7 161 /**
hudakz 3:58f5afbd24cd 162 * @brief Day of week
hudakz 3:58f5afbd24cd 163 * @note
hudakz 3:58f5afbd24cd 164 * @param
hudakz 3:58f5afbd24cd 165 * @retval Day of week (Sunday = 0, Monday = 1, etc.)
hudakz 3:58f5afbd24cd 166 */
hudakz 3:58f5afbd24cd 167 int Clock::wday(void) {
hudakz 3:58f5afbd24cd 168 return _tm.tm_wday; // Sunday = 0, Monday = 1, etc.
hudakz 3:58f5afbd24cd 169 }
hudakz 3:58f5afbd24cd 170
hudakz 3:58f5afbd24cd 171 /**
hudakz 0:af43d5d263e7 172 * @brief Hour
hudakz 0:af43d5d263e7 173 * @note
hudakz 0:af43d5d263e7 174 * @param
hudakz 0:af43d5d263e7 175 * @retval Hour
hudakz 0:af43d5d263e7 176 */
hudakz 0:af43d5d263e7 177 int Clock::hour(void) {
hudakz 0:af43d5d263e7 178 return _tm.tm_hour;
hudakz 0:af43d5d263e7 179 }
hudakz 0:af43d5d263e7 180
hudakz 0:af43d5d263e7 181 /**
hudakz 0:af43d5d263e7 182 * @brief Minutes
hudakz 0:af43d5d263e7 183 * @note
hudakz 0:af43d5d263e7 184 * @param
hudakz 0:af43d5d263e7 185 * @retval Minutes
hudakz 0:af43d5d263e7 186 */
hudakz 0:af43d5d263e7 187 int Clock::min(void) {
hudakz 0:af43d5d263e7 188 return _tm.tm_min;
hudakz 0:af43d5d263e7 189 }
hudakz 0:af43d5d263e7 190
hudakz 0:af43d5d263e7 191 /**
hudakz 0:af43d5d263e7 192 * @brief Seconds
hudakz 0:af43d5d263e7 193 * @note
hudakz 0:af43d5d263e7 194 * @param
hudakz 0:af43d5d263e7 195 * @retval Seconds
hudakz 0:af43d5d263e7 196 */
hudakz 0:af43d5d263e7 197 int Clock::sec(void) {
hudakz 0:af43d5d263e7 198 return _tm.tm_sec;
hudakz 0:af43d5d263e7 199 }
hudakz 0:af43d5d263e7 200
hudakz 0:af43d5d263e7 201 /**
hudakz 0:af43d5d263e7 202 * @brief Clock tick handler
hudakz 0:af43d5d263e7 203 * @note Called by the _ticker once per second
hudakz 0:af43d5d263e7 204 * Calls event handler if attached one by the user
hudakz 0:af43d5d263e7 205 * @param
hudakz 0:af43d5d263e7 206 * @retval
hudakz 0:af43d5d263e7 207 */
hudakz 0:af43d5d263e7 208 void Clock::tick(void) {
hudakz 0:af43d5d263e7 209 _tm = *::localtime(&(++_time));
hudakz 5:d65fc7060635 210 _onTick.call();
hudakz 0:af43d5d263e7 211 }
hudakz 0:af43d5d263e7 212
hudakz 0:af43d5d263e7 213
hudakz 0:af43d5d263e7 214 /**
hudakz 0:af43d5d263e7 215 * @brief Attaches a handler to the onTick event
hudakz 0:af43d5d263e7 216 * @note onTick event occurs each second
hudakz 0:af43d5d263e7 217 * @param fnc: User defined handler function of type void fnc(void)
hudakz 0:af43d5d263e7 218 * @retval
hudakz 0:af43d5d263e7 219 */
hudakz 5:d65fc7060635 220 void Clock::attach(void (*fptr)(void)) {
hudakz 5:d65fc7060635 221 if(fptr)
hudakz 5:d65fc7060635 222 _onTick.attach(fptr);
hudakz 0:af43d5d263e7 223 }
hudakz 0:af43d5d263e7 224
hudakz 5:d65fc7060635 225
hudakz 0:af43d5d263e7 226 /**
hudakz 0:af43d5d263e7 227 * @brief Detaches handler function from the onTick event
hudakz 0:af43d5d263e7 228 * @note
hudakz 0:af43d5d263e7 229 * @param
hudakz 0:af43d5d263e7 230 * @retval
hudakz 0:af43d5d263e7 231 */
hudakz 0:af43d5d263e7 232 void Clock::detach() {
hudakz 5:d65fc7060635 233 _onTick.attach(NULL);
hudakz 0:af43d5d263e7 234 }
hudakz 0:af43d5d263e7 235
hudakz 0:af43d5d263e7 236 /**
hudakz 0:af43d5d263e7 237 * @brief Converts human readable time to seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 238 * @note It's a static helper function.
hudakz 0:af43d5d263e7 239 * @param year: long format (for instance 2015)
hudakz 0:af43d5d263e7 240 * mon: month (1 stands for January etc.)
hudakz 0:af43d5d263e7 241 * mday: day of month
hudakz 0:af43d5d263e7 242 * hour: 24hour format
hudakz 0:af43d5d263e7 243 * min: minutes
hudakz 0:af43d5d263e7 244 * ser: seconds
hudakz 0:af43d5d263e7 245 * @retval Number of seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 246 */
hudakz 0:af43d5d263e7 247 time_t Clock::asTime(int year, int mon, int mday, int hour, int min, int sec) {
hudakz 0:af43d5d263e7 248 struct tm t;
hudakz 0:af43d5d263e7 249 t.tm_year = year - 1900;
hudakz 0:af43d5d263e7 250 t.tm_mon = mon - 1; // convert to 0 based month
hudakz 0:af43d5d263e7 251 t.tm_mday = mday;
hudakz 0:af43d5d263e7 252 t.tm_hour = hour;
hudakz 0:af43d5d263e7 253 t.tm_min = min;
hudakz 0:af43d5d263e7 254 t.tm_sec = sec;
hudakz 0:af43d5d263e7 255 t.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
hudakz 0:af43d5d263e7 256
hudakz 0:af43d5d263e7 257 return mktime(&t); // returns seconds elapsed since January 1, 1970
hudakz 0:af43d5d263e7 258 }