#include #include #define LED1 0 #define LED2 1 #define LED3 2 #define SW 3 #define BUZZ 4 // 3v電源クロック600kHzで1秒間隔の割り込み(実際は1.2秒くらいで1回の割り込み) #define MINCOUNT 51 // 1分間のウォッチドッグ割り込み回数 #define SLEEPCOUNT 25 // 30秒ほどでスリープ volatile uint8_t minute, second; uint8_t ledNo[] = {LED3, LED2, LED1}; // ウォッチドッグタイマー割り込みエントリ ISR(WDT_vect) { if(++second == MINCOUNT) { second = 0; if(++minute == 60) { minute = 0; } } } // ピン変化割り込みエントリ ISR(PCINT0_vect) { cli(); GIMSK &= ~_BV(PCIE); PCMSK &= ~_BV(PCINT3); sleep_disable(); sei(); } void setup() { // ピンの入出力設定 DDRB = 0b00010111; PORTB = 0b00001000; // 省エネ設定 ACSR |= _BV(ACD); // アナログ比較器電力削減 ADCSRA &= ~_BV(ADEN); // A/D変換禁止 PRR |= _BV(PRADC); // A/D変換器電力削減 minute = 0; second = 0; cli(); // 割込禁止 // ウォッチドッグタイマ設定 wdt_reset(); //ウォッチドッグタイマーリセット // 1秒間隔で割り込み WDTCR = _BV(WDTIE) | _BV(WDP2) | _BV(WDP1); // スリープ設定 set_sleep_mode(SLEEP_MODE_PWR_DOWN); sei(); // 割込許可 } void loop() { if(digitalRead(SW) == LOW) timerON(); if(second > SLEEPCOUNT - 1) // スリープ時間チェック { beep(400); cli(); WDTCR &= ~_BV(WDTIE); // ウォッチドッグ割込禁止 // ピン変化割り込み PCMSK |= _BV(PCINT3); // ピン3変化割り込み GIMSK |= _BV(PCIE); // ピン変化割り込み許可 sleep_enable(); // スリープ許可 sei(); sleep_mode(); minute = 0; second = 0; cli(); WDTCR |= _BV(WDTIE); // ウォッチドッグ割込許可 sei(); } } void timerON() { int led = 0; cli(); WDTCR &= ~_BV(WDTIE); // ウォッチドッグ割込禁止 sei(); beep(1200); while(digitalRead(SW) == LOW); // スイッチリリース待ち second = 0; minute = 0; cli(); WDTCR |= _BV(WDTIE); // ウォッチドッグ割込許可 sei(); DDRB = 0b00010111; // なぜかPINの再設定が必要 while(minute != 4) { if(minute == 3) { if(!(second & 1)) { digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); } else { digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); } } else { if(!(second & 1)) digitalWrite(ledNo[minute], HIGH); else digitalWrite(ledNo[minute], LOW); } if(digitalRead(SW) == LOW) goto INTERRUPT; } cli(); WDTCR &= ~_BV(WDTIE); // ウォッチドッグ割込禁止 sei(); // アラーム while(true) { DDRB = 0b00010111; // なぜかPINの再設定が必要 digitalWrite(ledNo[led], HIGH); beep(1200); if(digitalRead(SW) == LOW) break; delay(200); digitalWrite(ledNo[led], LOW); if(++led == 3) led = 0; } INTERRUPT: beep(500); while(digitalRead(SW) == LOW); digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); second = 0; minute = 0; cli(); WDTCR |= _BV(WDTIE); // ウォッチドッグ割込許可 sei(); } void beep(unsigned int hz) { tone(BUZZ, hz); // durationオプションはノイズが出る delay(200); noTone(BUZZ); }