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 LCD rtc Demo by
main.cpp
00001 /* 00002 * LCD code based on FRDM-KL46Z-LCD-rtc-Demo by Paul Staron. 00003 * Touch slider code based on serialSENS by Aaron Huang. 00004 */ 00005 #include "mbed.h" 00006 #include "SLCD.h" 00007 #include "TSISensor.h" 00008 00009 // Peripherals 00010 SLCD sLCD; 00011 Serial pc(USBTX, USBRX); 00012 TSISensor tsi; 00013 DigitalOut greenLED(LED1); 00014 DigitalOut redLED(LED2); 00015 InterruptIn setModeSwitch (SW3); 00016 00017 // FUNCTION-MODES 00018 // In SET_HOURS mode, wait for slider touch to set hours, or SW3 press to enter SET_MINUTES mode. 00019 // In SET_MINUTES mode, wait for slider touch to set minutes, or SW3 press to enter SET_SECONDS mode. 00020 // In SET_SECONDS mode, wait for slider touch to set seconds, or SW3 press to enter SHOW_TIME mode. 00021 // In SHOW_TIME mode, advance display state every seconds, or, on SW3 press, enter SET_HOURS mode. 00022 #define SET_HOURS 0 00023 #define SET_MINUTES 1 00024 #define SET_SECONDS 2 00025 #define SHOW_TIME 3 00026 int function_mode; 00027 00028 // TIME-DISPLAY STATES 00029 // Show HH:MM from state SHOW_HHMM to state SHOW_SS, 00030 // Show :SS from state SHOW_SS to state SHOW_LOOP 00031 #define SHOW_HHMM 0 00032 #define SHOW_SS 5 00033 #define SHOW_LOOP 10 00034 int display_state; 00035 00036 char LCDbuffer[32]; 00037 00038 // Scroll instructions across the LCD 00039 void scroll_message(void) 00040 { 00041 char message[60] = " Press SW3 and touch slider to set time "; 00042 00043 for (int start = 0; start < strlen(message) - 4; start++) 00044 { 00045 for (int digit = 0; digit < 4; digit++) 00046 sLCD.putc(message[start + digit]); 00047 wait(0.25); 00048 } 00049 } 00050 00051 // Set Real-time Clock HH:MM:SS 00052 void set_HHMMSS(int hours, int minutes, int seconds) 00053 { 00054 struct tm t; 00055 00056 if(hours > 23) hours = 0; 00057 if(minutes > 59) minutes = 0; 00058 t.tm_sec = seconds; 00059 t.tm_min = minutes; 00060 t.tm_hour = hours; 00061 t.tm_mday = 23; 00062 t.tm_mon = 2; 00063 t.tm_year = 114; 00064 set_time (mktime(&t)); 00065 } 00066 00067 // Read Real-time Clock HH:MM:SS 00068 void get_HHMMSS(int *hours, int *minutes, int *seconds) 00069 { 00070 time_t rtcTime = time(NULL); 00071 struct tm *t = localtime(&rtcTime); 00072 *hours = t->tm_hour; 00073 *minutes = t->tm_min; 00074 *seconds = t->tm_sec; 00075 } 00076 00077 // On SW3 press, cycle between function-modes 00078 void setMode(void) 00079 { 00080 if (function_mode == SET_HOURS) 00081 function_mode = SET_MINUTES; 00082 else if (function_mode == SET_MINUTES) 00083 function_mode = SET_SECONDS; 00084 else if (function_mode == SET_SECONDS) 00085 function_mode = SHOW_TIME; 00086 else if (function_mode == SHOW_TIME) 00087 function_mode = SET_HOURS; 00088 } 00089 00090 // Wait for slider to be pressed (or mode change) 00091 void waitForTouch(int mode) 00092 { 00093 redLED = 0; 00094 while(tsi.readDistance() == 0 && function_mode == mode) 00095 { 00096 wait(0.2); 00097 redLED = !redLED; 00098 } 00099 redLED = 1; 00100 } 00101 00102 // Wait for slider to be released and return slider value between 0 and <scale> 00103 int waitForRelease(char *label, int scale) 00104 { 00105 float pct; 00106 int return_value = 0; 00107 00108 greenLED = 0; 00109 while((pct = tsi.readPercentage()) != 0) 00110 { 00111 // In practice, readPercentage returns a number in the range 0.06..0.99 00112 // Stretch it to 0.00..0.99 before applying scale. 00113 pct = (pct - 0.09)/ 0.90; 00114 if (pct < 0.0) pct = 0.0; 00115 return_value = scale * pct; 00116 sLCD.printf("%2s%2i", label, return_value); 00117 wait(0.2); 00118 greenLED = !greenLED; 00119 } 00120 greenLED = 1; 00121 return return_value; 00122 } 00123 00124 // If slider is touched, update hours 00125 void setHours(void) 00126 { 00127 int hours, minutes, seconds; 00128 00129 get_HHMMSS(&hours, &minutes, &seconds); 00130 sLCD.printf("HH%2i", hours); 00131 waitForTouch(SET_HOURS); 00132 if (function_mode == SET_HOURS) 00133 { 00134 hours = waitForRelease("HH",24); 00135 pc.printf("Setting hours to %i\r\n", hours); 00136 set_HHMMSS(hours, minutes, seconds); 00137 function_mode = SHOW_TIME; 00138 display_state = SHOW_HHMM; 00139 } 00140 } 00141 00142 // If slider is touched, update minutes 00143 void setMinutes(void) 00144 { 00145 int hours, minutes, seconds; 00146 00147 get_HHMMSS(&hours, &minutes, &seconds); 00148 sLCD.printf("MM%2i", minutes); 00149 waitForTouch(SET_MINUTES); 00150 if (function_mode == SET_MINUTES) 00151 { 00152 minutes = waitForRelease("MM",60); 00153 pc.printf("Setting minutes to %i\r\n", minutes); 00154 set_HHMMSS(hours, minutes, seconds); 00155 function_mode = SHOW_TIME; 00156 display_state = SHOW_HHMM; 00157 } 00158 } 00159 00160 // If slider is touched, update seconds 00161 void setSeconds(void) 00162 { 00163 int hours, minutes, seconds; 00164 00165 get_HHMMSS(&hours, &minutes, &seconds); 00166 sLCD.printf("SS%2i", seconds); 00167 waitForTouch(SET_SECONDS); 00168 if (function_mode == SET_SECONDS) 00169 { 00170 seconds = waitForRelease("SS",60); 00171 pc.printf("Setting seconds to %i\r\n", seconds); 00172 set_HHMMSS(hours, minutes, seconds); 00173 function_mode = SHOW_TIME; 00174 display_state = SHOW_SS; 00175 } 00176 } 00177 00178 // Cycle between time-display states 00179 // In states SHOW_HHMM to SHOW_SS - 1, display HH:MM & flash green LED. 00180 // In states SHOW_SS to SHOW_LOOP, display :SS & flash red LED. 00181 void showTime(void) 00182 { 00183 DigitalOut *flashLED; 00184 time_t rtcTime = time(NULL); 00185 00186 if(display_state < SHOW_SS) 00187 { 00188 strftime(LCDbuffer, 4, "%H%M", localtime(&rtcTime));// display HH:MM 00189 flashLED = &greenLED; // while flashing green LED 00190 } 00191 else 00192 { 00193 strftime(LCDbuffer, 4, " %S", localtime(&rtcTime));// display :SS 00194 flashLED = &redLED; // while flashing red LED 00195 } 00196 sLCD.printf(LCDbuffer); // Send to LCD 00197 redLED = 1; greenLED = 1; // Both LEDs off 00198 wait(0.5); 00199 *flashLED = 0; // Red or Green on. 00200 wait(0.5); 00201 redLED = 1; greenLED = 1; // Both LEDs off. 00202 if (function_mode == SHOW_TIME) display_state++; // Increment display counter if no switch pressed 00203 if (display_state > SHOW_LOOP) display_state = SHOW_HHMM; 00204 } 00205 00206 main() 00207 { 00208 pc.printf("\r\n\nFRDM-KL46Z Clock\r\n"); 00209 00210 sLCD.All_Segments(1); wait(1); // Flash LCD segments 00211 sLCD.All_Segments(0); wait(1); 00212 00213 greenLED = 1; redLED = 1; // Both LEDs off 00214 00215 scroll_message(); // Display instructions 00216 00217 setModeSwitch.rise(setMode); // Enable setMode interrupt handler 00218 00219 sLCD.Colon(1); sLCD.DP2(0); 00220 function_mode = SHOW_TIME; 00221 while(1) 00222 { 00223 if (function_mode == SET_HOURS) 00224 setHours(); 00225 else if (function_mode == SET_MINUTES) 00226 setMinutes(); 00227 else if (function_mode == SET_SECONDS) 00228 setSeconds(); 00229 else if (function_mode == SHOW_TIME) 00230 showTime(); 00231 } 00232 } 00233 00234
Generated on Wed Jul 20 2022 09:45:33 by 1.7.2