🛠️

LTE-M Shield for Arduino の長期稼働安定化

2021/02/18に公開

はじめに

前回の記事で、センサーデータを SORACOM Harvest にアップロード& Lagoon で可視化していましたが、稼働後しばらくするとデータが途絶えていて、デバイスの電源を入れ直してから1日半くらいで止まるというのを繰り返していました。

その状態でコンソールのログを確認してみると、読み取ったセンサーデータなどが表示されていますが、送信の際の Sending...Failed というログから、マイコン(Arduino)は動いているが通信モジュールの方の動作がおかしいことが伺えます。
また、電源を繋いだままで、シリアルコンソールを開け直すことでマイコンにリセットがかかり、プログラムがリスタートしますが、その状態ではデータの送信が再開されませんでした。マイコンは生きているけど、通信モジュールの動作がおかしいという事を裏付ける挙動ですね。

モジュールのリセット方法

もしソフトウェア的にモジュールを再起動することができれば...と思っていたところ、Max が

D15がBG96のRESETにつながってるかもな。出荷時のIoT Shieldのボード上RESETもショートしてるので使えそう。

と情報をくれました。
また BG96 のハードウェアデザインドキュメントによれば、150 ms ~ 460 ms 程度のパルスでリセットができるみたいです。

実装

Arduino のスケッチ起動時に呼ばれる setup() 内で、モジュールのリセットを行ってから接続処理を行うようにしてみます。

#define BG96_RESET 15

void setup(){
  :
  pinMode(BG96_RESET,OUTPUT);
  digitalWrite(BG96_RESET,LOW);
  delay(300);
  digitalWrite(BG96_RESET,HIGH);
  delay(300);
  digitalWrite(BG96_RESET,LOW);
  :
  modem.restart();
  :
}

これを setup()modem.restart() より前にいれることで、モジュールのリセットを確実に行ってから接続処理を開始するようになりました。

定期的な Arduino リセット

さて次は定期的に Arduino をリセットするための仕組みですが、これは先人の知恵を拝借して、下記の様に実装しました。稼働時間が一定時間(下記の例では 1 日)を経過したら、Arduino ごと再起動するという感じになっています。

#define RESET_DURATION 86400000UL // 1 day
void software_reset() {
  asm volatile ("  jmp 0");
}

void loop(){
  :
(センシング&データ送信のための処理)
  :
#ifdef RESET_DURATION
  if(millis() > RESET_DURATION )
  {
    CONSOLE.println("Execute software reset...");
    delay(1000);
    software_reset();
  }
#endif
}

これで、データが途絶えることがなくなりました!めでたしめでたし。

最後に

soracom-labs/arduino-dragino-unifiedのレポジトリにもすでに反映されていますので、データ送信が止まってしまうという場合にはぜひ参考にしてみてください!

Discussion