M5StickCの設定初期化スケッチ

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

M5StickCを使っていると、通常は初期化しない場所がおかしくなることがたまにあります。そこで、動きがおかしいときや初期設定として動かすスケッチ例を作ってみました。

スケッチ

#include <M5StickC.h>
#include <Preferences.h>
#include <WiFi.h>
#include "time.h"

// 設定値
const char* ssid          = "SSID";
const char* password      = "PASSWORD";
const char* ntpServer     = "ntp.jst.mfeed.ad.jp";
const int time_difference = 9 * 3600; // Tokyo

// 内部変数
Preferences preferences;
bool ntp_setup = false;
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);

  M5.Lcd.setTextSize(1);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("M5StickC Resetter");

  // NVS領域初期化
  if ( preferences.clear() ) {
    Serial.println("NVS clear");
  }

  // RTC状態リセット
  Wire1.beginTransmission(0x51);
  Wire1.write(0x00);
  Wire1.write(0x00);
  Wire1.write(0x00);
  Wire1.endTransmission();
  Serial.println("RTC status reset");

  // connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

  // Set ntp time to local
  configTime(time_difference, 0, ntpServer);
}

void loop() {
  M5.Lcd.setCursor(0, 8 * 2);

  // RTC NTP set
  struct tm timeInfo;
  if (!ntp_setup && WiFi.status() == WL_CONNECTED && getLocalTime(&timeInfo)) {
    ntp_setup = true;

    // Set RTC time
    RTC_TimeTypeDef TimeStruct;
    TimeStruct.Hours   = timeInfo.tm_hour;
    TimeStruct.Minutes = timeInfo.tm_min;
    TimeStruct.Seconds = timeInfo.tm_sec;
    M5.Rtc.SetTime(&TimeStruct);

    RTC_DateTypeDef DateStruct;
    DateStruct.WeekDay = timeInfo.tm_wday;
    DateStruct.Month = timeInfo.tm_mon + 1;
    DateStruct.Date = timeInfo.tm_mday;
    DateStruct.Year = timeInfo.tm_year + 1900;
    M5.Rtc.SetData(&DateStruct);
  }

  // Wi-fi
  byte macAddress[6];
  WiFi.macAddress(macAddress);
  M5.Lcd.printf("SSID: %s\n", ssid);
  M5.Lcd.print("IP  : ");
  M5.Lcd.println(WiFi.localIP());
  M5.Lcd.printf("MAC : %02X:%02X:%02X:%02X:%02X:%02X\n", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]);
  M5.Lcd.println("");

  // バッテリー
  float vbat = M5.Axp.GetBatVoltage();
  int vlevel = ( vbat - 3.2 ) / 0.8 * 100;
  if ( vlevel < 0 ) {
    vlevel = 0;
  }
  if ( 100 < vlevel ) {
    vlevel = 100;
  }
  M5.Lcd.printf("BAT : %5.3fV %3d%%\n", M5.Axp.GetBatVoltage(), vlevel);
  M5.Lcd.println("");

  // RTC
  static const char *wd[7] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"};
  M5.Rtc.GetTime(&RTC_TimeStruct);
  M5.Rtc.GetData(&RTC_DateStruct);
  M5.Lcd.printf("DATE: %04d-%02d-%02d(%s)\n", RTC_DateStruct.Year, RTC_DateStruct.Month, RTC_DateStruct.Date, wd[RTC_DateStruct.WeekDay]);
  M5.Lcd.printf("TIME: %02d:%02d:%02d", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes, RTC_TimeStruct.Seconds);
  if ( ntp_setup ) {
    M5.Lcd.println(" (NTP)");
  } else {
    M5.Lcd.println("");
  }

  delay(1000);
}

解説

NVS領域

Wi-Fiなどの接続情報を保存している場所です。この領域はスケッチを転送しても更新されません。NSV領域はPreferencesクラスでアクセスをしますが、読み取りをした時点でエントリーが作成されて、容量を消費していまいます。

また、たまに内容が壊れるようで、壊れた状態ですとスケッチを転送しなおしても動かない謎の状態になります。

Preferencesの初期化に失敗したら、内容をクリアする処理を入れたほうがいいみたいですが、ここでは無条件でクリアしています。このためこれまで保存されていたNVS領域はすべて消えてしまいます。

RTC

M5StickCにはリアルタイムクロックが内蔵されており、電源を切っても時計が動いています。そのためM5StickCの電源を再起動しても、内容は初期化されません。まちがってデバッグモードなどにセットしてしまうと時計が動かなくなってしまいますが、現在のライブラリは状態初期化をしていませんのでRTCが動かないままになってしまいます。

こちらも初期状態に初期化をしています。

また、Wi-Fiに接続できた場合にはNTPサーバーに接続して、時間合わせをしています。

Wi-Fi設定

Wi-Fi設定は一度行うと内部に保存されています。そのため人にM5StickCを譲ったり、渡したりした場合には設定を抜き出してしまうことができます。

これを回避するためには、M5StickC全体の初期化か、NVS領域の初期化を行うか、なんでもいいのでダミーのSSIDで接続を試みると、その値が保存されます。

使い方

最初に使う時に初期化(orおかしくなったら初期化)

M5StickCを使う場合には、あらかじめWi-Fi設定やRTCの時間合わせをしておいたほうがこのましいです。

このリセッタをつかって、Wi-Fi設定やRTCの時間合わせを行うことで、他のスケッチを動かしても適切に初期化されている状態になります。

自分で使う場合にはスケッチ例の上の方にあるSSIDとパスワードを変更してから実行してください。

const char* ssid          = "SSID";
const char* password      = "PASSWORD";

人に譲る前に初期化

利用済みのM5StickCを人に譲る場合にはWi-Fi設定などを初期化したほうがこのましいです。このリセッタで初期化したあとに、Arduino IDEの[スケッチ例]->[M5StickC]->[Basics]->[FactoryTest]の購入時に入っているスケッチを入れてあげるといいと思います。

関連情報

まとめ

M5StickCのフラッシュ領域の初期化であればesptoolでerase_flashするか、M5BurnerでEraseをすることで実現できます。

ESP32に依存する部分は全体を初期化したほうがスッキリきれいになります。M5StickCの内蔵部分の初期化にはこのようなスケッチも便利ではないでしょうか?

コメント

タイトルとURLをコピーしました