ESP32 の Wi-Fi アクセスポイントをスマホで選択できるようにしてみた

記事公開日:2018年2月15日
ここの記事のプログラムをさらに改良し、ブラウザのセキュアな SSL 通信で、パスワードを暗号化して送信する、Wi-Fiアクセスポイントセレクターを作ってみました。
合わせて以下の記事をご覧ください。
Arduino – ESP32 で SSLサーバーを構築し、セキュアな Wi-Fi アクセスポイントセレクターを作ってみました

こんばんは。

今回は、コメント投稿などでお問い合わせいただいたこともあり、Arduino – ESP32 の Wi-Fi 設定で、SSID やパスワードをスマホで設定できるようにする実験をやってみました。
しかも、ブラウザで Wi-Fi スキャンされたアクセスポイントを簡単にセレクトできました。
これを使えば、外出先の公共アクセスポイントなどでも簡単に設定できそうです。

残念ながら、高度な Auth 認証が必要なアクセスポイントには接続できませんが、SSID と パスワードだけで接続できるアクセスポイントならば、この方法で簡単に接続でき、外出先で簡単に切り替えできると思われます。

動作している様子の動画を用意したかったのですが、近辺の SSID にモザイクをかける編集が大変だったので、残念ながら動画を作るのを途中でやめました。
静止画写真だけで想像していただければと思います。

Wi-Fiスマホセレクトができれば、パソコンを使わずにスマホだけでアクセスポイントを設定できるので、いろいろな用途に使えそうです。
プログラマーでもない素人の自分がここまで出来るようになるので、ホントにArduino core for the ESP32 のライブラリは良く出来ていて、有難い存在です。

今回のポイントは、ESP32 自体がルーターやアクセスポイントに接続していない時に、どうやってスマホと通信するかという問題です。

ネットで調べたり、いろいろ考えた結果、ESP32 の AP モードを使えば良いことが分かりました。
そう言えばそうですよね。
しばらく使い道が分からなかった AP モードを使えばナンてことは無いんです。

要するに、Arduino – ESP32 のライブラリの soft AP を使うモードです。
これは、ESP32 自身が Wi-Fi ルーター(アクセスポイント)になるのですが、市販の専用ルーターに比べて通信トラフィック容量が小さいので、あまり使い道が無いと思っていました。
でも、今回のように、スマホでアクセスポイントを切り替える用途にはバッチリ使えます。
今頃になって、APモードの利点が分かって来ました。

ESP32 を APモードとSTAモード(ステーションモード)の両方で起動し、まずは APモードでスマホと ESP32 を接続し、Wi-Fi スキャンをかけます。
そこで選択されたアクセスポイントと STAモードで接続するという方法です。
2つのモードがあるということはとっても便利ですね。

また、スマホで選択した SSID と パスワードは、 ESP-WROOM-32 に内蔵の SPIFFS フラッシュに保存し、そこから読み出してアクセスポイントと接続するようにしてみました。
ですから、プログラムを改良すれば、一度設定さえすれば、以後自動接続ということもできると思います。

ということで、自分なりの方法で作った方法を説明したいと思います。
因みに、趣味と独学の素人プログラムですので、動作は保証しません。
無駄なところが多々あると思いますが、あくまで自己満足で作ったものですのでご了承ください。

また、これは SSL通信ではありません。
パスワードは Wi-Fi通信で暗号化されません。
十分ご了承の上、自己責任で使用してください。

その他、もし、誤り等がありましたら、コメント投稿等でご連絡いただけると有難いです。

スポンサーリンク

使うもの

ESP32 ( ESP-WROOM-32 )開発ボード

私の場合は、USB電源の保護機能が充実している、スイッチサイエンスさんの ESPr Developer 32 を使っています。

Amazon.co.jp
ESPr Developer 32
スイッチサイエンス(Switch Science)

これについては、以下の記事も参照してみてください。

ESPr Developer 32 ( スイッチサイエンス製 ) を使ってみました

パソコン、スマホ、USB ケーブル等

ここでは、Windows 10 パソコンと、Android スマートフォンを使って説明しています。

Arduino core for the ESP32 の設定

Arduino IDE は 1.8.5 で動作確認しています。

Arduino IDE で ESP32 の開発ができる、Arduino core for the ESP32 のインストール方法は以下の記事を参照して、予めインストールしておいてください。

Arduino core for the ESP32 のインストール方法

なお、使用するバージョンによって、SPIFFS フラッシュ読み取り不良が起こったりします。

SPIFFS アップローダープラグインのインストール

Arduino IDE に ESP32 SPIFFS フラッシュアップローダープラグインを予めインストールしておいてください。
インストール方法や使い方については、以下の記事を参照してください。

ESP-WROOM-32 ( ESP32 ) SPIFFS アップローダープラグインの使い方

ここで注意していただきたいのは、Arduino core for the ESP32 のバージョンによって、SPIFFSフラッシュ読み取り不良があります。

Commits on Dec 19, 2017 バージョンまでは正常に動作していたのに、Commits on Feb 8, 2018 バージョン に替えると読み取り不良になります。
その場合、データを SPIFFSアップロードした後、Arduino – ESP32 の「スケッチ例」SPIFFS_Test を数回コンパイル書き込みして動作確認した後、ご自分のスケッチをコンパイル書き込みしてみてください。

空の設定ファイルを SPIFFS フラッシュへアップロードする

SPIFFS アップローダープラグインを使って、予め空のテキストファイルを、テキストエディタやメモ帳などで、UTF-8形式で作成してアップロードしておきます。

フォルダ名とファイル名はとりあえず以下のようにしておいてください。

/APconfig/APconfig.txt

このファイルだけアップロードしてしまうと、以前にアップロードされていたファイルが消えてしまうので、必要なファイルと共に改めてアップロードしてください。

ライブラリのインストール

今回は、ESP32 の STAモード(ステーションモード)でインターネットに接続できた場合、それを確認するために、NTPサーバーから時刻を取得します。
その場合、サンプルスケッチを使うよりか、私の自作のライブラリをインクルードした方が簡単なので、それを Arduino IDE にインストールします。

ライブラリはGitHub の以下のリンクにあります。
●ESP32_WebGet
https://github.com/mgo-tec/ESP32_WebGet
ダウンロードした ZIPファイルをArduino IDE にインストールする方法は以下を参照してください。

GitHubにある ZIP形式ライブラリ のインストール方法 ( Arduino IDE )

また、Arduino 標準の Time ライブラリをインストールしておいてください。
以下のリンクにあります。

https://github.com/PaulStoffregen/Time

では、次のページではスケッチを説明します。


スポンサーリンク


「ESP32 の Wi-Fi アクセスポイントをスマホで選択できるようにしてみた」への32件のフィードバック

  1. こんにちは!
    僕もこのような試みをESP8266でやったことがあります。htmlを作ったり結構めんどくさいんですよね ^^;

    最近はsmartConfigという機能を使っています。かなり楽です。
    https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiSmartConfig/WiFiSmartConfig.ino
    ESP-IDFでもサポートされていますので、割と安心して使えると思います。
    もしすでにご存知でしたら失礼しました。

    1. けりさん

      いつも Twitter ではお世話になっております。
      記事をご覧いただき、ありがとうございます。
      m(_ _)m

      smartConfig は使ったことが無いですね。
      これは、公共Wi-Fi などのオープンなアクセスポイントに自動接続するライブラリでしょうか?
      あまり詳しく調べてないのですが、このサンプルスケッチだけ見ても、イマイチ使い方がわかりません。。

      WiFiSTA ライブラリには、setAutoConnect などの関数があって、使い易そうですね。
      これらを使えば、もっと簡略化できるかもしれませんね。
      今度挑戦してみたいと思います。

      いつも有益な情報、ありがとうございます。
      感謝! 感謝!

  2. こんにちは!
    こちらの記事を参考にさせていただいて,スマートフォンからESPの設定を行えるようにしました.しかし,androidなら動作するのですが,iphoneだとWi-Fiに接続できても,ブラウザにアクセスできません.
    そちらはiphoneでも動作していますでしょうか?
    ちなみにブラウザはsafari,google chrome等一通り試してみました.

  3. cyprisさん

    大変申し訳ございません。
    只今、当方の不具合により、過去記事全てのソースコードの’¥’マークと、改行が消えてしまいました。

    ブログを全面修正して、現在復旧しました。

    ただ、その時のコメント投稿も消えてしまいました。
    大変申し訳ございませんでした。
    このコードで試していただくよう、よろしくお願いいたします。
    m(_ _)m

  4. cyprisさん

    こんにちは、教えてほしいのですが、スマホ(Android又はiPhone)から
    ESP32の設定変更の書換ができたそうですが、私は、訪問先のWiFiの
    ルータのSSIDとPassを書き換えられるようにしたいと思います。
    この辺のインターフェースの簡易版を作りたいのですが、注意点など
    教えて頂けませんか。
    宜しくお願いします。

    1. Tomさん

      管理人の mgo-tec です。
      当ブログにお越しいただき、ありがとうございます。

      この質問は cypris さん宛てということで承りました。
      cyprisさん、ご覧でしたらご回答よろしくお願いいたします。

  5. mgo-tec 様

    本テキストにチャレンジしています。
    設定したアクセスポイントへの接続まではできたのですが、ESP32 の soft IP アドレスへの接続ができません。
    Android 7.1.1 を使用、「接続できません」のメッセージとなります。
    アドバイスの程お願いいたします。

    1. juchangさん

      いつも記事のコードを試していただき、ありがとうございます。

      当方で確認したところ、特に問題無く接続できました。
      Android 7.0 です。

      スマホのWi-Fi画面スイッチか、またはWi-Fi設定画面でsoft APへのアクセスは問題ないということですね。
      とすると、ブラウザのURL入力欄のURLはどのように入力されていますか?
      192.168.4.1
      と入力してアクセスできなかったら、
      http://192.168.4.1
      と入力してみてください。
      因みに、ブラウザはGoogle Chromeを使ってみて下さい。

      また、セキュリティーソフトで引っかかっている可能性があります。
      その場合は、一時的にセキュリティーソフトや、Wi-Fiセキュリティーソフトを解除してみてください。

      1. mgo-tec 様

        いつもご面倒をお掛けします。
        Google Chromeを使っていて、http://192.168.4.1 とも入力していますが、いずれも「応答時間が長すぎます。」とのメッセージとなります。
        「空の設定ファイルを SPIFFS フラッシュへアップロードする」というところが今一理解できていないのですが本トラブルと関係ありますでしょうか。
        smartConfig も閲覧しましたが、やはり関連が理解できません。
        ご指導の程よろしくお願い致します。

        1. juchangさん

          そうですか。。。
          APconfig.txt は、station mode のアクセスポイント一覧を保存するためのファイルです。
          soft APのアクセスとは関係ありません。

          ならば、ブラウザのURL欄に192.168.4.1 を入力した後のシリアルモニターはどう表示されるか教えてください。

          1. mgo-tec 様

            シリアルモニターの表示を確認しましたところ、スマホのアクセスポイント選択で表示されるはずの「 15 – AP_STACONNECTED 」の表示がありませんでした。
            パスワードの変更(長めに)、ライブラリーの整理等試してみましたが効果がありませんでした。

          2. juchangさん

            なるほど。
            Arduino IDE の「ツール」で「Core Debug Level」をverboseにしているということで良いでしょうか?
            それは外部Wi-FiルーターにSTA(stationモード)で接続できていないということのようです。

            でも残念ながら、情報が少なすぎて、どこが悪いのか全く判断できません。
            もっと情報をいただきたいので、それ以前のシリアルモニター表示はどのように表示されていますでしょうか?
            scan start
            scan done
            networks found
            などが表示されていますか?
            また、スキャンされたアクセスポイントのSSID一覧は表示されていますでしょうか?

  6. mgo-tec 様

    「 Core Debug Level 」の設定が違っていました。
    verbose に設定し書き込みをしたところ下記のメッセージとなりました。
    [D][WiFiGeneric.cpp:336] _eventCallback():Event:15-AP_STACONNECTED
    dhcps:send_offer>udp_sendto result 0
    [D][WiFiGeneric.cpp:336] _eventCallback():Event:17-AP_STAIPASSIGNED
    scan start
    [D][WiFiGeneric.cpp:336] _eventCallback():Event:1-SCAN_DONE
    scan done

    9 networks found
    0:Buffalo-*-****
    1:**********

    接続の瞬間のみ、AP_STACONNECTED となりますが、その後表示しなくなります。

    1. juchangさん

      私は今、最新版環境で動作確認しています。
      Arduino IDE ver 1.8.9
      Arduino core for the ESP32 1.0.2

      気になったのが、

      [D][WiFiGeneric.cpp:336] _eventCallback():Event:15-AP_STACONNECTED
      dhcps:send_offer>udp_sendto result 0
      [D][WiFiGeneric.cpp:336] _eventCallback():Event:17-AP_STAIPASSIGNED
      scan start
      [D][WiFiGeneric.cpp:336] _eventCallback():Event:1-SCAN_DONE
      

      という一連のところです。
      AP_STACONNECTED
      AP_STAIPASSIGNED
      というのは、なぜかSTAモードでアクセスポイントに接続したということになります。
      最初はSoft AP モードで起動せねばならず、STAモードで起動して、外部ルーターへ接続されてしまっていますね。
      これはおかしいですね。

      このメッセージの前に
      AP_START
      というメッセージがなければ、Soft AP モードで起動できていません。

      私の場合は以下のように表示されます。

      [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 0 - WIFI_READY
      [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 - AP_START
      [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 - AP_START
      

      この記事を書いた当初とArduino core の最新版とではメッセージの出方が違いますが、これは、Soft AP モードがスタートしたというメッセージで、これが正しい動作です。

      今一度、ソースコードの36行目、37行目が正しく入力されているか確認してみてください。
      また、Soft AP モードのSSID とパスワードは半角9文字以上にして、文字以外の記号は入れないで試してみて下さい。

      1. mgo-tec 様

        下記の動作環境となっています。
        Arduino IDE ver 1.8.9
        Arduino core for the ESP32 1.0.2

        Arduino IDE ver 1.8.5 でも試してみましたが同じ結果となります。

        36行目: WiFi.mode(WIFI_AP_STA);
        37行目: WiFi.softAP(ap_ssid, ap_pass);
        としていますが正しいですか。

        SSID とパスワードも半角9文字以上としています。

        ご確認の程お願いいたします。

      2. mgo-tec 様

        その後の調査で、書き込み後シリアルモニターを立ち上げた時点では、[D][WiFiGeneric.cpp:336] _eventCallback(): Event: 0 – WIFI_READY
        [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 – AP_START
        [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 – AP_START
        と表示されていることを確認しました。
        その後の、スマホのアクセスポイントへの接続後に、AP_STACONNECTED
        AP_STAIPASSIGNED
        となっています。

        1. juchangさん

          なるほど。
          AP_START が出て、その後、スマホからのWi-Fiアクセスポイント接続で、ESP32 の Soft AP モードとの接続は出来ているようですね。
          因みに、シリアルモニターには
          Server started
          という文字は表示されていますか?

          Soft APモード接続は出来ているとすると、あとはブラウザとの通信がうまく行っていません。
          Server started という文字が表示された後、ESP32 はサーバーとして動作します。

          その文字が表示されているならば、ブラウザのURL入力欄に 192.168.4.1 を入力してエンターを押した後、シリアルモニターに
          new client
          という文字は表示されますか?

          1. mgo-tec 様

            [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 0 – WIFI_READY
            [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 – AP_START
            [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 13 – AP_START
            Setup done
            Server started
            scan start
            [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 1-SCAN_DONE
            scan done
            ここまでテキストと同じ表示となっています。

            ブラウザのURL入力欄に「 192.168.4.1 」を入力してエンターを押してもシリアルモニターには何の変化もありません。

          2. juchangさん

            それは謎ですね。
            ということは、ソースコードの67行目を通過できていないということです。
            ESP32がclientを認識できないようです。
            ソースコードの50行と51行の間に
            delay(1);
            を入れてみて下さい。

            また、Arduino IDE 「ツール」のボード設定は私は以下のようにしています。

            ボード:  ESP32 Dev Module
            Upload Speed:  921600
            CPU Frequency:  240MHz (WiFi/BT)
            Flash Frequency:  80MHz
            Flash Mode:  QIO
            Flash Size:  4MB (32Mb)
            Partition Scheme:  Huge APP (3MB No OTA/1MB SPIFFS)
            Core Debug Level:  なし
            PSRAM:  Disabled
            シリアルポート:  ※ご自分の M5Camera のUSBポート
            ————————————-
            書込装置: USBasp
            

            Partition Scheme の設定を換えたら、新たにSPIFFSにファイルを書き込む必要がありますので、ご注意ください。
            Partition Schemeは基本的に変えなくても良いと思います。

            以上で試してダメならば、もしかしたら Android のバージョンが影響しているのかも知れません。
            私のAndroidはバージョンが低いために、セキュリティーが甘いのかも知れません。
            もしかしたら、Android7.1の場合は動作しないのかもです。
            私はスマホを買い替える予算が無くて、今は試せません。
            申し訳ありません。

          3. juchangさん

            当方のAndroidバージョンは8.0.0の間違いでした。
            大変失礼いたしました。
            m(_ _)m
            それでも一世代前の端末ですが。。。

            いずれにしても、Android 7.1.1の端末は持っていないので、if(client)文を通過できないのは原因不明です。
            今日中には調査できないと思いますので、今後分かり次第お知らせしたいと思います。

  7. mgo-tec 様

    50行と51行の間に
    delay(1);
    を入れることにより、「 AP_STAIPASSIGNED 」の表示は出なくなりましたが、「 192.168.4.1 」を入力してもシリアルモニターの変化はありませんでした。
    Setup done
    Server started
    scan start
    [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 1 – SCAN_DONE
    scan done

    9 networks found

    0: *************(-84dBm)*
    1: ********** (-85dBm)*
    省略
    8: *********** (-93dBm)*

    [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 15 – AP_STACONNECTED
    scan start
    [D][WiFiGeneric.cpp:336] _eventCallback(): Event: 1 – SCAN_DONE
    scan done
    *networks found
    繰り返し

    貴重なお時間を割いてお付き合いいただきありがとうございました。
    今後ともよろしくお願い致します。

    1. juchangさん

      そうですか。。。
      たぶん、私は原因究明できそうもないです。
      ソースコードの65行、67行で、
      client = server.available();
      if(client){
      のところを通過できないということは、ESP32のサーバープログラムが動作しないということです。

      この記事を書いた当初は Android7.0 で動作確認しているので、Android7.1.1も同様かと思われます。
      juchangさんの端末で何か他のWi-Fiセキュリティーソフトが働いませんでしょうか?

      ソースコードの転記で誤りが無ければ、私には原因究明できそうもありません。
      お手上げです。
      申し訳ございません。
      m(_ _)m

        1. mgo-tec 様

          諦めきれずに試行錯誤を繰り返しています。
          Webで検索している中で、WiFi接続時の電圧降下が原因ではとのやり取りがあり、独立電源が良いという情報がありました。
          具体的なやり方が理解できないため、mgo-tec さんにお伺いを立てたいと思います。
          又、「ツール」のボード設定で、Core Debug Level は「なし」と「 Verbose 」のどちらが良いのかご教示の程お願いいたします。

          1. juchangさん

            すみません。
            当方では症状が出ないため、検証ができないでいます。
            ESP32-DevKitC か ESPr Developer 32 または M5Stack をお使いでしたら、私の方で症状が出ないので、どうやって解決したら良いのか分からない状態です。
            その他のボードでしたら、もしかしたら電源の可能性もありますね。

            電源はUSBハブを使わないことが重要です。
            また、PCのUSBポート(できればUSB3.0)に直挿しして、USBケーブルは太く短く、良質のケーブルを使用してください。
            格安USBケーブルは要注意です。

            また、長い間、ESP32 の大電流によって、PCのUSBポートが破壊されている場合があります。
            その場合はモバイルUSB電源等で試してみるというのも手です。

            Core Debug Level は「なし」にしていた方が、シリアルモニターへの文字出力が減るために安定動作します。
            「Verbose」はどこでプログラムがストップしたかを探るのに有効で、問題無い時は「なし」にする方が良いです。

          2. juchangさん

            そういえば、ひとつ心当たりがありました。
            ソースコードの36行目の前に

            WiFi.disconnect(true, true);

            を追記してコンパイル書き込みしてみてください。
            これは、WiFi設定を全てリセットする関数です。
            昔、私のESP32がWiFiに繋がらなくなった時に、WiFi.begin関数の前にこれを試したら、無事接続できました。

            それでもダメなら、Arduino core for the ESP32 の「スケッチの例」にあるサンプルスケッチ
            SimpleWiFiServer
            の WiFi.begin 関数の1行を以下の2行に書き換えます。

            WiFi.mode(WIFI_AP_STA); //AP mode and STA mode
            WiFi.softAP(ap_ssid, ap_pass);
            

            ap_ssid と ap_pass はそれぞれ半角9文字以上にしてください。
            それでコンパイル書き込みしてみてください。
            それでもうまく行かない場合は、ESP32が故障しているか、USBポートが壊れているという原因になると思います。

            以上、ご確認くださいませ。

  8. mgo-tec 様

    接続成功!
    大変ご面倒をお掛け致しました。
    softAP のアクセスポイントをタップしパスワードを入力すると、「接続先にインターネット接続がありません」というところまではテキスト通りだったのですが、その後「このネットワークはインターネットに接続していません。接続を維持しますか?」というメッセージが出ていたのに気付きませんでした。
    「はい」をタップし、ブラウザの URL 入力欄に「 192.168.4.1 」と入力すると無事接続できるようになりました。
    その後の操作もテキスト通りとなります。
    いつも単純なミスでご迷惑をお掛けし申し訳ありません。
    これでカメラモジュールに集中して取り組むことができます。
    ありがとうございました。

    1. juchangさん

      そういうことでしたか。
      そういえば、この記事には実際の動画を掲載していなかったので、スマホからどういうメッセージが出るか分からないですね。
      この記事の後、セキュアなSSL通信を使ったアクセスポイントセレクターを作った時には動画をアップしていたので、そちらを見ればスマホ側のメッセージ表示が見られました。
      Arduino – ESP32 で SSLサーバーを構築し、セキュアな Wi-Fi アクセスポイントセレクターを作ってみました

      できるだけ動画をアップした方が良いのかな? と、今回、私自身も学びました。
      何にしても、ちゃんと動作してホッとしました。
      こちらこそ、いつもいろいろ試していただき、ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください