電池やバッテリーで動くものを作ろうとすると、やっぱり消費電力が気になるところ。

長く動かそうとすると、とにかく節電!

 

Arduinoにはスリープモードがあるので、Arduino Nanoを使って実験してみました。

また、AVRマイコンのATTiny44Aでも動作確認を行いました。

少し動作が異なるところがありましたので、そのあたりのメモも兼ねて記録を残しておきます。

 

 

使ったもの

  • Arduino Nano(ATmega328P搭載)
  • ATTiny44A

 

参考にさせていただいた記事はこちら。

 

 

少し古い本だけど、AVRを触り始めてから買ったこの本にもスリープモードについて分かりやすく説明がありました。

 

 

 

 

スリープモードにもいくつか種類があるんですが、基本的にはパワーダウンモードを使います。

理由は、これが一番節電になるからです。

 

スリープモードから復帰させる方法は、ざっくり分けると2種類。

  1. ウォッチドッグタイマーで定期的に復帰させる
  2. 割り込み処理で復帰させる

これは用途に合わせて使用すると良いですね。

今回は割り込み処理で復帰させる方法を試しました。

 

 

この割り込み処理での注意点としては、割り込みさせるためのピンが決まっているということです。

Arduino Nanoの場合は、D2D3がそれぞれINT0INT1になっており、この2つのピンをトリガーとして割り込み処理を行います。

ATTiny44Aの場合は、D8INT0となっています。

このあたりに注意して、ハードとソフトの設計をしないといけません。

 

割り込みのトリガーも、レベル割り込みエッジ割り込みの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単体で動かさないといけないんですよね。

今回は良い勉強になりました。