Smart LED window to mimic the sun

Dependencies:   mbed

Committer:
TCNoodleshop
Date:
Sun Dec 08 21:28:41 2019 +0000
Revision:
0:53cb5d7e5c36
First commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TCNoodleshop 0:53cb5d7e5c36 1 #include "mbed.h"
TCNoodleshop 0:53cb5d7e5c36 2 #include <PwmOut.h>
TCNoodleshop 0:53cb5d7e5c36 3 // **I/O INITIALIZATION**
TCNoodleshop 0:53cb5d7e5c36 4 Serial pc(USBTX, USBRX); // tx, rx for Serial Port (Debugging)
TCNoodleshop 0:53cb5d7e5c36 5 Serial Blue(p28,p27); // Bluetooh Initialization
TCNoodleshop 0:53cb5d7e5c36 6 PwmOut bLED(p21); // Blue LEDS PWM pin assignment
TCNoodleshop 0:53cb5d7e5c36 7 PwmOut rLED(p23); // Red LEDS PWM pin assignment
TCNoodleshop 0:53cb5d7e5c36 8 AnalogIn bSliderIn(p20); // Slider in for blue
TCNoodleshop 0:53cb5d7e5c36 9 AnalogIn rSliderIn(p19); // Slider in for red
TCNoodleshop 0:53cb5d7e5c36 10
TCNoodleshop 0:53cb5d7e5c36 11 // **GLOBAL VARIABLES**
TCNoodleshop 0:53cb5d7e5c36 12 int mode = 0; //Mode 0 = bluetooth; Mode 1 = slider; Mode 2 = RTC
TCNoodleshop 0:53cb5d7e5c36 13 // These percentages are based off 0-100,
TCNoodleshop 0:53cb5d7e5c36 14 // They do not correleate linearly with direct PwmOut.
TCNoodleshop 0:53cb5d7e5c36 15 int bPercent=0;
TCNoodleshop 0:53cb5d7e5c36 16 int rPercent=0;
TCNoodleshop 0:53cb5d7e5c36 17
TCNoodleshop 0:53cb5d7e5c36 18 // **BLUETOOTH**
TCNoodleshop 0:53cb5d7e5c36 19 // Variables
TCNoodleshop 0:53cb5d7e5c36 20 volatile bool button_ready = 0;
TCNoodleshop 0:53cb5d7e5c36 21 volatile int bnum = 0;
TCNoodleshop 0:53cb5d7e5c36 22 volatile int bhit =0;
TCNoodleshop 0:53cb5d7e5c36 23 // State used to remember previous characters read in a button message
TCNoodleshop 0:53cb5d7e5c36 24 enum statetype {start = 0, got_exclm, got_B, got_num, got_hit};
TCNoodleshop 0:53cb5d7e5c36 25 statetype state = start;
TCNoodleshop 0:53cb5d7e5c36 26 // Interrupt routine to parse message with one new character per serial RX interrupt
TCNoodleshop 0:53cb5d7e5c36 27 void parse_message()
TCNoodleshop 0:53cb5d7e5c36 28 {
TCNoodleshop 0:53cb5d7e5c36 29 switch (state) {
TCNoodleshop 0:53cb5d7e5c36 30 case start:
TCNoodleshop 0:53cb5d7e5c36 31 if (Blue.getc()=='!') state = got_exclm;
TCNoodleshop 0:53cb5d7e5c36 32 else state = start;
TCNoodleshop 0:53cb5d7e5c36 33 break;
TCNoodleshop 0:53cb5d7e5c36 34 case got_exclm:
TCNoodleshop 0:53cb5d7e5c36 35 if (Blue.getc() == 'B') state = got_B;
TCNoodleshop 0:53cb5d7e5c36 36 else state = start;
TCNoodleshop 0:53cb5d7e5c36 37 break;
TCNoodleshop 0:53cb5d7e5c36 38 case got_B:
TCNoodleshop 0:53cb5d7e5c36 39 bnum = Blue.getc();
TCNoodleshop 0:53cb5d7e5c36 40 state = got_num;
TCNoodleshop 0:53cb5d7e5c36 41 break;
TCNoodleshop 0:53cb5d7e5c36 42 case got_num:
TCNoodleshop 0:53cb5d7e5c36 43 bhit = Blue.getc();
TCNoodleshop 0:53cb5d7e5c36 44 state = got_hit;
TCNoodleshop 0:53cb5d7e5c36 45 break;
TCNoodleshop 0:53cb5d7e5c36 46 case got_hit:
TCNoodleshop 0:53cb5d7e5c36 47 if (Blue.getc() == char(~('!' + ' B' + bnum + bhit))) button_ready = 1;
TCNoodleshop 0:53cb5d7e5c36 48 state = start;
TCNoodleshop 0:53cb5d7e5c36 49 break;
TCNoodleshop 0:53cb5d7e5c36 50 default:
TCNoodleshop 0:53cb5d7e5c36 51 Blue.getc();
TCNoodleshop 0:53cb5d7e5c36 52 state = start;
TCNoodleshop 0:53cb5d7e5c36 53 }
TCNoodleshop 0:53cb5d7e5c36 54 }
TCNoodleshop 0:53cb5d7e5c36 55
TCNoodleshop 0:53cb5d7e5c36 56 // **FUNCTIONS**
TCNoodleshop 0:53cb5d7e5c36 57
TCNoodleshop 0:53cb5d7e5c36 58 // setLight: Sets a specified color strip to an input (0-100)
TCNoodleshop 0:53cb5d7e5c36 59 // then saves that input to the variables rPercent or bPercent.
TCNoodleshop 0:53cb5d7e5c36 60 //
TCNoodleshop 0:53cb5d7e5c36 61 // Input values are not linearly correlated with the PWM duty cycle,
TCNoodleshop 0:53cb5d7e5c36 62 // instead they are translated with a cubic function, so the lights
TCNoodleshop 0:53cb5d7e5c36 63 // *appear* to be acting linearly
TCNoodleshop 0:53cb5d7e5c36 64 void setLight(int input, PwmOut *LED){
TCNoodleshop 0:53cb5d7e5c36 65 if (input >100){ //Correct input to 100 if input is somehow too high
TCNoodleshop 0:53cb5d7e5c36 66 input = 100;
TCNoodleshop 0:53cb5d7e5c36 67 } else if (input <0){ //Correct input to 0 if input is somehow too low
TCNoodleshop 0:53cb5d7e5c36 68 input = 0;
TCNoodleshop 0:53cb5d7e5c36 69 }
TCNoodleshop 0:53cb5d7e5c36 70 if (LED == &bLED){ //If input is the blue LEDs
TCNoodleshop 0:53cb5d7e5c36 71 if (input >= bPercent){ // If input is HIGHER than current brightness
TCNoodleshop 0:53cb5d7e5c36 72 for (int i = bPercent; i < input; i++){ //Loop to gradually increase brightness until reaches desired value
TCNoodleshop 0:53cb5d7e5c36 73 float temp = i;
TCNoodleshop 0:53cb5d7e5c36 74 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 75 wait(.01);
TCNoodleshop 0:53cb5d7e5c36 76 }
TCNoodleshop 0:53cb5d7e5c36 77 } else { // If input is LOWER than current brightness
TCNoodleshop 0:53cb5d7e5c36 78 for (int i = bPercent; i > input; i--){ //Loop until reaches desired value
TCNoodleshop 0:53cb5d7e5c36 79 float temp = i;
TCNoodleshop 0:53cb5d7e5c36 80 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 81 wait(.01);
TCNoodleshop 0:53cb5d7e5c36 82 }
TCNoodleshop 0:53cb5d7e5c36 83 }
TCNoodleshop 0:53cb5d7e5c36 84 bPercent = (input); //Record input to current bPercent
TCNoodleshop 0:53cb5d7e5c36 85 } else { //If input is the red LEDs
TCNoodleshop 0:53cb5d7e5c36 86 if (input >= rPercent){
TCNoodleshop 0:53cb5d7e5c36 87 for (int i = rPercent; i < input; i++){
TCNoodleshop 0:53cb5d7e5c36 88 float temp = i;
TCNoodleshop 0:53cb5d7e5c36 89 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 90 wait(.01);
TCNoodleshop 0:53cb5d7e5c36 91 }
TCNoodleshop 0:53cb5d7e5c36 92 } else { //if input < bPercent
TCNoodleshop 0:53cb5d7e5c36 93 for (int i = rPercent; i > input; i--){
TCNoodleshop 0:53cb5d7e5c36 94 float temp = i;
TCNoodleshop 0:53cb5d7e5c36 95 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 96 wait(.01);
TCNoodleshop 0:53cb5d7e5c36 97 }
TCNoodleshop 0:53cb5d7e5c36 98 }
TCNoodleshop 0:53cb5d7e5c36 99 rPercent = (input);
TCNoodleshop 0:53cb5d7e5c36 100 }
TCNoodleshop 0:53cb5d7e5c36 101 }
TCNoodleshop 0:53cb5d7e5c36 102
TCNoodleshop 0:53cb5d7e5c36 103
TCNoodleshop 0:53cb5d7e5c36 104 // sliderSet: Nearly the same as setLight() but with built-in noise reduction
TCNoodleshop 0:53cb5d7e5c36 105 // (Doesn't allow any changes greater than 2 at a time)
TCNoodleshop 0:53cb5d7e5c36 106 void sliderSet(int input, PwmOut *LED){
TCNoodleshop 0:53cb5d7e5c36 107 float temp = input;
TCNoodleshop 0:53cb5d7e5c36 108 if (input >100){ //Set LED to 1 if input is somehow >= 100
TCNoodleshop 0:53cb5d7e5c36 109 *LED = 1;
TCNoodleshop 0:53cb5d7e5c36 110 return;
TCNoodleshop 0:53cb5d7e5c36 111 } else if (input <0){ //Set LED to 0 if input is somehow <= 100
TCNoodleshop 0:53cb5d7e5c36 112 *LED = 0;
TCNoodleshop 0:53cb5d7e5c36 113 return;
TCNoodleshop 0:53cb5d7e5c36 114 } else { //Cubic Function with noise reduction
TCNoodleshop 0:53cb5d7e5c36 115 int bDif = abs( bPercent - input);
TCNoodleshop 0:53cb5d7e5c36 116 int rDif = abs( rPercent - input);
TCNoodleshop 0:53cb5d7e5c36 117 if (LED == &bLED){ //IF BLUE LED
TCNoodleshop 0:53cb5d7e5c36 118 if (bDif <2 && bDif > -2){
TCNoodleshop 0:53cb5d7e5c36 119 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 120 bPercent = (input);
TCNoodleshop 0:53cb5d7e5c36 121 }
TCNoodleshop 0:53cb5d7e5c36 122 } else { // IF RED LED
TCNoodleshop 0:53cb5d7e5c36 123 if (rDif <2 && rDif > -2){
TCNoodleshop 0:53cb5d7e5c36 124 *LED = (((temp*temp*temp)/1000000));
TCNoodleshop 0:53cb5d7e5c36 125 rPercent = (input);
TCNoodleshop 0:53cb5d7e5c36 126 }
TCNoodleshop 0:53cb5d7e5c36 127 }
TCNoodleshop 0:53cb5d7e5c36 128 }
TCNoodleshop 0:53cb5d7e5c36 129 }
TCNoodleshop 0:53cb5d7e5c36 130
TCNoodleshop 0:53cb5d7e5c36 131 // Returns the user percentage assigned to that LED.
TCNoodleshop 0:53cb5d7e5c36 132 int getPercent(PwmOut *LED){
TCNoodleshop 0:53cb5d7e5c36 133 if (LED == &bLED){
TCNoodleshop 0:53cb5d7e5c36 134 return bPercent;
TCNoodleshop 0:53cb5d7e5c36 135 } else return rPercent;
TCNoodleshop 0:53cb5d7e5c36 136 }
TCNoodleshop 0:53cb5d7e5c36 137
TCNoodleshop 0:53cb5d7e5c36 138 // **MAIN**
TCNoodleshop 0:53cb5d7e5c36 139 int main() {
TCNoodleshop 0:53cb5d7e5c36 140 //attach interrupt function for each new Bluetooth serial character
TCNoodleshop 0:53cb5d7e5c36 141 Blue.attach(&parse_message,Serial::RxIrq);
TCNoodleshop 0:53cb5d7e5c36 142 bLED.period_ms (1); //Set LED freq to 1Khz
TCNoodleshop 0:53cb5d7e5c36 143 rLED.period_ms (1);
TCNoodleshop 0:53cb5d7e5c36 144 PwmOut *LEDToControl = &bLED; //bLED is default LEDToControl
TCNoodleshop 0:53cb5d7e5c36 145 set_time(1574588800); //7:00am
TCNoodleshop 0:53cb5d7e5c36 146
TCNoodleshop 0:53cb5d7e5c36 147 while(1) {
TCNoodleshop 0:53cb5d7e5c36 148 if (mode == 1){
TCNoodleshop 0:53cb5d7e5c36 149 sliderSet(bSliderIn*100,&bLED);
TCNoodleshop 0:53cb5d7e5c36 150 sliderSet(rSliderIn*100,&rLED);
TCNoodleshop 0:53cb5d7e5c36 151 } else if (mode == 2){
TCNoodleshop 0:53cb5d7e5c36 152 time_t now = time(0);
TCNoodleshop 0:53cb5d7e5c36 153 tm *ltm = localtime(&now);
TCNoodleshop 0:53cb5d7e5c36 154 int cHour = ltm->tm_hour;
TCNoodleshop 0:53cb5d7e5c36 155 int cMin = ltm->tm_min;
TCNoodleshop 0:53cb5d7e5c36 156 if (cHour > 18 || cHour <7){ //If between 6pm and 7am, turn all lights off
TCNoodleshop 0:53cb5d7e5c36 157 setLight(0, &bLED);
TCNoodleshop 0:53cb5d7e5c36 158 setLight(0, &rLED);
TCNoodleshop 0:53cb5d7e5c36 159 } else if (cHour >= 7 && cHour < 8) { //From 7-8, fade as sunrise
TCNoodleshop 0:53cb5d7e5c36 160 int lightset = cHour*100+(cMin)/.6;
TCNoodleshop 0:53cb5d7e5c36 161 setLight((lightset-710)*8,&bLED); //Blue LED fade in at 7:06
TCNoodleshop 0:53cb5d7e5c36 162 setLight((lightset-700)*8,&rLED); //Red LED fade in at 7-7:08
TCNoodleshop 0:53cb5d7e5c36 163 pc.printf("Lightset: %i \n", lightset);
TCNoodleshop 0:53cb5d7e5c36 164 } else if (cHour >= 17 && cHour < 18) { //From 5-6, fade as sunset
TCNoodleshop 0:53cb5d7e5c36 165 int lightset = cHour*100+(cMin)/.6;
TCNoodleshop 0:53cb5d7e5c36 166 setLight(100-((lightset-1725)*8),&rLED); //Red LED fade out at 5:15-5:30
TCNoodleshop 0:53cb5d7e5c36 167 setLight(100-((lightset-1700)*8),&bLED); //Blue LED fade out at 5-5:15
TCNoodleshop 0:53cb5d7e5c36 168 } else {
TCNoodleshop 0:53cb5d7e5c36 169 setLight(100, &bLED);
TCNoodleshop 0:53cb5d7e5c36 170 setLight(100, &rLED);
TCNoodleshop 0:53cb5d7e5c36 171 }
TCNoodleshop 0:53cb5d7e5c36 172 }
TCNoodleshop 0:53cb5d7e5c36 173 //check for a new button message ready
TCNoodleshop 0:53cb5d7e5c36 174 if(button_ready) { // button changed
TCNoodleshop 0:53cb5d7e5c36 175 if(bnum=='1' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 176 mode = 0;
TCNoodleshop 0:53cb5d7e5c36 177 pc.printf("mode 0!\n");
TCNoodleshop 0:53cb5d7e5c36 178 } else if (bnum=='2' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 179 mode = 1;
TCNoodleshop 0:53cb5d7e5c36 180 setLight(bSliderIn*100,&bLED);
TCNoodleshop 0:53cb5d7e5c36 181 setLight(rSliderIn*100,&rLED);
TCNoodleshop 0:53cb5d7e5c36 182 pc.printf("mode 1!\n");
TCNoodleshop 0:53cb5d7e5c36 183 } else if (bnum=='3' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 184 mode = 2;
TCNoodleshop 0:53cb5d7e5c36 185 pc.printf("mode 2!\n");
TCNoodleshop 0:53cb5d7e5c36 186 }else if (bnum=='4' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 187 if (mode == 0){
TCNoodleshop 0:53cb5d7e5c36 188 if (LEDToControl == &bLED){
TCNoodleshop 0:53cb5d7e5c36 189 LEDToControl = &rLED;
TCNoodleshop 0:53cb5d7e5c36 190 } else {
TCNoodleshop 0:53cb5d7e5c36 191 LEDToControl = &bLED;
TCNoodleshop 0:53cb5d7e5c36 192 }
TCNoodleshop 0:53cb5d7e5c36 193 }
TCNoodleshop 0:53cb5d7e5c36 194 pc.printf("color!\n");
TCNoodleshop 0:53cb5d7e5c36 195 }else if (bnum=='5' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 196 if (mode == 0){
TCNoodleshop 0:53cb5d7e5c36 197 if (getPercent(LEDToControl) <= 95){
TCNoodleshop 0:53cb5d7e5c36 198 setLight((getPercent(LEDToControl)+10),LEDToControl);
TCNoodleshop 0:53cb5d7e5c36 199 }
TCNoodleshop 0:53cb5d7e5c36 200 }
TCNoodleshop 0:53cb5d7e5c36 201 pc.printf("inc!\n");
TCNoodleshop 0:53cb5d7e5c36 202 }else if (bnum=='6' && bhit == '1'){
TCNoodleshop 0:53cb5d7e5c36 203 if (mode == 0){
TCNoodleshop 0:53cb5d7e5c36 204 if (getPercent(LEDToControl)>=5){
TCNoodleshop 0:53cb5d7e5c36 205 setLight((getPercent(LEDToControl)-10),LEDToControl);
TCNoodleshop 0:53cb5d7e5c36 206 }
TCNoodleshop 0:53cb5d7e5c36 207 //time_t seconds = time(0);
TCNoodleshop 0:53cb5d7e5c36 208 //pc.printf("Time as a basic string = %s", ctime(&seconds));
TCNoodleshop 0:53cb5d7e5c36 209 }
TCNoodleshop 0:53cb5d7e5c36 210 }
TCNoodleshop 0:53cb5d7e5c36 211 button_ready = 0; //reset flag after reading button message
TCNoodleshop 0:53cb5d7e5c36 212 }
TCNoodleshop 0:53cb5d7e5c36 213
TCNoodleshop 0:53cb5d7e5c36 214 }
TCNoodleshop 0:53cb5d7e5c36 215
TCNoodleshop 0:53cb5d7e5c36 216 }
TCNoodleshop 0:53cb5d7e5c36 217