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 T Morgan

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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