Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SLCD TSI mbed-src
Fork of FRDM-KL46Z LCD rtc Demo 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 |
--- /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
--- 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));
-
-}
-
-
-
-
