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
Revision 2:46d52fa160b2, committed 2014-02-24
- Comitter:
- tmorgan
- Date:
- Mon Feb 24 20:48:50 2014 +0000
- Parent:
- 1:34f0bfc62803
- Commit message:
- Initial release.
Changed in this revision
TSI.lib | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 34f0bfc62803 -r 46d52fa160b2 TSI.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSI.lib Mon Feb 24 20:48:50 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/vsluiter/code/TSI/#4dc2f5a3a731
diff -r 34f0bfc62803 -r 46d52fa160b2 main.cpp --- a/main.cpp Mon Jan 27 21:58:45 2014 +0000 +++ b/main.cpp Mon Feb 24 20:48:50 2014 +0000 @@ -1,136 +1,234 @@ +/* + * LCD code based on FRDM-KL46Z-LCD-rtc-Demo by Paul Staron. + * Touch slider code based on serialSENS by Aaron Huang. + */ #include "mbed.h" #include "SLCD.h" +#include "TSISensor.h" -time_t seconds = time(NULL); // needed to start rtc on reset to maintain reasonable time if hard reset +// Peripherals +SLCD sLCD; +Serial pc(USBTX, USBRX); +TSISensor tsi; +DigitalOut greenLED(LED1); +DigitalOut redLED(LED2); +InterruptIn setModeSwitch (SW3); + +// FUNCTION-MODES +// In SET_HOURS mode, wait for slider touch to set hours, or SW3 press to enter SET_MINUTES mode. +// In SET_MINUTES mode, wait for slider touch to set minutes, or SW3 press to enter SET_SECONDS mode. +// In SET_SECONDS mode, wait for slider touch to set seconds, or SW3 press to enter SHOW_TIME mode. +// In SHOW_TIME mode, advance display state every seconds, or, on SW3 press, enter SET_HOURS mode. +#define SET_HOURS 0 +#define SET_MINUTES 1 +#define SET_SECONDS 2 +#define SHOW_TIME 3 +int function_mode; + +// TIME-DISPLAY STATES +// Show HH:MM from state SHOW_HHMM to state SHOW_SS, +// Show :SS from state SHOW_SS to state SHOW_LOOP +#define SHOW_HHMM 0 +#define SHOW_SS 5 +#define SHOW_LOOP 10 +int display_state; + +char LCDbuffer[32]; + +// Scroll instructions across the LCD +void scroll_message(void) +{ + char message[60] = " Press SW3 and touch slider to set time "; + + for (int start = 0; start < strlen(message) - 4; start++) + { + for (int digit = 0; digit < 4; digit++) + sLCD.putc(message[start + digit]); + wait(0.25); + } +} -SLCD slcd; -Timer scroll; -DigitalOut led1(LED1); -DigitalOut led2(LED2); -InterruptIn setmin (SW1); -InterruptIn sethour (SW3); +// Set Real-time Clock HH:MM:SS +void set_HHMMSS(int hours, int minutes, int seconds) +{ + struct tm t; + + if(hours > 23) hours = 0; + if(minutes > 59) minutes = 0; + t.tm_sec = seconds; + t.tm_min = minutes; + t.tm_hour = hours; + t.tm_mday = 23; + t.tm_mon = 2; + t.tm_year = 114; + set_time (mktime(&t)); +} + +// Read Real-time Clock HH:MM:SS +void get_HHMMSS(int *hours, int *minutes, int *seconds) +{ + time_t rtcTime = time(NULL); + struct tm *t = localtime(&rtcTime); + *hours = t->tm_hour; + *minutes = t->tm_min; + *seconds = t->tm_sec; +} + +// On SW3 press, cycle between function-modes +void setMode(void) +{ + if (function_mode == SET_HOURS) + function_mode = SET_MINUTES; + else if (function_mode == SET_MINUTES) + function_mode = SET_SECONDS; + else if (function_mode == SET_SECONDS) + function_mode = SHOW_TIME; + else if (function_mode == SHOW_TIME) + function_mode = SET_HOURS; +} + +// Wait for slider to be pressed (or mode change) +void waitForTouch(int mode) +{ + redLED = 0; + while(tsi.readDistance() == 0 && function_mode == mode) + { + wait(0.2); + redLED = !redLED; + } + redLED = 1; +} -struct tm t; +// Wait for slider to be released and return slider value between 0 and <scale> +int waitForRelease(char *label, int scale) +{ + float pct; + int return_value = 0; + + greenLED = 0; + while((pct = tsi.readPercentage()) != 0) + { + // In practice, readPercentage returns a number in the range 0.06..0.99 + // Stretch it to 0.00..0.99 before applying scale. + pct = (pct - 0.09)/ 0.90; + if (pct < 0.0) pct = 0.0; + return_value = scale * pct; + sLCD.printf("%2s%2i", label, return_value); + wait(0.2); + greenLED = !greenLED; + } + greenLED = 1; + return return_value; +} + +// If slider is touched, update hours +void setHours(void) +{ + int hours, minutes, seconds; + + get_HHMMSS(&hours, &minutes, &seconds); + sLCD.printf("HH%2i", hours); + waitForTouch(SET_HOURS); + if (function_mode == SET_HOURS) + { + hours = waitForRelease("HH",24); + pc.printf("Setting hours to %i\r\n", hours); + set_HHMMSS(hours, minutes, seconds); + function_mode = SHOW_TIME; + display_state = SHOW_HHMM; + } +} -int i,j,k,lastscroll,display_timer,minute,hour,colon,dp; -char message[60]; -void scroll_message(); -char buffer[32]; +// If slider is touched, update minutes +void setMinutes(void) +{ + int hours, minutes, seconds; + + get_HHMMSS(&hours, &minutes, &seconds); + sLCD.printf("MM%2i", minutes); + waitForTouch(SET_MINUTES); + if (function_mode == SET_MINUTES) + { + minutes = waitForRelease("MM",60); + pc.printf("Setting minutes to %i\r\n", minutes); + set_HHMMSS(hours, minutes, seconds); + function_mode = SHOW_TIME; + display_state = SHOW_HHMM; + } +} -void setminIRQ(); -void sethourIRQ(); +// If slider is touched, update seconds +void setSeconds(void) +{ + int hours, minutes, seconds; + + get_HHMMSS(&hours, &minutes, &seconds); + sLCD.printf("SS%2i", seconds); + waitForTouch(SET_SECONDS); + if (function_mode == SET_SECONDS) + { + seconds = waitForRelease("SS",60); + pc.printf("Setting seconds to %i\r\n", seconds); + set_HHMMSS(hours, minutes, seconds); + function_mode = SHOW_TIME; + display_state = SHOW_SS; + } +} +// Cycle between time-display states +// In states SHOW_HHMM to SHOW_SS - 1, display HH:MM & flash green LED. +// In states SHOW_SS to SHOW_LOOP, display :SS & flash red LED. +void showTime(void) +{ + DigitalOut *flashLED; + time_t rtcTime = time(NULL); + + if(display_state < SHOW_SS) + { + strftime(LCDbuffer, 4, "%H%M", localtime(&rtcTime));// display HH:MM + flashLED = &greenLED; // while flashing green LED + } + else + { + strftime(LCDbuffer, 4, " %S", localtime(&rtcTime));// display :SS + flashLED = &redLED; // while flashing red LED + } + sLCD.printf(LCDbuffer); // Send to LCD + redLED = 1; greenLED = 1; // Both LEDs off + wait(0.5); + *flashLED = 0; // Red or Green on. + wait(0.5); + redLED = 1; greenLED = 1; // Both LEDs off. + if (function_mode == SHOW_TIME) display_state++; // Increment display counter if no switch pressed + if (display_state > SHOW_LOOP) display_state = SHOW_HHMM; +} main() { - slcd.All_Segments(1); - wait(2); - slcd.All_Segments(0); - wait(1); + pc.printf("\r\n\nFRDM-KL46Z Clock\r\n"); - led1 = 1;led2 = 1; - - sprintf(message, " rtc clock s3 sets the hours s1 sets the minutes"); + sLCD.All_Segments(1); wait(1); // Flash LCD segments + sLCD.All_Segments(0); wait(1); -// scrolling message - scroll.start(); - while (i<58) { - - while (i<58) { - scroll_message(); - } - } - wait(1); + greenLED = 1; redLED = 1; // Both LEDs off + + scroll_message(); // Display instructions + + setModeSwitch.rise(setMode); // Enable setMode interrupt handler - setmin.rise(setminIRQ); // start set Minutes IRQ - sethour.rise(sethourIRQ); // start set Hours IRQ - -// rtc clock function - while(1) { - - time_t seconds = time(NULL); - - if(display_timer>6) { - strftime(buffer, 4, "%H%M", localtime(&seconds));// display Hours,Minutes for 2 seconds - slcd.Colon(1);led2=0; - slcd.DP2(0);led1=1; - } else { - strftime(buffer, 4, "%M%S", localtime(&seconds));// display Minutes,Seconds for 8 seconds - slcd.Colon(0);led2=1; - slcd.DP2(1);led1=0; - } - slcd.printf(buffer); - wait(.5); - slcd.DP2(0);led1=1; - display_timer++; - if (display_timer>9)display_timer=0; - wait(.5); + sLCD.Colon(1); sLCD.DP2(0); + function_mode = SHOW_TIME; + while(1) + { + if (function_mode == SET_HOURS) + setHours(); + else if (function_mode == SET_MINUTES) + setMinutes(); + else if (function_mode == SET_SECONDS) + setSeconds(); + else if (function_mode == SHOW_TIME) + showTime(); } } -void scroll_message() -{ - if (scroll.read_ms() > lastscroll + 350) { - scroll.reset(); - if (i > 58) { - i=0; - } - int j, k = i; - for (j = 0; j < 4; j++) { - if (message[k+j]) { - slcd.putc(message[k+j]); - } else { - slcd.putc(' '); - k--; - } - } - i++; - lastscroll=scroll.read_ms(); - } -} -void setminIRQ(void) // set Minutes ISR -{ - display_timer=7; - time_t seconds = time(NULL); - char buffer[2]; - strftime(buffer, 2,"%H", localtime(&seconds)); - hour = atoi(buffer); // get Hour integer - strftime(buffer, 2,"%M", localtime(&seconds)); - minute = atoi(buffer); // get Minutes integer - minute++; - if(minute>59) minute=0; - t.tm_sec = 0; // Seconds reset to zero - t.tm_min = minute; - t.tm_hour = hour; - t.tm_mday = 1; - t.tm_mon = 2; - t.tm_year = 114; - set_time (mktime(&t)); - -} - -void sethourIRQ(void) // set Hours ISR -{ - display_timer=7; - time_t seconds = time(NULL); - char buffer[2]; - strftime(buffer, 2,"%H", localtime(&seconds)); - hour = atoi(buffer); // get Hour integer - strftime(buffer, 2,"%M", localtime(&seconds)); - minute = atoi(buffer); // get Minutes integer - hour++; - if(hour>23) hour=0; - t.tm_sec = 0; // Seconds reset to zero - t.tm_min = minute; - t.tm_hour = hour; - t.tm_mday = 1; - t.tm_mon = 2; - t.tm_year = 114; - set_time (mktime(&t)); - -} - - - -