Yu-Cheng MBED
Dependencies: SLCD TSI mbed-src
Fork of FRDM-KL46Z-Clock by
main.cpp
- Committer:
- tmorgan
- Date:
- 2014-02-24
- Revision:
- 2:46d52fa160b2
- Parent:
- 1:34f0bfc62803
- Child:
- 3:586be3d0341d
File content as of revision 2:46d52fa160b2:
/* * 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" // 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); } } // 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; } // 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; } } // 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; } } // 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() { pc.printf("\r\n\nFRDM-KL46Z Clock\r\n"); sLCD.All_Segments(1); wait(1); // Flash LCD segments sLCD.All_Segments(0); wait(1); greenLED = 1; redLED = 1; // Both LEDs off scroll_message(); // Display instructions setModeSwitch.rise(setMode); // Enable setMode interrupt handler 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(); } }