// Final Project -- Disco Light // Alex Cerruti and Chris Wherry #include <90s8515.h> #include //timeout values for each task #define t1 25 #define t2 50 unsigned char reload; //timer 0 reload to set 2 mSec unsigned char time1, delay; //timeout counters, delay produces a crude debounce unsigned char beat_flag; //light states int count, color, next_color, positions; //define variables for functions //the three task subroutines void task1(void); // turns fan on and off void cw(void); // function to move color wheel one color clockwise void ccw(void); // function to move color wheel one color counter-clockwise void beat(void); // control movement of color wheel with inputted music void initialize(void); //all the usual mcu stuff //********************************************************** //timer 0 overflow ISR interrupt [TIM0_OVF] void timer0_overflow(void) { //reload to force 1 mSec overflow TCNT0=reload; //Decrement the three times if they are not already zero if (time1>0) --time1; } //********************************************************** //Entry point and task scheduler loop void main(void) { initialize(); //main task scheduler loop while(1) { if (time1==0) task1(); if (PIND.6==0 & beat_flag==0) // we detect a beat { // set flag so we only change one color per beat beat_flag=1; // we have reached a beat call beat() function beat(); // call beat and change color delay=t2; } if (PIND.6==1 & --delay==0) { delay = t2; beat_flag=0; // no more bass beat ready for a new beat } } } //********************************************************** //Temperature turn on fan function void task1(void) { time1 = t1; if(PIND.7 == 1) //turn off the fan in this case { PORTC = 0xf0; // keep halogen on, but turn off fan } else //otherwise turn it on PORTC = 0xff; } //********************************************************** // Function that moves it counter-clockwise void ccw(void) { //make motor step forward twenty steps for(count=0; count<5*positions; count++) { PORTB = 0x01; delay_ms(5); PORTB = 0x02; delay_ms(5); PORTB = 0x04; delay_ms(5); PORTB = 0x08; delay_ms(5); } } //********************************************************** // Function that moves it clockwise void cw(void) { //make motor step backward twenty steps for(count=0; count<5*positions; count++) { PORTB = 0x08; delay_ms(5); PORTB = 0x04; delay_ms(5); PORTB = 0x02; delay_ms(5); PORTB = 0x01; delay_ms(5); } } /////////////////////////////// // Color Table: // 0 - black // 1 - white // 2 - light green // 3 - blue // 4 - yellow // 5 - orange // 6 - green // 7 - amber // 8 - pink // 9 - magenta // 10 - strobe //////////////////////////////// void beat(void) { next_color = TCNT0 % 11; // get a random number between 0 and 10 if (next_color == 10) // if strobe { next_color=1; // first set to white // move to white from current color if (next_color-color>0) { positions = next_color-color; // calculate number of positions needed to turn ccw(); color = next_color; // keep track of new color } if (next_color-color<0) { positions = color-next_color; // make sure positions is positive cw(); color = next_color; // keep track of new color } // now oscillate between black and white for 5 times positions=1; for(count=0; count<5; count++) { cw(); // now on black ccw(); // now on white } } else if (next_color-color>0) { positions = next_color-color; // calculate number of positions needed to turn ccw(); color = next_color; // keep track of new color } else if (next_color-color<0) { positions = color-next_color; // make sure positions is positive cw(); color = next_color; // keep track of new color } } //********************************************************** //Set it all up void initialize(void) { //set up the ports DDRD=0x00; //PORT D in an input DDRB=0xff; //PORT B is an output DDRC =0xff; //PORT C is an output PORTB=0x00; //initialize PortB to 0 PORTC=0xf0; //intialize PortC to f0 (turn on light/fan off) // For 8515: // UCR = 0x10 + 0x08 ; // UBRR = 51 ; //using a 8 MHz crystal reload=256-125; //value for 1 msec for 8 MHz TCNT0=reload; TIMSK=2; //turn on timer 0 overflow ISR (Mega pg. 30) TCCR0=3; //prescalar to 64 //init the task timers time1=t1; //make motor to reset position // color will then be black for(count=0; count<52; count++) { PORTB = 0x08; delay_ms(5); PORTB = 0x04; delay_ms(5); PORTB = 0x02; delay_ms(5); PORTB = 0x01; delay_ms(5); } beat_flag = 0; // intialize beat flag to zero (received no base beats yet) color = 0; // black next_color = 0; // initalize positions = 0; // how many positions to turn delay = t2; //crank up the ISRs #asm sei #endasm }