※この記事は2020年4月7日に更新されました。

本日はArduino IDEの中にあるスケッチ例を使って、M5Stackをサーバー化し、PCのプラウザから接続してみたいと思います。

→Arduino IDEのインストールなどについてはこちら

【参考書籍】M5Stackに関しては下島先生のこちらの書籍を参考にさせて頂ています。

【ポイント】mDNS

multicast DNSというサーバーも同時に起動していますので、IPアドレスで接続する必要はなく、任意の文字列でアクセスすることができます。

if (MDNS.begin("m5stack")) {
         M5.Lcd.println("MDNS responder started");
     }

M5stackの場合は、モニターがついているので、割り当てられたIPアドレスを目視で確認することができます。

そのため、もちろんローカルサーバーの場合はIPアドレスで接続すればいいのですが、名前を任意で設定できた方が管理がしやすいのではないでしょうか?

それに、ラズパイなどのモニターレスのデバイスで動かす場合などに備えてしっかりと、mDNSで使いたいですよね。

というわけで、mDNSを使い、任意アドレスを設定します。

サンプルコードではm5stackとしていますが、もちろんプロジェクトや、管理目的別に名前を設定してOKです。

スケッチ例

Arduino IDEを起動し、ファイル→スケッチ例→Web Server→Hello Serverを呼び出しましょう。

すると、スケッチ例が出てきます。

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const char* ssid = "........";
const char* password = "........";

WebServer server(80);

const int led = 13;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "hello from esp8266!");
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void) {
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
}

今回はM5stackで使うので、必ず

#include <M5Stack.h>

を宣言しましょう。

下島先生のサンプルコードをライティングさせてもらいました。

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

const char* ssid = "・・・・・・・";
const char* password = "・・・・・・";

WebServer server(80);

void handleRoot() {
  server.send(200, "text/plain", "hello from M5Stack!");
  M5.Lcd.println("accessed on \"/\"");
}


void handleNotFound() {
  server.send(404, "text/plain","File Not Found\n\n");
  M5.Lcd.println("File Not Found");
}


void setup(void) {
     M5.begin();

     WiFi.begin(ssid, password);
     while (WiFi.status() != WL_CONNECTED) {
         delay(500);
         M5.Lcd.print(".");
     }
     M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
     M5.Lcd.println(WiFi.localIP());

     if (MDNS.begin("m5stack")) {
         M5.Lcd.println("MDNS responder started");
     }


     server.on("/", handleRoot);
     server.onNotFound(handleNotFound);

     server.begin();
     M5.Lcd.println("HTTP server started");
}
  
void loop(void) {
  server.handleClient();
}

考えられるエラー

筆者はこれで4時間格闘しました。

PCは有線接続でしたので、スマホでチェックしていました。

スマホでチェックしていけたらPCでもいけるだろうと踏んで・・・

しかし、エラー、そしてまたエラー。

悩みに悩んで、割り当てられたIPアドレスで接続を試みると成功。

ということは、mDNSまでのプログラムは機能しているというわけです。

問題はmDNSがうまくいっていない。

何度も何度もデバッグ作業・・・

しかし、mDNS以外のプログラムは正常に動作している。

そこで調べてみると・・・

androidはmDNSに対応していないとの情報が・・・

早速PCの有線をWiFiに切り替えてトライしてみると、あったりとmDNS接続完了。

無事にM5stackのローカルサーバー化に成功しました。

あとは、printf関数で、表示させたい文字をHTMLで入力していくだけ。

温度計や湿度計の計測結果などもM5Stackに表示させるのであれば通常のテキストで良いですが、プラウザに表示させるのであればHTMLが必須になります。

デバッグチェックポイント

・wwwになっていないか?
→もちろんローカルサーバーですので世界と繋がる必要はありません。

・androidからアクセスしてないか?
→androidはmDNS変換に対応していないそうです。

・割り当てられたIPアドレスから接続できるかどうか?
→バグの可能性を潰していきましょう。

次回はprintfでHTMLを表示させてみたいと思います。