Smart LED window to mimic the sun

Dependencies:   mbed

Revision:
0:53cb5d7e5c36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Dec 08 21:28:41 2019 +0000
@@ -0,0 +1,217 @@
+#include "mbed.h"
+#include <PwmOut.h>
+// **I/O INITIALIZATION**
+Serial pc(USBTX, USBRX); // tx, rx for Serial Port (Debugging)
+Serial Blue(p28,p27); // Bluetooh Initialization
+PwmOut bLED(p21); // Blue LEDS PWM pin assignment
+PwmOut rLED(p23); // Red LEDS PWM pin assignment
+AnalogIn bSliderIn(p20); // Slider in for blue
+AnalogIn rSliderIn(p19); // Slider in for red
+
+// **GLOBAL VARIABLES**
+int mode = 0; //Mode 0 = bluetooth; Mode 1 = slider; Mode 2 = RTC
+//  These percentages are based off 0-100,
+//  They do not correleate linearly with direct PwmOut.
+int bPercent=0; 
+int rPercent=0;
+
+// **BLUETOOTH**
+//  Variables
+volatile bool button_ready = 0;
+volatile int  bnum = 0;
+volatile int  bhit =0;
+//  State used to remember previous characters read in a button message
+enum statetype {start = 0, got_exclm, got_B, got_num, got_hit};
+statetype state = start;
+//  Interrupt routine to parse message with one new character per serial RX interrupt
+void parse_message()
+{
+    switch (state) {
+        case start:
+            if (Blue.getc()=='!') state = got_exclm;
+            else state = start;
+            break;
+        case got_exclm:
+            if (Blue.getc() == 'B') state = got_B;
+            else state = start;
+            break;
+        case got_B:
+            bnum = Blue.getc();
+            state = got_num;
+            break;
+        case got_num:
+            bhit = Blue.getc();
+            state = got_hit;
+            break;
+        case got_hit:
+            if (Blue.getc() == char(~('!' + ' B' + bnum + bhit))) button_ready = 1;
+            state = start;
+            break;
+        default:
+            Blue.getc();
+            state = start;
+    }
+}
+
+// **FUNCTIONS**
+
+// setLight: Sets a specified color strip to an input (0-100)
+// then saves that input to the variables rPercent or bPercent.
+//
+//      Input values are not linearly correlated with the PWM duty cycle,
+//      instead they are translated with a cubic function, so the lights
+//       *appear* to be acting linearly
+void setLight(int input, PwmOut *LED){
+    if (input >100){ //Correct input to 100 if input is somehow too high
+        input = 100;
+    } else if (input <0){ //Correct input to 0 if input is somehow too low
+        input = 0;
+    } 
+    if (LED == &bLED){ //If input is the blue LEDs
+        if (input >= bPercent){ // If input is HIGHER than current brightness
+            for (int i = bPercent; i < input; i++){ //Loop to gradually increase brightness until reaches desired value
+                float temp = i;
+                *LED = (((temp*temp*temp)/1000000));
+                wait(.01);
+            }
+        } else { // If input is LOWER than current brightness
+            for (int i = bPercent; i > input; i--){ //Loop until reaches desired value
+                float temp = i;
+                *LED = (((temp*temp*temp)/1000000));
+                wait(.01);
+            }
+        }   
+    bPercent = (input); //Record input to current bPercent   
+    } else { //If input is the red LEDs
+        if (input >= rPercent){
+            for (int i = rPercent; i < input; i++){
+                float temp = i;
+                *LED = (((temp*temp*temp)/1000000));
+                wait(.01);
+            }
+        } else { //if input < bPercent
+            for (int i = rPercent; i > input; i--){
+                float temp = i;
+                *LED = (((temp*temp*temp)/1000000));
+                wait(.01);
+            }
+        }   
+    rPercent = (input); 
+    }
+}
+
+
+// sliderSet: Nearly the same as setLight() but with built-in noise reduction
+// (Doesn't allow any changes greater than 2 at a time)
+void sliderSet(int input, PwmOut *LED){
+    float temp = input;
+    if (input >100){ //Set LED to 1 if input is somehow >= 100
+        *LED = 1;
+        return;
+    } else if (input <0){ //Set LED to 0 if input is somehow <= 100
+        *LED = 0;
+        return;
+    } else { //Cubic Function with noise reduction
+        int bDif = abs( bPercent - input);
+        int rDif = abs( rPercent - input);
+        if (LED == &bLED){ //IF BLUE LED
+            if (bDif <2 && bDif > -2){
+                *LED = (((temp*temp*temp)/1000000));
+                bPercent = (input);
+            }
+        } else { // IF RED LED
+            if (rDif <2  && rDif > -2){
+                *LED = (((temp*temp*temp)/1000000));
+                rPercent = (input);
+            }
+        }
+    }
+}
+
+// Returns the user percentage assigned to that LED.
+int getPercent(PwmOut *LED){
+    if (LED == &bLED){
+        return bPercent;
+    } else return rPercent;
+}
+
+// **MAIN**
+int main() {
+    //attach interrupt function for each new Bluetooth serial character
+    Blue.attach(&parse_message,Serial::RxIrq);
+    bLED.period_ms (1); //Set LED freq to 1Khz
+    rLED.period_ms (1);
+    PwmOut *LEDToControl = &bLED; //bLED is default LEDToControl
+    set_time(1574588800); //7:00am
+    
+    while(1) {
+        if (mode == 1){
+            sliderSet(bSliderIn*100,&bLED);
+            sliderSet(rSliderIn*100,&rLED);
+        } else if (mode == 2){
+            time_t now = time(0);
+            tm *ltm = localtime(&now);
+            int cHour = ltm->tm_hour;
+            int cMin = ltm->tm_min;
+                if (cHour > 18 || cHour <7){ //If between 6pm and 7am, turn all lights off
+                    setLight(0, &bLED);
+                    setLight(0, &rLED);
+                } else if (cHour >= 7 && cHour < 8) { //From 7-8, fade as sunrise
+                    int lightset = cHour*100+(cMin)/.6;
+                    setLight((lightset-710)*8,&bLED); //Blue LED fade in at 7:06
+                    setLight((lightset-700)*8,&rLED); //Red LED fade in at 7-7:08
+                    pc.printf("Lightset: %i \n", lightset);
+                } else if (cHour >= 17 && cHour < 18) { //From 5-6, fade as sunset
+                    int lightset = cHour*100+(cMin)/.6;
+                    setLight(100-((lightset-1725)*8),&rLED); //Red LED fade out at 5:15-5:30
+                    setLight(100-((lightset-1700)*8),&bLED); //Blue LED fade out at 5-5:15
+                } else {
+                    setLight(100, &bLED);
+                    setLight(100, &rLED);
+                }
+            }
+        //check for a new button message ready
+        if(button_ready) { // button changed
+            if(bnum=='1' && bhit == '1'){
+                mode = 0;
+                pc.printf("mode 0!\n");
+            } else if (bnum=='2' && bhit == '1'){
+                mode = 1;
+                setLight(bSliderIn*100,&bLED);
+                setLight(rSliderIn*100,&rLED);
+                pc.printf("mode 1!\n");
+            } else if (bnum=='3' && bhit == '1'){
+                mode = 2;
+                pc.printf("mode 2!\n");
+            }else if (bnum=='4' && bhit == '1'){
+                if (mode == 0){
+                    if (LEDToControl == &bLED){
+                        LEDToControl = &rLED;
+                    } else {
+                        LEDToControl = &bLED;
+                    }
+                }
+                pc.printf("color!\n");
+            }else if (bnum=='5' && bhit == '1'){
+                if (mode == 0){
+                    if (getPercent(LEDToControl) <= 95){
+                        setLight((getPercent(LEDToControl)+10),LEDToControl); 
+                    }
+                }
+                pc.printf("inc!\n");
+            }else if (bnum=='6' && bhit == '1'){
+                if (mode == 0){
+                    if (getPercent(LEDToControl)>=5){
+                        setLight((getPercent(LEDToControl)-10),LEDToControl);
+                    }
+                    //time_t seconds = time(0);
+                    //pc.printf("Time as a basic string = %s", ctime(&seconds));
+                }
+            }
+            button_ready = 0; //reset flag after reading button message
+        }
+        
+    }
+       
+}
+     
\ No newline at end of file