Yu-Cheng MBED

Dependencies:   SLCD TSI mbed-src

Fork of FRDM-KL46Z-Clock by T Morgan

Revision:
2:46d52fa160b2
Parent:
1:34f0bfc62803
Child:
3:586be3d0341d
--- 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));
-
-}
-
-
-
-