JUGEMテーマ:Arduino


ArduinoでDeepSleepを利用する
■実際の消費電流の測定

実際の電流を測定しています。
テスターはマイクロアンペアのモードです。
起動直後大き目の電力が流れてその後
6μA~7μAぐらい消費します。DeepSleepしています。
スリープは8秒毎に解除される、のでその時に赤いLEDをピカッと光らせます。
Sleepから復帰して赤いLEDを光らせるために一瞬電流が多く流れます。
LEDを光らせた後に再びsleepに入ります。
3回繰り返した後に緑のLEDを1秒間光らせます。
この時も電流が多く流れます。
■プログラム解説
 
 □loopの開始と終了に20ミリ秒のdelayを入れています。
  これはsleep復帰後すぐにSerial通信をすると文字化けしてしまうためです。
 □watchDogSleep();
  これがSleepのメインになります。
  消費電力を抑えるにはなるべく長くsleepさせておいたほうが良いと考え指定できる最大の8秒sleepさせます。
  でも、もっと長くsleepさせたいので回数を指定するようにしてsleep→復帰→sleepを繰り返すようにています。
  
  ループの中で実際のDeepSleepと復帰処理を行います。
  
 □パワーダウンモードを設定 SM1 パワーダウンモード
 
   SMCR |= 0b00000001 | 0b00000100;
 
 □AD変換機能をOFFにする ADEN 復帰後ONにする
 
  ADCSRA &= ~(0b10000000); //ADコンバーターEnableをOFF
  
 □おっちドッグタイマーをセットする
 
  asm("wdr");
  WDTCSR |= 0b00011000; //WDCE WDE おっちドッグタイマー設定モード
  //WDTCSR = 0b01000000 | 0b000110;// 1 秒
  //WDTCSR = 0b01000000 | 0b000111;// 2 秒
  //WDTCSR = 0b01000000 | 0b100000;// 4 秒
  WDTCSR = 0b01000000 | 0b100001;// 8 秒
 
 □低電圧検出器を停止する(スリープの間有効)
 
  MCUCR |= 0b00100000 | 0b01000000;  //BODSE BODS
  MCUCR = (MCUCR & ~(0b00100000)) | (0b01000000); //BODSE BODS
  
 □スリープする。 指定した時間で戻る 上記の低電圧検出器を停止の流れで実施
 
  asm("sleep");
 
 □おっちドッグタイマーを停止する
 
  asm("wdr");
  MCUSR &= ~(0b00001000);          //おっちドッグタイマーリセットフラグをOFF WDRF
  WDTCSR |= (0b00010000)|(1 << 0b00001000); //おっちドッグタイマー設定変更 WDCE WDE
  WDTCSR = 0b00000000;           //おっちドッグタイマー停止
 
 □AD変換機能をONにする
 
  ADCSRA |= 0b10000000;   //ADENをON
 □ISR(WDT_vect)
 
   赤いLEDをピカッと光らせます
■プログラム
void setup() {
  Serial.begin(9600);
  Serial.println("ver1.0");
  Serial.println("start:");
  pinMode(4, OUTPUT);
  pinMode(13, OUTPUT);
}
#define sleep_time 20
void loop() {
  //
  //loop関数開始のログ出力
  //
  delay(sleep_time);  //
  Serial.println("loop start:");
  delay(sleep_time);  //
  //
  //緑のLEDをピカッと光らせる
  //ここにプログラムを書く
  //
  digitalWrite(4, HIGH);
  delay(100);
  digitalWrite(4, LOW);
  //
  //ウォッチドッグタイマーでスリープする 8秒×3=24秒
  //
  watchDogSleep(3);
  //
  //おっちドックタイマーから復帰のログ出力
  //
  delay(sleep_time);
  Serial.println("loop end:");
  delay(sleep_time);
}
//watchdog interrupt
ISR(WDT_vect){
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
}
void watchDogSleep(int count)
{
  //
  //おっちドッグタイマーが最大8秒しかできないので
  //1秒設定にしてループする
  //
  for(int i=0;i     // パワーダウンモードを設定 SM1
    SMCR |= 0b00000001 | 0b00000100;
  
    // AD変換機能をOFFにする ADEN
    ADCSRA &= ~(0b10000000);  //
    
    // おっちドッグタイマーをセットする
    asm("wdr");
    WDTCSR |= 0b00011000; //WDCE WDE set
    //WDTCSR =  0b01000000 | 0b000110;// 1 sec
    //WDTCSR =  0b01000000 | 0b000111;// 2 sec
    //WDTCSR =  0b01000000 | 0b100000;// 4 sec
    WDTCSR =  0b01000000 | 0b100001;// 8 sec
  
    // 低電圧検出器を停止するスリープの間有効
    MCUCR |= 0b00100000 | 0b01000000;   //BODSE  BODS
    MCUCR = (MCUCR & ~(0b00100000)) | (0b01000000); //BODSE  BODS
    
    //スリープ 指定した時間で戻る
    asm("sleep");
  
    // おっちドッグタイマーを停止する
    asm("wdr");
    MCUSR &= ~(0b00001000);                   //おっちドッグタイマーリセットフラグをOFF WDRF
    WDTCSR |= (0b00010000)|(1 << 0b00001000); //おっちドッグタイマー設定変更 WDCE WDE
    WDTCSR = 0b00000000;                      //おっちドッグタイマー停止
  
    // AD変換機能をONにする
    ADCSRA |= 0b10000000;     //ADEN
  }
}