void change_light_mode(){ get_lcd()->clear(); get_lcd()->setCursor(0,0); get_lcd()->print("Light mode"); get_lcd()->setCursor(11,1); if(light_mode == AUTO){ light_mode = ON; get_lcd()->print("ON"); } else if(light_mode == ON){ light_mode = OFF; get_lcd()->print("OFF"); } else{ light_mode = AUTO; get_lcd()->print("AUTO"); } auto_time = -60000; // So that auto mode activates directly light_cycle(); long int wait = millis(); while(millis() - wait < 1500 ){ // Wait 1500 ms if(millis() - wait > 300){ if(check_button(button_2, change_light_mode)){ break; } } } }
boolean light (byte led) { int i; tune_playscore (light_sound); led_lighting = led; led_on[led] = true; lighting_skips = MAX_BRIGHTNESS_CYCLE_SKIPS; // start with maximum minor cycle skips lighting_skipcount = 0; do { for (i=0; i<CYCLES_PER_BRIGHTNESS_INCREMENT; ++i) if (light_cycle()) return true; // stop if button pushed --lighting_skips; //gradually reduce minor cycle skips } while (lighting_skips>0); led_lighting = 0xff; // nothing lighting up now return false; }
int main (void) { byte led, night, i; boolean center_shamas; // candle lighter is LED 8, not LED 4 unsigned long sleepcounter; // Clear watchdog timer-- this can prevent several things from going wrong. MCUSR &= 0xF7; //Clear WDRF Flag WDTCSR = 0x18; //Set stupid bits so we can clear timer... WDTCSR = 0x00; MCUCR &= 0xCF; //Disable sleep mode init_timers(); // initialize both timers, for music and for delays // configure I/O ports restart: DDRA = (1<<SPEAKER2)+(1<<SPEAKER3); PORTA = 0; DDRB = (1<<LED5)+(1<<LED6)+(1<<LED7)+(1<<LED8); PORTB = (1<<BUTTON); // pushbutton has a pullup DDRD = (1<<SPEAKER1)+(1<<SPEAKER2)+(1<<LED0)+(1<<LED1)+(1<<LED2)+(1<<LED3)+(1<<LED4); PORTD = 0; for (led=0; led<9; ++led) led_on[led] = false; for (i=0; i<NUM_CHANS; ++i) playing[i] = false; while (BUTTON_DOWN) ; // wait for button to be released #if 0 // test all notes {byte note; for (note=21; note<109; ++note) { tune_playnote(0, note); tune_delay(200); tune_stopnote(0); tune_delay(50); } tune_delay(1000); } #endif #if 0 // test wait timer accuracy {byte i; for (i=0; i<10; ++i){ tune_playnote(0,60); tune_delay(100); tune_stopnote(0); tune_delay(900); } } #endif // the current night is stored in non-volatile EPROM; go to the next night. night = eeprom_read_byte((byte *)EEPROM_addr); if (night > 7) night = 7; // uninitialized? start with 0 if (++night > 7) night = 0; // next night eeprom_write_byte((byte *)EEPROM_addr,night); // light the shamas center_shamas = true; // no longer an option: PORTA & (1<<JMP1); // jumper 1 means shamas is on the end tune_delay(2000); // wait two seconds led = center_shamas ? 4 : 8; for (i=0; i<4; ++i) { // simulate striking a match, sort of tune_playscore (match_sound); PORT(led_port[led]) |= led_mask[led]; // turn it on while (tune_playing) ; PORT(led_port[led]) &= ~led_mask[led]; // turn it off tune_delay (300); } if (light(led)) goto restart; // now light it // light one or more other candles, depending on the night led = 7-night; // start with the newest light if (center_shamas && led>3) ++led; do { delay_with_lights (MSEC_TO_CYCLES(1500)); if (light (led++)) goto restart; if (center_shamas && led==4) ++led; } while (night--); // play the music while keeping the lights lit delay_with_lights (MSEC_TO_CYCLES(2000)); tune_playscore (score); while (tune_playing) { if (light_cycle()) { tune_stopscore(); goto restart; } } // Wait half an hour with the lights on, then turn off #define SLEEP_MINUTES 30 for (sleepcounter = SLEEP_MINUTES*60UL*1000UL/(ON_TIME+OFF_TIME); sleepcounter; --sleepcounter) { if (light_cycle()) goto restart; } PORTA = 0; PORTB = 0; PORTD = 0; DDRD = 0; DDRB = 0; DDRA = 0; MCUCR &= 0xCF; // ensure power-down mode MCUCR |= 0x30; // enable sleep & power-down modes asm("sleep"); //Go to sleep! }
boolean delay_with_lights (int cycles) { // callers should use this macro, so that division is done at compile time #define MSEC_TO_CYCLES(msec) msec/(ON_TIME+OFF_TIME) while (cycles--) if (light_cycle()) return true; return false; }