45
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

M5StickCのWiFi接続情報を、スマホで入力できるようにする

Last updated at Posted at 2020-01-22

はじめに

こんにちは。電気毛布を自動制御しようと頑張っているエンジニア@tmitsuoka0423です。
以前、obnizを使った電気毛布制御システムを作成しました。

手元に M5StickC があったので、上記の記事で作成したプログラム同等のスケッチを作成し、快適な睡眠生活を送っていました。
また、Ambientというサービスを使い、測定した布団の温度などを可視化して楽しんでいました。

Wi-Fi接続のために、毎回ソースを書き換える?

ある日、フィードバックをもらうため知人に電気毛布システムを貸すことになったのですが、そこで問題が発生しました。
M5StickC に書き込んでいるスケッチに、私の家のネットワーク接続情報がハードコーディングされていたのです。
これでは知人の家のネットワークにつながりません。

ネットワークに接続する
  String ssid = "hoge";
  String password = "hogehoge";
  WiFi.begin(ssid, password);

幸い、知人は IoT にとても明るいエンジニアでしたので必要なソースコードを渡し、自分でSSIDとパスワードを書き換えてM5ScickCに書き込んでくれとお願いできました。

このシステムは、実はArduinoスケッチを修正して、M5StickCに書き込める人しか使えない仕組みになってしまっていたのです。
製品化を考える上で、使える人という観点であまり制約を設けたくありません。

そこで本記事では、スマホからネットワーク接続情報を入力できる仕組みとソースコードを紹介します。

ネットワーク接続までの流れ

接続の流れとしては、大まかに2ステップとなります。

  1. スマホと M5StickC を Wi-Fi 接続し、ネットワーク接続情報を M5StickC に送る
  2. M5StickC をネットワークに接続する
順番に見ていきましょう。

なお、ソースコードはすべて[m5stickc-wifi-entry-sample-public]にアップしていますので、全量はこちらからご確認ください。
記事では、ソースコードをピックアップして説明します。

⓪起動時はアクセスポイントモード

M5StickC は実はアクセスポイントとして振る舞うことができます。

以下のように書くと、M5StickC がアクセスポイントとなり

  • SSID: "M5S_AP"
  • Password: "12345678"
    で、スマホや PC から Wi-Fi 接続できるようになります。
アクセスポイントとして振る舞う
  WiFi.softAP("M5S_AP", "12345678");

(1)スマホからM5StickCにWi-Fi接続する

スマホで Wi-Fi 一覧を見ると、M5S_APがあるはずです。
パスワードを入力して接続します。

(2)ネットワーク接続情報入力ページを表示する、(3)送信する

M5S_APに接続した状態で、http://192.168.4.1/にアクセスすると以下のような画面が表示されるので、家にあるネットワークの SSID とパスワードを入力します。

表示されている画面は、M5StickC から HTML を返却しています。
接続するボタンをタップすると、form が GET で送信されます。

レスポンスを返却する
  WiFiServer server(80);
  WiFiClient client = server.available();
  String s = "";
  s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE html>";
  s += "<html lang=\"ja\">";
  s += "  <head>";
~~~~~~~~~~~~~~~~~~~~() ~~~~~~~~~~~~~~~~~~~~
  s += "    <main>";
  s += "      <form method=\"GET\" action=\"/connect\">";
  s += "        <input type=\"text\" name=\"ssid\" placeholder=\"SSID\" />";
  s += "        <input type=\"password\" name=\"password\" placeholder=\"Password\" />";
  s += "        <button type=\"submit\">接続する</button>";
  s += "      </form>";
  s += "  </body>";
  s += "</html>";
  client.print(s);
  client.flush();
  client.stop();

(4)M5StickCをネットワークに接続する

スマホで入力したネットワーク接続情報を受け取るには以下のようなコードを書きます。

GETリクエストを受け取る
  String req = client.readStringUntil('\r');
  int addr_start = req.indexOf(' ');
  int addr_end = req.indexOf(' ', addr_start + 1);
  String path = req.substring(addr_start + 1, addr_end); // path -> "/connect?ssid=<SSID>&password=<Password>"

String 型の変数pathSSIDパスワードが入ってくるので、正規表現かなにかで抜き出し、以下のコードを書きます。

M5StickCをネットワークに接続する
  WiFi.begin(ssid, password);

ネットワーク接続に成功した場合、M5StickC のモニタにConnected!と表示されます。

シリアルモニタで、ローカル IP アドレスも割り当てられていることが確認できました。

蛇足

  • よく思い出したら、スマートコンセントHS105を Wi-Fi に接続するときに似たような手順で接続していた(HS105 はスマホアプリだった)
  • なんとなく裏側の実装がわかったと同時に、"誰でも IoT 製品を Wi-Fi に接続する方法"としてある種の答え合わせができた気がする。
  • ライブラリとして公開していきたい
45
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?