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の使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。
ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。