赤外線センサー GP1UXC41QS は 0.3~0.6[mA] の電流を消費する。コイン電池 CR2032 の容量が 225[mAh] とすると、センサーの消費電力だけで 375時間=15日 くらいで電池がなくなってしまう。これに AVR マイコンの消費も加わるので、実際はもっと短くなる。
そこで、省電力化のために、通常は AVR マイコンをスリープ状態にして、ウォッチドッグタイマ割り込みで定期的に起動し、赤外線センサーの入力を見て、赤外線を受信していなければまたスリープすることにした。 赤外線センサーの電源は、AVR マイコンの出力ピンから取り、スリープ中は OFF にする。
この方法はウォッチドッグタイマ割り込みのある AVR でしかできない。今回は Tiny10 でテストした。メインクロックは内蔵 CR で 1[MHz] とする。
スリープ後 125[ms] にウォッチドッグ割り込みが発生するように指定して、割り込みが発生したら IR センサの電源を入れて 1[ms] 待つ (センサの出力の安定を待つため)。その後 IR センサの出力を読んで、L (赤外線信号あり) ならコードを実行、H (赤外線信号なし) ならスリープする。これの繰り返しを行う。
10Ωの抵抗は電流測定用。この両端の電圧をオシロで測定して、消費電流を測定した。
結果は、1秒間に約7回、1.06[ms] の間、最大約 6[mA] のパルス状の電源電流が流れた(オシロのピーク値測定モードで測定したので、実際の消費電流はこれより小さいと思う)。それ以外 (スリープ中) の消費電流はノイズに埋もれて測定できなかったが、アナログテスターでの測定とデータシートによると、約 4[μA] くらいと思われる。
平均すると、常時 50[μA] 程度の電流が流れているのと等価になる。容量 225[mAh] の CR2032 なら 4500時間=187日間動作するはず。あくまで理想上の計算なので、実験してみないとわからないが。
割り込み周期を変更したり、待ち時間を短縮すれば、さらに消費電力化も可能と思われる。
ちなみに家電用の赤外線リモコンの場合、1ビットを表すパルス1個は 1~4[ms] 程度の長さ。信号全体でも 100~200 [ms] 程度のことが多いので、今回の方法の速度では、信号全体を取り込むことはできない (割り込みで赤外線信号に気付いた時は、すでに信号の前半を取りこぼしてしまっている)。信号が繰り返し送られることを前提として受信するか、リーダーが長い特殊な赤外線フォーマットで通信する必要がある。
ウォッチドッグタイマ割り込みで定期的にIRセンサを起動 (Tiny10, 1MHz)。 PB0 から IR センサの電源を出力する。10Ωの抵抗は電流測定用。 |
// 消費電力測定: Tiny10 用 #include <avr/io.h> #define F_CPU 1000000UL #include <util/delay.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <avr/wdt.h> // 起動前にウォッチドッグを禁止 uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3"))); void get_mcusr(void) { mcusr_mirror = RSTFLR; RSTFLR = 0; wdt_disable(); } // ウォッチドッグ割り込みハンドラ EMPTY_INTERRUPT(WDT_vect) int main(void) { DDRB = 0b11111011; // PORTB 0,1,3 を出力に PUEB = 0b00000000; // プルアップしない // ウォッチドッグタイマ割り込みを有効にして(WDIE=1) // ウォッチドッグリセットは発生しないようにする(WDE=0)(125ms) RSTFLR = 0; WDTCSR = _BV(WDIE) | _BV(WDP1) | _BV(WDP0) ; sei(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); while(1) { PORTB |= _BV(PB0); // IR 電源 ON _delay_ms(1); // 1[ms] 待つ if ((PINB & _BV(PB2)) == 0) { PORTB &= ~_BV(PB0); // IR 電源 OFF // ここに赤外線を受信したときに実行したい処理を書く } PORTB &= ~_BV(PB0); // IR 電源 OFF wdt_reset(); WDTCSR |= _BV(WDIF); sleep_mode(); } }
パルス状に見えるのは1秒間に約7回(144[ms]間隔)の電源 ON。 それ以外の期間はスリープ。スリープ中の測定ノイズが激しい。 オシロはピーク検出モードにしている。 |
1回のパルスを拡大すると、長さは1.06[ms]。 この期間、最大約 6[mA] の電流が流れている。 |