概要

 BLE Nanoでスリープし、ウォッチドッグタイマのタイムアウトでリセットをかけ、再起動するためのプログラムを作成し、動作を確認した。


背景と目的

 最近、BLE Nanoでスリープさせる必要が出た。そのため、プログラムの作成方法を調べ、実装して動作確認してみる。


詳細

1.方法の調査

 まず、Web等でいろいろ調べた結果、いくつか参考になるサイトが見つかった。

 スリープさせるには、deepsleep命令を呼べばよいようだ。deepsleepは、Windowsだと、BLE Nanoのライブラリが保存されているフォルダで、"C:\Users\username\AppData\Local\Arduino15\packages\RedBear\hardware\nRF51822\1.0.7\cores\RBL_nRF51822\mbed\targets\hal\TARGET_NORDIC\TARGET_MCU_NRF51822\sleep.c"に定義してある。復帰させるには、GPIO変化やUART受信割り込みやウォッチドッグタイマのタイムアウトによるリセット等が使えるらしい。(ウォッチドッグタイマは復帰というものでもないが)
今回は、GPIOやUARTによる割り込みを使用する予定がないので、ウォッチドッグタイマのタイムアウトでリセットさせることにする。

2.実装

 今回は、

  • 起動直後、ビルトインのLED(13番ピン)を3回1秒周期で光らせる
  • ウォッチドッグタイマの設定をする
  • スリープに入る

 という流れでプログラムを作ってみた。ここで注意すべきは、deepsleepを2回続けて呼んでいるところ。なぜかというと、2回呼ばないとスリープに入らない、というか、消費電流が下がらないためだ。これは、いろいろ実験して試した結果であり、どこかにドキュメントがあるわけではないので、なんとも微妙なのだが事実そうだから仕方ない。

const int LED_BUILTIN = 13;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void wdt_init(void) {
  
  NRF_WDT->CONFIG = ( WDT_CONFIG_SLEEP_Run << WDT_CONFIG_SLEEP_Pos); // スリープ中も動かす
  NRF_WDT->CRV = 30 * 32768;             // タイマの長さ 32768 * NでN秒
  NRF_WDT->RREN |= WDT_RREN_RR0_Msk;  // Enable reload register 0
  NRF_WDT->TASKS_START = 1;           // Start the Watchdog timer
  
}

void flash_led(double interval, int count){

  int i;

  for(i = 0; i < count; i++){
    digitalWrite(LED_BUILTIN, LOW);
    delay(interval / 2);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(interval / 2);
  }
  
}

void loop() {

  // 処理
  flash_led(500, 3);
  
  // ウォッチドッグタイマ準備
  wdt_init();

  // スリープへ
  deepsleep();
  deepsleep(); // なぜか2回呼ばないとスリープしない

}
3.動作確認

 上記のプログラムを実行したときに、ちゃんと消費電流が下がっていることを確認するため、先日作製した電流検出回路を使った結果が以下。図3.1は、縦軸は電圧だが、10mA/1Vと読み替えられるようになっている。スリープ⇒復帰を約10数秒繰り返しており、スパイク状の電流が観測されているところが起動中、6~7mA程度の期間が、loop関数実行中、そのあとほとんど0になっている部分がスリープ中となっている。

20170225215536
図3.1 消費電流の波形

 さらに、スリープ中は、どれくらい電流が下がっているかを拡大したところが図3.2。縦軸は1mA/1Vだ。周期的に100uA程度の電流が流れたり、止まったりを繰り返している。理由は不明だが、参考5記述と整合する気がする。(BLE Nanoじゃないけど同じチップを使用)

20170225235407
図3.2 スリープ中を拡大


まとめ

 BLE Nanoでスリープさせるプログラムを作成し、スリープ中の消費電流の確認もできた。