Nick Zhao
/
SmartLEDWindow
Smart LED window to mimic the sun
Diff: main.cpp
- 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