電池やバッテリーで動くものを作ろうとすると、やっぱり消費電力が気になるところ。
長く動かそうとすると、とにかく節電!
Arduinoにはスリープモードがあるので、Arduino Nanoを使って実験してみました。
また、AVRマイコンのATTiny44Aでも動作確認を行いました。
少し動作が異なるところがありましたので、そのあたりのメモも兼ねて記録を残しておきます。
使ったもの
- Arduino Nano(ATmega328P搭載)
- ATTiny44A
参考にさせていただいた記事はこちら。
少し古い本だけど、AVRを触り始めてから買ったこの本にもスリープモードについて分かりやすく説明がありました。
スリープモードにもいくつか種類があるんですが、基本的にはパワーダウンモードを使います。
理由は、これが一番節電になるからです。
スリープモードから復帰させる方法は、ざっくり分けると2種類。
- ウォッチドッグタイマーで定期的に復帰させる
- 割り込み処理で復帰させる
これは用途に合わせて使用すると良いですね。
今回は割り込み処理で復帰させる方法を試しました。
この割り込み処理での注意点としては、割り込みさせるためのピンが決まっているということです。
Arduino Nanoの場合は、D2とD3がそれぞれINT0、INT1になっており、この2つのピンをトリガーとして割り込み処理を行います。
ATTiny44Aの場合は、D8がINT0となっています。
このあたりに注意して、ハードとソフトの設計をしないといけません。
割り込みのトリガーも、レベル割り込みとエッジ割り込みの2種類があります。
エッジ割り込みは、スリープモードの1つであるアイドルモードのときのみに使用できるモードで、それ以外のモードだとレベル割り込みになります。
具体的なやり方としては、トリガーのピンをプルアップさせておき、そこへ割り込みの信号を入力します。
割り込みの信号としては下記4種類を識別します。
- LOW:LOWになったとき
- CHANGE:HIGH/LOWの状態が変化したとき
- FALLING:HIGHからLOWへの立ち下がり
- RISING:LOWからHIGHへの立ち上がり
上2つがレベル割り込み、下2つがエッジ割り込みです。
ちなみに、本当に使えないのか試してみたところ、Arduino Nanoではパワーダウンモードでもエッジ割り込みが機能しました。
おそらくArduinoの基板に外部クロックがあるので、そこでうまく動作したのではないかと考えています。
AVR単体だと、パワーダウンモードではエッジ割り込みは機能しませんでした。
今回はLOWのレベル割り込みを使いました。
LOWのレベル割り込みを使うときの注意点としては、割り込み信号を長時間入力していると、その間に何度も割り込み処理が発生してしまうという点です。
このあたりは、プログラムの工夫が必要になる可能性がありそうです。
参考元の記事にはArduino用のスケッチがありましたので、それをもとにAVR単体用に少しプログラムを修正しました。
動作確認用に、復帰時にLEDをON、スリープ時にLEDをOFFしています。
AVRにプログラムを書き込む方法は過去の記事を参考にしてください。
#include <avr/sleep.h>
int SleepModePin = 3; //Sleep_Modeピン
int valsleep = 0; // 後にSleep_Modeピンの値を格納する変数
int WakeUpPin = 8; //復帰ピン
void setup(){
pinMode(SleepModePin, INPUT_PULLUP);
pinMode(WakeUpPin, INPUT_PULLUP);
pinMode(0, OUTPUT); //Lチカ用
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}
void loop(){
digitalWrite(0,HIGH);
valsleep = digitalRead(SleepModePin);
if (valsleep == LOW){
interrupt();
}
}
void interrupt(){
digitalWrite(0,LOW);
attachInterrupt(0,WakeUp, LOW); //AVR単体ではFALLINGは使えない 割り込み時の処理
sleep_mode();
detachInterrupt(0); //外部割込み停止
}
void WakeUp(){
}
Arduinoだと基板が色々と電気を食ってるから、本当に省電力化を目指すならAVR単体で動かさないといけないんですよね。
今回は良い勉強になりました。