//********************************************************* //Code for Lucetios - Home lighting control system // //Project by: // Eric Okawa // Marcelo Garza // Abhijeet Agarwal // //This code runs the home lighting control system, where //there are two light sensors to read the light intensity //inside and outside the house, and two motors to control // // 4 Buttons for pre-set settings: S1, S2, S3, S4 // 1 Button for turning on Float mode: F // 2 Buttons for changing floating points: F_plus, F_minus //********************************************************* //I like these definitions #define begin { #define end } #include #include //#include // LCD driver routines //timeout values for each task #define T1 10 #define T2 10 #define T3 100 //IR Sensors debounce #define NONE 0 #define IN 1 #define IN_M 2 #define OUT 3 #define OUT_M 4 //Settings #define S1 1 #define S2 2 #define S3 4 #define S4 8 #define FLOAT 16 #define PLUS 32 #define MINUS 64 #define TEST 128 #define MAX_ROT 300 #define MIN_ROT 0 #define MAX_LIGHT 320 #define MIN_LIGHT 0 #define NOOP 3 #define UP 1 #define DOWN 2 void task1(void); //test for button press void task2(void); //test for button press void task3(void); //test for button press void initialize(void); //all the usual mcu stuff void adconv1(void); //AtoD Converter from Sensor 1 void adconv2(void); //AtoD Converter from Sensor 2 //void blinds_close(void); //Spins the motor clockwise //void blinds_open(void); //Spins the motor anti-clockwise //void light_up(void); //Spins the motor clockwise //void light_down(void); //Spins the motor anti-clockwise char adc_flag; //Preset position for Motor unsigned int M1 = 300; //Preset value 1 unsigned int M2 = 150; //Preset value 2 unsigned int M3 = 100; //Preset value 3 unsigned int M4 = 0; //Preset value 4 //Preset dimming for lamp unsigned int L1 = 320; //Preset value 1 unsigned int L2 = 200; //Preset value 2 unsigned int L3 = 100; //Preset value 3 unsigned int L4 = 0; //Preset value 4 char sensorA, sensorB; //IR sensors char traffic = NONE; //for debounce of the IR sensors char adjusting_settings; int num_people = 0; // Occupancy test char blinds_command = 0; //Sets the direction of rotation char lights_command = 0; //Sets the direction of rotation char motor_value; unsigned int time, time1, time2, time3; //task scheduling timeout counters int light_out, light_in; //raw A to D number for both light sensors unsigned int blinds_position = 0; //Current position of the blinds unsigned int light_position = 0; //Current position of the dimmer unsigned int saved_blinds_position = 250; //Saves the positio for when people leave room unsigned int saved_light_position = 250; //Saves the positio for when people leave room unsigned char crank; unsigned char light_crank; unsigned int float_value = 15; unsigned char setting = 0; unsigned char pseudo_setting = 0; unsigned char previous_setting; unsigned int depress = 0; //********************************************************** //timer 0 overflow ISR interrupt [TIM0_COMP] void timer0_overflow(void) begin time++; if (time1>0) --time1; if (time2>0) --time2; if (time3>0) --time3; end //****************************************** //Light sensor one: Say it is places inside //the house //****************************************** void adconv1(void) begin ADMUX = 0b11100000; //ADCSR: //Bit7: ADC enable //Bit6: ADC start conversion //Bit4: ADC interrupt flag //Bit3: ADC interrupt enable //Bits2-0: frequency division factor (128) ADCSR = 0b11000111; light_out = ADCH; light_out = light_out>>1; if (light_out>100) light_out = 100; // printf("\rBlinds[%3d], Light[%3d], Outside[%3d],",blinds_position, light_position, light_out); // lcd_gotoxy(11,0); //position to upper left on display // sprintf(intensity1,"%3d", light_out); // lcd_puts(intensity1); end //****************************************** //Light sensor two: Say it is places inside //the house //****************************************** void adconv2(void) begin // light_delay = 0; ADMUX = 0b11100001; //ADCSR: //Bit7: ADC enable //Bit6: ADC start conversion //Bit4: ADC interrupt flag //Bit3: ADC interrupt enable //Bits2-0: frequency division factor (128) ADCSR = 0b11000111; light_in = ADCH; light_in = light_in>>1; if (light_in>100) light_in = 100; // printf("Inside[%3d]",light_in); adc_flag = 1; // light_delay = 1; // lcd_gotoxy(11,1); //position to upper left on display // sprintf(intensity2,"%3d", light_out); // lcd_puts(intensity2); end //****************************************** //Change the position of the motor // //****************************************** void call_motor(void) begin //Changes position of the blinds if((blinds_position <= MAX_ROT)&&(blinds_position >= MIN_ROT)&&(blinds_command != NOOP)&&(blinds_command != 0)) { switch (crank) { //Different step positions - cranks up or down case 0: motor_value = ~(0b00001010); if(blinds_command == UP) crank = 3; else if (blinds_command == DOWN) crank = 1; break; case 1: motor_value = ~(0b00000110); if(blinds_command == UP) crank = 0; else if (blinds_command == DOWN) crank = 2; break; case 2: motor_value = ~(0b00000101); if(blinds_command == UP) crank = 1; else if (blinds_command == DOWN) crank = 3; break; case 3: motor_value = ~(0b00001001); if(blinds_command == UP) crank = 2; else if (blinds_command == DOWN) crank = 0; break; } if((blinds_command == UP)&&(blinds_position < MAX_ROT)) blinds_position++; if((blinds_command == UP)&&(blinds_position == MAX_ROT)) blinds_command = NOOP; if((blinds_command == DOWN)&&(blinds_position > 0)) blinds_position--; if ((blinds_command == DOWN)&&(blinds_position == 0)) blinds_command = NOOP; } //Changes position of the if((light_position <= MAX_LIGHT)&&(light_position >= MIN_LIGHT)&&(lights_command != NOOP)&&(lights_command != 0)) { switch (light_crank)//different positions for the light - crank up or down { case 0: motor_value = ~((0b00010000)|(~motor_value & 0b00001111)); if(lights_command == UP) light_crank = 1; else if (lights_command == DOWN) light_crank = 3; break; case 1: motor_value = ~((0b01000000)|(~motor_value & 0b00001111)); light_crank = 2; if(lights_command == UP) light_crank = 2; else if (lights_command == DOWN) light_crank = 0; break; case 2: motor_value = ~((0b00100000)|(~motor_value & 0b00001111)); light_crank = 3; if(lights_command == UP) light_crank = 3; else if (lights_command == DOWN) light_crank = 1; break; case 3: motor_value = ~((0b10000000)|(~motor_value & 0b00001111)); light_crank = 0; if(lights_command == UP) light_crank = 0; else if (lights_command == DOWN) light_crank = 2; break; } if((lights_command == UP)&&(light_position < MAX_LIGHT)) light_position++; if((lights_command == UP)&&(light_position == MAX_LIGHT)) lights_command = NOOP; if((lights_command == DOWN)&&(light_position > 0)) light_position--; if((lights_command == DOWN)&&(light_position == 0))lights_command = NOOP; } PORTB = motor_value; //Output command to the motor // lights_command = NOOP; // blinds_command = NOOP; motor_value = ~0b00000000; //Disconnect the motor end void task1(void) begin time1 = T1; //reset the task timer if(PINC != ~0) { setting = ~PINC; //Checking the pseudo_setting = setting; } if(num_people == 0) //When everybody leaves the room, close blinds, turn off light { if (blinds_position > MIN_ROT) blinds_command = DOWN;//close blinds if (light_position > 0) lights_command = DOWN;//turn light off // printf("\n\r[%d][%d]\n\r",saved_light_position, saved_blinds_position); } else { if((saved_light_position != 0) && (saved_blinds_position != 0)) { if (blinds_position < saved_blinds_position) blinds_command = UP; else if (blinds_position == saved_blinds_position) blinds_command = NOOP; if (light_position < saved_light_position) lights_command = UP; else if (light_position == saved_light_position) lights_command = NOOP; } else { if ((pseudo_setting == previous_setting)&&(previous_setting !=0)&& ((pseudo_setting & 0x10) != 0x10)&&((pseudo_setting & 0x20) != 0x20)&& ((pseudo_setting & 0x40) != 0x40)&&((pseudo_setting & 0x80) != 0x80)) { blinds_command = NOOP; lights_command = NOOP; if(depress > 40) { printf("Saving mode"); switch(setting) { case S1://Save value onto button 1 M1 = blinds_position;//Save blinds position L1 = light_position;//Save lights position break; case S2://Save value onto button 2 M2 = blinds_position;//Save blinds position L2 = light_position;//Save lights position break; case S3://Save value onto button 3 M3 = blinds_position;//Save blinds position L3 = light_position;//Save lights position break; case S4://Save value onto button 4 M4 = blinds_position;//Save blinds position L4 = light_position;//Save lights position break; } } depress++; pseudo_setting = 0; } else { //Switch between the pushbuttons switch (setting) { case S1: //Button1 - Setting 1 - Move blind and light to set pos if (blinds_position < M1) blinds_command = UP; else if (blinds_position > M1) blinds_command = DOWN; if(blinds_position == M1) blinds_command = NOOP; if (light_position < L1) lights_command = UP; else if (light_position > L1) lights_command = DOWN; if(light_position == L1) lights_command = NOOP; break; case S2: //Buttin2 - Setting 2 - Move blind and light to set pos if (blinds_position < M2) blinds_command = UP; else if (blinds_position > M2) blinds_command = DOWN; if(blinds_position == M2) blinds_command = NOOP; if (light_position < L2) lights_command = UP; else if (light_position > L2) lights_command = DOWN; if(light_position == L2) lights_command = NOOP; break; case S3: //Button3 - Setting 3 - Move blind and light to set pos if (blinds_position < M3) blinds_command = UP; else if (blinds_position > M3) blinds_command = DOWN; if(blinds_position == M3) blinds_command = NOOP; if (light_position < L3) lights_command = UP; else if (light_position > L3) lights_command = DOWN; if(light_position == L3) lights_command = NOOP; break; case S4: //Button4 - Setting 4 - Move blind and light to set pos if (blinds_position < M4) blinds_command = UP; else if (blinds_position > M4) blinds_command = DOWN; if(blinds_position == M4) blinds_command = NOOP; if (light_position < L4) lights_command = UP; else if (light_position > L4) lights_command = DOWN; if(light_position == L4) lights_command = NOOP; break; case FLOAT: if (adc_flag == 1) { if(light_in > (float_value + 2)) { if(blinds_position < MAX_ROT) blinds_command = UP; else lights_command = UP; adc_flag = 0; } else if(light_in < (float_value - 2)) { if(light_position > MIN_LIGHT) lights_command = DOWN; else blinds_command = DOWN; adc_flag = 0; } else if ((light_in <= float_value + 2)&&(light_in >= float_value - 2)) { if((light_in < light_out)&&(light_out > 50)&&(blinds_position > MIN_ROT)) blinds_command = DOWN; if((light_out < (light_in + 5))&&(blinds_position < MAX_ROT)) { lights_command = DOWN; blinds_command = UP; } adc_flag = 0; } } else { blinds_command = NOOP; lights_command = NOOP; } break; case PLUS: if(float_value < 100) { float_value++; printf(" FV[%d], ", float_value); } setting = FLOAT; break; case MINUS: if(float_value > 0) { float_value--; printf(" FV[%d], ", float_value); } setting = FLOAT; break; default: if((pseudo_setting & 0x80) == 0x80) //Case when the last button is pressed { adjusting_settings = 1; if(setting == 0x81) blinds_command = UP; else if(setting == 0x82) blinds_command = DOWN; else if(setting == 0x84) lights_command = UP; else if(setting == 0x88) lights_command = DOWN; else { blinds_command = NOOP; lights_command = NOOP; } } else if (adjusting_settings == 1) { blinds_command = NOOP; lights_command = NOOP; adjusting_settings = 0; } pseudo_setting = 0; break; } //end switch previous_setting = setting; depress = 0; } //end else from if (setting == previous_setting) depress++; } //end else from if((saved_light_position != 0) && (saved_blinds_position != 0)) }//end else from(num_people == 0) if ((blinds_command == NOOP)&&(lights_command == NOOP)) { saved_blinds_position = saved_light_position = 0; PORTB = ~0b00000000;//Detach the motor } else call_motor(); // printf(" PORTB[%x]", PORTB); // printf("\rMV[%x] BP[%d] BC[%d] LP[%d] LC[%d]", PORTB, blinds_position, blinds_command, light_position, lights_command); end //********************************************************** // Checks for IR sensors // //********************************************************** void task2(void) begin time2 = T2; //reset the task timer if((~PIND & 0x4) == 0x4) sensorB = 1; else sensorB = 0; if((~PIND & 0x8) == 0x8) sensorA = 1; else sensorA = 0; if (sensorA && !sensorB) { if((traffic == NONE)||(traffic == IN_M)) traffic = IN; } else if (!sensorA && sensorB) { if((traffic == NONE)||(traffic == OUT_M)) traffic = OUT; } else if (sensorA && sensorB) { if(traffic == IN) { traffic = IN_M; } else if (traffic == OUT) { traffic = OUT_M; } } else if (!sensorA && !sensorB) { if(traffic == OUT_M) { if (num_people == 1) { //When everybody leaves, save position saved_blinds_position = blinds_position; saved_light_position = light_position; printf("\n\rPosition saved!\n\rSaved Position: [%d,%d]", blinds_position, light_position); } //As people leave, decrease the number of people in the room if(num_people != 0) num_people--; printf("Ppl[%d]\n\r", num_people); } else if(traffic == IN_M) { num_people++; printf("Ppl[%d]\n\r", num_people); } traffic = NONE; } end //********************************************************** void task3(void) begin time3 = T3; //reset the task timer //Decrement the three times if they are not already zero //The values we get are: //light_out = intensity outside (Range: 0-900) //light_in = intensity inside (Range: 0-900) adconv1(); //sensor places inside the house adconv2(); //sensor places outside the house ADCSR.6 = 1; end //********************************************************** void main(void) begin initialize(); while(1) { //main task scheduler loop -- never exits! if (time1==0) task1(); if (time2==0) task2(); if (time3==0) task3(); } end //********************************************************** //Set it all up void initialize(void) begin //init the UART UCSRB = 0x18; UBRRL = 103; DDRB=0xff; // PORT B is an ouput DDRC=0x00; // PORT C is an input DDRD=0x00; // PORT D is an input //set up timer 0 OCR0=249; //1 mSec TIMSK=2; //turn on timer 0 cmp-match ISR TCCR0=0b00001011; //prescalar to 64 and Clr-on-match //init the task timers time1=T1; time2=T2; time3=T3; #asm sei #endasm end