M5Stackでできること 〜Wi-Fi接続中に一時的に通信できなくなった後の挙動

M5Stackなどで、一定期間毎にWi-Fi経由でWebサーバにデータ送信するようなIoTデバイスをつくる場合、デバイス起動直後(setup内で)にWi-Fi接続を行い、その後は何度も繰り返して(loop内で)データ送信を行うのが一般的です。


スケッチ例「ファイル」>「スケッチ例」>「WiFi」>「WiFiClient」でも、処理フローは以下のようになっています。

// 省略
void setup()
{
    // 省略
    WiFi.begin(ssid, password);
    // 省略
}

void loop()
{
    delay(5000);
    // 省略
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
    }
    // 省略
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n\r\n");
    // 省略
}

ところで、デバイス設置場所のWi-Fiの電波状況が悪い場合、デバイスからのデータが送信できたりできなかったりと、動作が不安定になることがあります。
一旦「WiFi.begin」で正常にWi-Fiネットワークに接続できた後に、電波状況が悪くなり正常にデータ送信できなくなった場合、その後でふたたび電波状況が良くなれば、そのままで引き続き問題なくデータ送信できるのか、それとも「WiFi.begin」でWi-Fiネットワークへの接続をやり直さなければならないのか、気になりました。

そのため、以下のような簡単な実験を行ってみました。

  • スケッチ例「WiFiClient」と同様の処理フローで「Wi-Fi接続」と「データ送信」を行う。
  • 何回かデータ送信を行ったあと、Wi-Fiルータの電源をオフにする。
  • 何回かデータ送信に失敗するのを確認した後、Wi-Fiルータの電源をオンにする。
  • その後も、問題なくデータ送信できるかどうか確認する。

スケッチは以下のとおりです。
スケッチ例「WiFiClient」とほぼ同じです。

#include <M5Stack.h>
#include <WiFi.h>

const char* ssid     = "XXXXXXXX";
const char* password = "XXXXXXXX";
const char* host     = "XXXXXXXX";
const char* event    = "XXXXXXXX";
const char* chipid   = "TEST01";

void setup() {
  M5.begin();

  // Wi-Fi接続
  Serial.println("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
}

void loop() {
  // 1分待つ
  delay(60000);

  // データ送信
  int val0 = random(100, 1000);
  Serial.println("");
  Serial.println("connecting to host");

  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  String url = "";
  url += event;
  url += "?chipid=";
  url += chipid;
  url += "&val0=";
  url += val0;

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
  Serial.println("closing connection");
}

結果(シリアルモニタの表示内容)は以下のとおりです。

Connecting to WiFi
..................
WiFi connected

connecting to host
closing connection

connecting to host
closing connection
			←Wi-Fiルータの電源をOFF
connecting to host
connection failed

connecting to host
connection failed
			←Wi-Fiルータの電源をON
connecting to host
closing connection

connecting to host
closing connection

デバイスが動作している途中に、一時的にWi-Fiでのデータ送信ができなくなっても、通信が復活すれば、それ以降は引き続き問題なくデータ送信できました。

これまでは、正常にデータ送信できなかった場合、M5Stackをリセット(再起動)して、スケッチを最初から実行しなおしたりしていましたが、そのようなことをしなくても問題ないようです。


なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。