A sunrise alarm clock controlled through serial designed to run on a LPC 1768 and is currently being modified to run on a Nucleo board

Dependencies:   RTC mbed

Revision:
1:dcd847fa6def
Parent:
0:ea21a4715fed
Child:
2:223c142956c6
--- a/main.cpp	Wed Aug 05 13:24:21 2015 +0000
+++ b/main.cpp	Wed Aug 05 19:28:12 2015 +0000
@@ -1,48 +1,173 @@
 #include "mbed.h"
+#include "RTC.h"
 
-PwmOut reds(p21);
+PwmOut reds(p24);
 PwmOut greens(p22);
 PwmOut yellows(p23);
-PwmOut blues(p24);
+PwmOut blues(p21);
 
 Serial pc(USBTX, USBRX);
 
-void Rx_interrupt(void);
+// Circular buffers for serial TX and RX data - used by interrupt routines
+const int buffer_size = 255;
+// might need to increase buffer size for high baud rates
+char tx_buffer[buffer_size+1];
+char rx_buffer[buffer_size+1];
+// Circular buffer pointers
+// volatile makes read-modify-write atomic
+volatile int tx_in=0;
+volatile int tx_out=0;
+volatile int rx_in=0;
+volatile int rx_out=0;
+// Line buffers for sprintf and sscanf
+char tx_line[80];
+char rx_line[80];
 
-int main(){
+// State of the time setting
+volatile int timeSetting = 0;
+// Alarm state
+volatile int alarmActive = 0;
+
+void Rx_interrupt(void);
+void minTick(void);
+void alarmRoutine(void);
+void lightSequence(void);
+int redMs = 0;
+int greenMs = 0;
+int yellowMs = 0;
+int blueMs = 0;
+
+int main()
+{
     pc.baud(9600);
     reds.period_ms(1);
     greens.period_ms(1);
     yellows.period_ms(1);
     blues.period_ms(1);
-    
-    reds.pulsewidth_us(500);
-    greens.pulsewidth_us(500);
-    yellows.pulsewidth_us(500);
-    blues.pulsewidth_us(500);
-    
+
+    reds.pulsewidth_us(redMs);
+    greens.pulsewidth_us(greenMs);
+    yellows.pulsewidth_us(yellowMs);
+    blues.pulsewidth_us(blueMs);
+
     pc.attach(&Rx_interrupt, Serial::RxIrq);
-    
+
     set_time(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37
 
-    while(1) {
-        time_t seconds = time(NULL);
-        seconds.
-
-        printf("Time as seconds since January 1, 1970 = %d\r\n", seconds);
-
-        printf("Time as a basic string = %s\r\n", ctime(&seconds));
+    RTC::attach(&minTick, RTC::Minute);
 
-        char buffer[32];
-        strftime(buffer, 32, "%I:%M %p\r\n", localtime(&seconds));
-        printf("Time as a custom formatted string = %s\r\n", buffer);
-
-        wait(1);
-    }
-    
     return 0;
 }
 
-void Rx_interrupt(){
-        
+void Rx_interrupt()
+{
+    while (pc.readable()) {
+        rx_buffer[rx_in] = pc.getc();
+// Uncomment to Echo to USB serial to watch data flow
+        pc.putc(rx_buffer[rx_in]);
+        if(!rx_in) {
+            if(rx_buffer[rx_in]=='a') {
+                timeSetting = 1;
+                printf("Enter alarm time as 'HH:MM' and press enter\r\n");
+                rx_in = 0;
+                return;
+            } else if(rx_buffer[rx_in]=='t') {
+                printf("Enter time and date as 'HH:MM:SS_dd/mm/yyyy' and press enter\r\n");
+                timeSetting = 2;
+                rx_in = 0;
+                return;
+            } else if(rx_buffer[rx_in]=='o') {
+                printf("Lights off\r\n");
+                redMs = 0;
+                greenMs = 0;
+                yellowMs = 0;
+                blueMs = 0;
+                rx_in = 0;
+                timeSetting = 0;
+                reds.pulsewidth_us(redMs);
+                greens.pulsewidth_us(greenMs);
+                yellows.pulsewidth_us(yellowMs);
+                blues.pulsewidth_us(blueMs);
+                alarmActive = 0;
+                return;
+            } else {
+                if(!timeSetting) {
+                    printf("Press 'a' to set alarm and 't' to set the time\r\n");
+                    timeSetting = 0;
+                    rx_in = 0;
+                    return;
+                }
+            }
+        } else {
+            if(rx_buffer[rx_in]== '\r') {
+                if(timeSetting == 1) {
+                    int hours, minutes;
+                    if(sscanf(rx_buffer, "%d:%d", &hours, &minutes)==2) {
+                        printf("Alarm Stored\r\n");
+                    } else {
+                        printf("Error\r\n");
+                    }
+                    tm newTime;
+                    newTime.tm_min = minutes;
+                    newTime.tm_hour = hours;
+                    RTC::alarm(&alarmRoutine, newTime);
+                } else if(timeSetting == 2) {
+                    int hours, minutes, seconds, day, month, year;
+                    if(sscanf(rx_buffer, "%d:%d:%d_%d/%x/%d", &hours, &minutes,&seconds, &day, &month, &year)==6) {
+                        printf("Time Stored: %d:%d:%d_%d/%x/%d\r\n", hours, minutes,seconds, day, month, year);
+                        tm newTime;
+                        newTime.tm_sec = seconds;
+                        newTime.tm_min = minutes;
+                        newTime.tm_hour = hours;
+                        newTime.tm_mday = day;
+                        newTime.tm_mon = month;
+                        newTime.tm_year = year-1900;
+                        
+                        time_t setTime = mktime(&newTime);
+                        set_time(setTime);
+                    } else {
+                        printf("Error\r\n");
+                    }
+                }
+                rx_in = 0;
+                timeSetting = 0;
+                return;
+            }
+        }
+    }
+    rx_in = (rx_in + 1) % buffer_size;
+}
+
+void minTick()
+{
+    time_t seconds = time(NULL);
+    printf("Time as a basic string = %s\r\n", ctime(&seconds));
+    printf("Press 'a' to set alarm and 't' to set the time\r\n");
+    //reds.pulsewidth_us(redMs);
+    //redMs+=100;
+    //if(!(redMs-1100)) {
+    //    redMs = 0;
+    //}
+}
+void alarmRoutine(){
+    RTC::attach(&lightSequence, RTC::Second);
+    printf("ALARM!!!\r\n");
+}
+void lightSequence(){
+    if(redMs != 1000){
+        redMs+=100;
+        reds.pulsewidth_us(redMs);
+    }else if (yellowMs!=1000){
+        yellowMs+=100;
+        yellows.pulsewidth_us(yellowMs);
+    }else if (greenMs!=1000){
+        greenMs+=100;
+        greens.pulsewidth_us(greenMs);
+    }else if (blueMs!=1000){
+        blueMs+=100;
+        blues.pulsewidth_us(blueMs);
+    }else{
+        alarmActive = 0;
+        RTC::detach(RTC::Second);
+    }
 }
\ No newline at end of file