勘違いをしていたのでここに記録。
ATMega328PをSleepにした場合は、GPIOの出力が停止されるとなにかの
Webサイトで見たことがあったのでそう思っていたのだが、
実際には違っていた。
検証で使用したのは以下のプログラム
#include <avr/sleep.h> // スリープライブラリ
#define WAKEUP 2 // スリープからの起動ピン
#define LED 3 // LEDピン
void setup() {
delay(1000);
pinMode(WAKEUP, INPUT_PULLUP);
pinMode(LED, OUTPUT);
delay(100);
digitalWrite(LED, HIGH); // LED on
delay(3000);
digitalWrite(LED, LOW); // LED off
}
void loop() {
//ATmegaスリープに入る
digitalWrite(LED, HIGH); // LED on
// delay(200);
interruptWDT(7, true); // 2s & 割り込みのスリープを設定
//スリープから復帰
digitalWrite(LED, LOW); // LED off
delay(2000); //後から消す
}
// 外部入力割込みによる起動処理
void wakeUp() {
//外部入力割込みの際に行いたい処理を記載
}
// WDTがタイムアップした時に実行される処理
ISR(WDT_vect) {
//ウォッチドッグの際に行いたい処理を記載
}
// 割り込みスリープ処理
// t=スリープ時間
// flag: true = WDTも起動 false = 外部割り込みのみ起動
void interruptWDT(unsigned long t, bool flag) {
Serial.flush(); // シリアルバッファが空になるまで待つ
if (flag == true) {
delayWDT_setup(t); // ウォッチドッグタイマー割り込み条件設定
}
// ADCを停止(消費電流 147→27μA)
ADCSRA &= ~(1 << ADEN);
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード指定
attachInterrupt(0, wakeUp, LOW); // Lowになった時にwakeUp関数起動
sleep_enable();
// BODを停止(消費電流 27→6.5μA)
MCUCR |= (1 << BODSE) | (1 << BODS); // MCUCRのBODSとBODSEに1をセット
MCUCR = (MCUCR & ~(1 << BODSE)) | (1 << BODS); // すぐに(4クロック以内)BODSSEを0, BODSを1に設定
asm("sleep"); // 3クロック以内にスリープに入る sleep_mode();では間に合わなかった
sleep_disable(); // 割り込みででここから動作再開
ADCSRA |= (1 << ADEN); // ADCの電源をON(BODはハードウエアで自動再開される)
detachInterrupt(0); //外部割込み停止
}
void delayWDT_setup(unsigned int ii) { // ウォッチドッグタイマーをセット。
// 引数はWDTCSRにセットするWDP0-WDP3の値。設定値と動作時間は概略下記
// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
// 6=1sec, 7=2sec, 8=4sec, 9=8sec
byte bb;
if (ii > 9) { // 変な値を排除
ii = 9;
}
bb = ii & 7; // 下位3ビットをbbに
if (ii > 7) { // 7以上(7.8,9)なら
bb |= (1 << 5); // bbの5ビット目(WDP3)を1にする
}
bb |= (1 << WDCE);
MCUSR &= ~(1 << WDRF); // MCU Status Reg. Watchdog Reset Flag ->0
// start timed sequence
WDTCSR |= (1 << WDCE) | (1 << WDE); // ウォッチドッグ変更許可(WDCEは4サイクルで自動リセット)
// set new watchdog timeout value
WDTCSR = bb; // 制御レジスタを設定
WDTCSR |= _BV(WDIE);
}
よく考えたら昔自分でもATMega328pでSleep中に出力していたのを
途中から思い出した・・・