FRDM-KL46Z clock based on Paul Staron's FRDM-KL46Z-LCD-rtc-demo. Uses the on-board touch slider to set hours, minutes and seconds.
Dependencies: SLCD TSI mbed-src
Fork of FRDM-KL46Z-Clock by
main.cpp@2:46d52fa160b2, 2014-02-24 (annotated)
- Committer:
- tmorgan
- Date:
- Mon Feb 24 20:48:50 2014 +0000
- Revision:
- 2:46d52fa160b2
- Parent:
- 1:34f0bfc62803
Initial release.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tmorgan | 2:46d52fa160b2 | 1 | /* |
tmorgan | 2:46d52fa160b2 | 2 | * LCD code based on FRDM-KL46Z-LCD-rtc-Demo by Paul Staron. |
tmorgan | 2:46d52fa160b2 | 3 | * Touch slider code based on serialSENS by Aaron Huang. |
tmorgan | 2:46d52fa160b2 | 4 | */ |
star297 | 0:4f67859595b2 | 5 | #include "mbed.h" |
star297 | 0:4f67859595b2 | 6 | #include "SLCD.h" |
tmorgan | 2:46d52fa160b2 | 7 | #include "TSISensor.h" |
star297 | 0:4f67859595b2 | 8 | |
tmorgan | 2:46d52fa160b2 | 9 | // Peripherals |
tmorgan | 2:46d52fa160b2 | 10 | SLCD sLCD; |
tmorgan | 2:46d52fa160b2 | 11 | Serial pc(USBTX, USBRX); |
tmorgan | 2:46d52fa160b2 | 12 | TSISensor tsi; |
tmorgan | 2:46d52fa160b2 | 13 | DigitalOut greenLED(LED1); |
tmorgan | 2:46d52fa160b2 | 14 | DigitalOut redLED(LED2); |
tmorgan | 2:46d52fa160b2 | 15 | InterruptIn setModeSwitch (SW3); |
tmorgan | 2:46d52fa160b2 | 16 | |
tmorgan | 2:46d52fa160b2 | 17 | // FUNCTION-MODES |
tmorgan | 2:46d52fa160b2 | 18 | // In SET_HOURS mode, wait for slider touch to set hours, or SW3 press to enter SET_MINUTES mode. |
tmorgan | 2:46d52fa160b2 | 19 | // In SET_MINUTES mode, wait for slider touch to set minutes, or SW3 press to enter SET_SECONDS mode. |
tmorgan | 2:46d52fa160b2 | 20 | // In SET_SECONDS mode, wait for slider touch to set seconds, or SW3 press to enter SHOW_TIME mode. |
tmorgan | 2:46d52fa160b2 | 21 | // In SHOW_TIME mode, advance display state every seconds, or, on SW3 press, enter SET_HOURS mode. |
tmorgan | 2:46d52fa160b2 | 22 | #define SET_HOURS 0 |
tmorgan | 2:46d52fa160b2 | 23 | #define SET_MINUTES 1 |
tmorgan | 2:46d52fa160b2 | 24 | #define SET_SECONDS 2 |
tmorgan | 2:46d52fa160b2 | 25 | #define SHOW_TIME 3 |
tmorgan | 2:46d52fa160b2 | 26 | int function_mode; |
tmorgan | 2:46d52fa160b2 | 27 | |
tmorgan | 2:46d52fa160b2 | 28 | // TIME-DISPLAY STATES |
tmorgan | 2:46d52fa160b2 | 29 | // Show HH:MM from state SHOW_HHMM to state SHOW_SS, |
tmorgan | 2:46d52fa160b2 | 30 | // Show :SS from state SHOW_SS to state SHOW_LOOP |
tmorgan | 2:46d52fa160b2 | 31 | #define SHOW_HHMM 0 |
tmorgan | 2:46d52fa160b2 | 32 | #define SHOW_SS 5 |
tmorgan | 2:46d52fa160b2 | 33 | #define SHOW_LOOP 10 |
tmorgan | 2:46d52fa160b2 | 34 | int display_state; |
tmorgan | 2:46d52fa160b2 | 35 | |
tmorgan | 2:46d52fa160b2 | 36 | char LCDbuffer[32]; |
tmorgan | 2:46d52fa160b2 | 37 | |
tmorgan | 2:46d52fa160b2 | 38 | // Scroll instructions across the LCD |
tmorgan | 2:46d52fa160b2 | 39 | void scroll_message(void) |
tmorgan | 2:46d52fa160b2 | 40 | { |
tmorgan | 2:46d52fa160b2 | 41 | char message[60] = " Press SW3 and touch slider to set time "; |
tmorgan | 2:46d52fa160b2 | 42 | |
tmorgan | 2:46d52fa160b2 | 43 | for (int start = 0; start < strlen(message) - 4; start++) |
tmorgan | 2:46d52fa160b2 | 44 | { |
tmorgan | 2:46d52fa160b2 | 45 | for (int digit = 0; digit < 4; digit++) |
tmorgan | 2:46d52fa160b2 | 46 | sLCD.putc(message[start + digit]); |
tmorgan | 2:46d52fa160b2 | 47 | wait(0.25); |
tmorgan | 2:46d52fa160b2 | 48 | } |
tmorgan | 2:46d52fa160b2 | 49 | } |
star297 | 0:4f67859595b2 | 50 | |
tmorgan | 2:46d52fa160b2 | 51 | // Set Real-time Clock HH:MM:SS |
tmorgan | 2:46d52fa160b2 | 52 | void set_HHMMSS(int hours, int minutes, int seconds) |
tmorgan | 2:46d52fa160b2 | 53 | { |
tmorgan | 2:46d52fa160b2 | 54 | struct tm t; |
tmorgan | 2:46d52fa160b2 | 55 | |
tmorgan | 2:46d52fa160b2 | 56 | if(hours > 23) hours = 0; |
tmorgan | 2:46d52fa160b2 | 57 | if(minutes > 59) minutes = 0; |
tmorgan | 2:46d52fa160b2 | 58 | t.tm_sec = seconds; |
tmorgan | 2:46d52fa160b2 | 59 | t.tm_min = minutes; |
tmorgan | 2:46d52fa160b2 | 60 | t.tm_hour = hours; |
tmorgan | 2:46d52fa160b2 | 61 | t.tm_mday = 23; |
tmorgan | 2:46d52fa160b2 | 62 | t.tm_mon = 2; |
tmorgan | 2:46d52fa160b2 | 63 | t.tm_year = 114; |
tmorgan | 2:46d52fa160b2 | 64 | set_time (mktime(&t)); |
tmorgan | 2:46d52fa160b2 | 65 | } |
tmorgan | 2:46d52fa160b2 | 66 | |
tmorgan | 2:46d52fa160b2 | 67 | // Read Real-time Clock HH:MM:SS |
tmorgan | 2:46d52fa160b2 | 68 | void get_HHMMSS(int *hours, int *minutes, int *seconds) |
tmorgan | 2:46d52fa160b2 | 69 | { |
tmorgan | 2:46d52fa160b2 | 70 | time_t rtcTime = time(NULL); |
tmorgan | 2:46d52fa160b2 | 71 | struct tm *t = localtime(&rtcTime); |
tmorgan | 2:46d52fa160b2 | 72 | *hours = t->tm_hour; |
tmorgan | 2:46d52fa160b2 | 73 | *minutes = t->tm_min; |
tmorgan | 2:46d52fa160b2 | 74 | *seconds = t->tm_sec; |
tmorgan | 2:46d52fa160b2 | 75 | } |
tmorgan | 2:46d52fa160b2 | 76 | |
tmorgan | 2:46d52fa160b2 | 77 | // On SW3 press, cycle between function-modes |
tmorgan | 2:46d52fa160b2 | 78 | void setMode(void) |
tmorgan | 2:46d52fa160b2 | 79 | { |
tmorgan | 2:46d52fa160b2 | 80 | if (function_mode == SET_HOURS) |
tmorgan | 2:46d52fa160b2 | 81 | function_mode = SET_MINUTES; |
tmorgan | 2:46d52fa160b2 | 82 | else if (function_mode == SET_MINUTES) |
tmorgan | 2:46d52fa160b2 | 83 | function_mode = SET_SECONDS; |
tmorgan | 2:46d52fa160b2 | 84 | else if (function_mode == SET_SECONDS) |
tmorgan | 2:46d52fa160b2 | 85 | function_mode = SHOW_TIME; |
tmorgan | 2:46d52fa160b2 | 86 | else if (function_mode == SHOW_TIME) |
tmorgan | 2:46d52fa160b2 | 87 | function_mode = SET_HOURS; |
tmorgan | 2:46d52fa160b2 | 88 | } |
tmorgan | 2:46d52fa160b2 | 89 | |
tmorgan | 2:46d52fa160b2 | 90 | // Wait for slider to be pressed (or mode change) |
tmorgan | 2:46d52fa160b2 | 91 | void waitForTouch(int mode) |
tmorgan | 2:46d52fa160b2 | 92 | { |
tmorgan | 2:46d52fa160b2 | 93 | redLED = 0; |
tmorgan | 2:46d52fa160b2 | 94 | while(tsi.readDistance() == 0 && function_mode == mode) |
tmorgan | 2:46d52fa160b2 | 95 | { |
tmorgan | 2:46d52fa160b2 | 96 | wait(0.2); |
tmorgan | 2:46d52fa160b2 | 97 | redLED = !redLED; |
tmorgan | 2:46d52fa160b2 | 98 | } |
tmorgan | 2:46d52fa160b2 | 99 | redLED = 1; |
tmorgan | 2:46d52fa160b2 | 100 | } |
star297 | 0:4f67859595b2 | 101 | |
tmorgan | 2:46d52fa160b2 | 102 | // Wait for slider to be released and return slider value between 0 and <scale> |
tmorgan | 2:46d52fa160b2 | 103 | int waitForRelease(char *label, int scale) |
tmorgan | 2:46d52fa160b2 | 104 | { |
tmorgan | 2:46d52fa160b2 | 105 | float pct; |
tmorgan | 2:46d52fa160b2 | 106 | int return_value = 0; |
tmorgan | 2:46d52fa160b2 | 107 | |
tmorgan | 2:46d52fa160b2 | 108 | greenLED = 0; |
tmorgan | 2:46d52fa160b2 | 109 | while((pct = tsi.readPercentage()) != 0) |
tmorgan | 2:46d52fa160b2 | 110 | { |
tmorgan | 2:46d52fa160b2 | 111 | // In practice, readPercentage returns a number in the range 0.06..0.99 |
tmorgan | 2:46d52fa160b2 | 112 | // Stretch it to 0.00..0.99 before applying scale. |
tmorgan | 2:46d52fa160b2 | 113 | pct = (pct - 0.09)/ 0.90; |
tmorgan | 2:46d52fa160b2 | 114 | if (pct < 0.0) pct = 0.0; |
tmorgan | 2:46d52fa160b2 | 115 | return_value = scale * pct; |
tmorgan | 2:46d52fa160b2 | 116 | sLCD.printf("%2s%2i", label, return_value); |
tmorgan | 2:46d52fa160b2 | 117 | wait(0.2); |
tmorgan | 2:46d52fa160b2 | 118 | greenLED = !greenLED; |
tmorgan | 2:46d52fa160b2 | 119 | } |
tmorgan | 2:46d52fa160b2 | 120 | greenLED = 1; |
tmorgan | 2:46d52fa160b2 | 121 | return return_value; |
tmorgan | 2:46d52fa160b2 | 122 | } |
tmorgan | 2:46d52fa160b2 | 123 | |
tmorgan | 2:46d52fa160b2 | 124 | // If slider is touched, update hours |
tmorgan | 2:46d52fa160b2 | 125 | void setHours(void) |
tmorgan | 2:46d52fa160b2 | 126 | { |
tmorgan | 2:46d52fa160b2 | 127 | int hours, minutes, seconds; |
tmorgan | 2:46d52fa160b2 | 128 | |
tmorgan | 2:46d52fa160b2 | 129 | get_HHMMSS(&hours, &minutes, &seconds); |
tmorgan | 2:46d52fa160b2 | 130 | sLCD.printf("HH%2i", hours); |
tmorgan | 2:46d52fa160b2 | 131 | waitForTouch(SET_HOURS); |
tmorgan | 2:46d52fa160b2 | 132 | if (function_mode == SET_HOURS) |
tmorgan | 2:46d52fa160b2 | 133 | { |
tmorgan | 2:46d52fa160b2 | 134 | hours = waitForRelease("HH",24); |
tmorgan | 2:46d52fa160b2 | 135 | pc.printf("Setting hours to %i\r\n", hours); |
tmorgan | 2:46d52fa160b2 | 136 | set_HHMMSS(hours, minutes, seconds); |
tmorgan | 2:46d52fa160b2 | 137 | function_mode = SHOW_TIME; |
tmorgan | 2:46d52fa160b2 | 138 | display_state = SHOW_HHMM; |
tmorgan | 2:46d52fa160b2 | 139 | } |
tmorgan | 2:46d52fa160b2 | 140 | } |
star297 | 0:4f67859595b2 | 141 | |
tmorgan | 2:46d52fa160b2 | 142 | // If slider is touched, update minutes |
tmorgan | 2:46d52fa160b2 | 143 | void setMinutes(void) |
tmorgan | 2:46d52fa160b2 | 144 | { |
tmorgan | 2:46d52fa160b2 | 145 | int hours, minutes, seconds; |
tmorgan | 2:46d52fa160b2 | 146 | |
tmorgan | 2:46d52fa160b2 | 147 | get_HHMMSS(&hours, &minutes, &seconds); |
tmorgan | 2:46d52fa160b2 | 148 | sLCD.printf("MM%2i", minutes); |
tmorgan | 2:46d52fa160b2 | 149 | waitForTouch(SET_MINUTES); |
tmorgan | 2:46d52fa160b2 | 150 | if (function_mode == SET_MINUTES) |
tmorgan | 2:46d52fa160b2 | 151 | { |
tmorgan | 2:46d52fa160b2 | 152 | minutes = waitForRelease("MM",60); |
tmorgan | 2:46d52fa160b2 | 153 | pc.printf("Setting minutes to %i\r\n", minutes); |
tmorgan | 2:46d52fa160b2 | 154 | set_HHMMSS(hours, minutes, seconds); |
tmorgan | 2:46d52fa160b2 | 155 | function_mode = SHOW_TIME; |
tmorgan | 2:46d52fa160b2 | 156 | display_state = SHOW_HHMM; |
tmorgan | 2:46d52fa160b2 | 157 | } |
tmorgan | 2:46d52fa160b2 | 158 | } |
star297 | 0:4f67859595b2 | 159 | |
tmorgan | 2:46d52fa160b2 | 160 | // If slider is touched, update seconds |
tmorgan | 2:46d52fa160b2 | 161 | void setSeconds(void) |
tmorgan | 2:46d52fa160b2 | 162 | { |
tmorgan | 2:46d52fa160b2 | 163 | int hours, minutes, seconds; |
tmorgan | 2:46d52fa160b2 | 164 | |
tmorgan | 2:46d52fa160b2 | 165 | get_HHMMSS(&hours, &minutes, &seconds); |
tmorgan | 2:46d52fa160b2 | 166 | sLCD.printf("SS%2i", seconds); |
tmorgan | 2:46d52fa160b2 | 167 | waitForTouch(SET_SECONDS); |
tmorgan | 2:46d52fa160b2 | 168 | if (function_mode == SET_SECONDS) |
tmorgan | 2:46d52fa160b2 | 169 | { |
tmorgan | 2:46d52fa160b2 | 170 | seconds = waitForRelease("SS",60); |
tmorgan | 2:46d52fa160b2 | 171 | pc.printf("Setting seconds to %i\r\n", seconds); |
tmorgan | 2:46d52fa160b2 | 172 | set_HHMMSS(hours, minutes, seconds); |
tmorgan | 2:46d52fa160b2 | 173 | function_mode = SHOW_TIME; |
tmorgan | 2:46d52fa160b2 | 174 | display_state = SHOW_SS; |
tmorgan | 2:46d52fa160b2 | 175 | } |
tmorgan | 2:46d52fa160b2 | 176 | } |
star297 | 0:4f67859595b2 | 177 | |
tmorgan | 2:46d52fa160b2 | 178 | // Cycle between time-display states |
tmorgan | 2:46d52fa160b2 | 179 | // In states SHOW_HHMM to SHOW_SS - 1, display HH:MM & flash green LED. |
tmorgan | 2:46d52fa160b2 | 180 | // In states SHOW_SS to SHOW_LOOP, display :SS & flash red LED. |
tmorgan | 2:46d52fa160b2 | 181 | void showTime(void) |
tmorgan | 2:46d52fa160b2 | 182 | { |
tmorgan | 2:46d52fa160b2 | 183 | DigitalOut *flashLED; |
tmorgan | 2:46d52fa160b2 | 184 | time_t rtcTime = time(NULL); |
tmorgan | 2:46d52fa160b2 | 185 | |
tmorgan | 2:46d52fa160b2 | 186 | if(display_state < SHOW_SS) |
tmorgan | 2:46d52fa160b2 | 187 | { |
tmorgan | 2:46d52fa160b2 | 188 | strftime(LCDbuffer, 4, "%H%M", localtime(&rtcTime));// display HH:MM |
tmorgan | 2:46d52fa160b2 | 189 | flashLED = &greenLED; // while flashing green LED |
tmorgan | 2:46d52fa160b2 | 190 | } |
tmorgan | 2:46d52fa160b2 | 191 | else |
tmorgan | 2:46d52fa160b2 | 192 | { |
tmorgan | 2:46d52fa160b2 | 193 | strftime(LCDbuffer, 4, " %S", localtime(&rtcTime));// display :SS |
tmorgan | 2:46d52fa160b2 | 194 | flashLED = &redLED; // while flashing red LED |
tmorgan | 2:46d52fa160b2 | 195 | } |
tmorgan | 2:46d52fa160b2 | 196 | sLCD.printf(LCDbuffer); // Send to LCD |
tmorgan | 2:46d52fa160b2 | 197 | redLED = 1; greenLED = 1; // Both LEDs off |
tmorgan | 2:46d52fa160b2 | 198 | wait(0.5); |
tmorgan | 2:46d52fa160b2 | 199 | *flashLED = 0; // Red or Green on. |
tmorgan | 2:46d52fa160b2 | 200 | wait(0.5); |
tmorgan | 2:46d52fa160b2 | 201 | redLED = 1; greenLED = 1; // Both LEDs off. |
tmorgan | 2:46d52fa160b2 | 202 | if (function_mode == SHOW_TIME) display_state++; // Increment display counter if no switch pressed |
tmorgan | 2:46d52fa160b2 | 203 | if (display_state > SHOW_LOOP) display_state = SHOW_HHMM; |
tmorgan | 2:46d52fa160b2 | 204 | } |
star297 | 0:4f67859595b2 | 205 | |
star297 | 0:4f67859595b2 | 206 | main() |
star297 | 1:34f0bfc62803 | 207 | { |
tmorgan | 2:46d52fa160b2 | 208 | pc.printf("\r\n\nFRDM-KL46Z Clock\r\n"); |
star297 | 1:34f0bfc62803 | 209 | |
tmorgan | 2:46d52fa160b2 | 210 | sLCD.All_Segments(1); wait(1); // Flash LCD segments |
tmorgan | 2:46d52fa160b2 | 211 | sLCD.All_Segments(0); wait(1); |
star297 | 0:4f67859595b2 | 212 | |
tmorgan | 2:46d52fa160b2 | 213 | greenLED = 1; redLED = 1; // Both LEDs off |
tmorgan | 2:46d52fa160b2 | 214 | |
tmorgan | 2:46d52fa160b2 | 215 | scroll_message(); // Display instructions |
tmorgan | 2:46d52fa160b2 | 216 | |
tmorgan | 2:46d52fa160b2 | 217 | setModeSwitch.rise(setMode); // Enable setMode interrupt handler |
star297 | 1:34f0bfc62803 | 218 | |
tmorgan | 2:46d52fa160b2 | 219 | sLCD.Colon(1); sLCD.DP2(0); |
tmorgan | 2:46d52fa160b2 | 220 | function_mode = SHOW_TIME; |
tmorgan | 2:46d52fa160b2 | 221 | while(1) |
tmorgan | 2:46d52fa160b2 | 222 | { |
tmorgan | 2:46d52fa160b2 | 223 | if (function_mode == SET_HOURS) |
tmorgan | 2:46d52fa160b2 | 224 | setHours(); |
tmorgan | 2:46d52fa160b2 | 225 | else if (function_mode == SET_MINUTES) |
tmorgan | 2:46d52fa160b2 | 226 | setMinutes(); |
tmorgan | 2:46d52fa160b2 | 227 | else if (function_mode == SET_SECONDS) |
tmorgan | 2:46d52fa160b2 | 228 | setSeconds(); |
tmorgan | 2:46d52fa160b2 | 229 | else if (function_mode == SHOW_TIME) |
tmorgan | 2:46d52fa160b2 | 230 | showTime(); |
star297 | 0:4f67859595b2 | 231 | } |
star297 | 1:34f0bfc62803 | 232 | } |
star297 | 0:4f67859595b2 | 233 | |
star297 | 0:4f67859595b2 | 234 |