ESP8266にwifi経由でArduinoスケッチを書き込めるライブラリ「ESP8266 Web Update」のUIを、力技でマシな見た目にする話—ElegantOTAは使わないコース—

タイトルのまんまです。 超ニッチな話だと思いますが、自分用の備忘録をかねて書きます。

この記事は、こんな人向けです

  • Arduino環境でESP8266を使っている
  • 「ESP8266HTTPUpdateServer library」の標準UIがちょっとしょぼいなって思った
  • 細かいことは気にしない

そもそもESP8266とは何なのかというと、WiFi内蔵でArduino互換機として使える安価なマイコンです。

ja.wikipedia.org

お手軽に使ってみるなら、とりあえずスイッチサイエンスの「ESPr Developer」がベストだと思います。

www.switch-science.com

このマイコン、すばらしいことに、ライブラリで提供されているOTA(Over the air)アップデートという機能をつかえば、WiFi経由でスケッチを書き込むことができます。

手が届きづらい場所に設置する機器なんかにぴったりです。

www.motohasi.net

さて、↑の記事にある通り、OTAの方法は3種類用意されています。

その中で、今回は「Webブラウザでのアップデート」方式が対象の小ネタです。

UIがしょぼい

さて、まずは標準のUIを見てみましょう。

ライブラリのExampleが用意されているので、これを書き込んでみます。

スケッチ例から「ESP8266HTTPUpdateServer」→「WebUpdater」を選んでください。

your-ssidyour-passwordのところには、自分のWiFi環境の情報を入れましょう。

#define STASSID "your-ssid"
#define STAPSK  "your-password"

あと書き込み前に、ボード設定の「Flash Size」だけ「2M (1M SPIFFS)」にしておきましょう。なんでそうするか気になったら、各自調べてみてください。

書き込みが終わってWiFiがつながれば、http://esp8266-webupdate.local/updateでアップデート画面を開くことができるはずです。

f:id:at_you_key:20191001205401p:plain
これはアップロード画面

f:id:at_you_key:20191001205414p:plain
こっちは完了画面

ほら、しょぼくないですか?

かっこいいライブラリもあるけど

簡単にかっこいい見た目にできる「ElegantOTA」というライブラリもあります。

github.com

プログレスバーまで表示されちゃったりして、まさにエレガントです。

ArduinoIDEのライブラリマネージャーからもインストールできます。

ライブラリ突っ込むだけで手軽に綺麗なUIが欲しいなら、いまのところこれ一択という感じです。

しかし、ちょっと自己主張が強すぎるのが使い所を選びます。

HTML/CSSをゴリゴリ改造する

そこで今回ご提案するのが、第3の選択肢「力技ちからわざ」です。

ライブラリのHTML部分をゴリゴリ書き換えて、ほどほどの見た目を目指してみましょう。

ライブラリを一式コピーしてくる

もとのライブラリはそのまま残しておきたいので、スケッチのフォルダにコピーを作って改造してきます。

まずはさっきのExampleを別名保存してテスト用に使いましょう。

つぎにオリジナルのライブラリ探します。 けっこう深い階層にあるので、ファイル検索で「ESP8266HTTPUpdateServer.cpp」を探すのが楽だと思います。

場所が見つかったら、「ESP8266HTTPUpdateServer.cpp」と「ESP8266HTTPUpdateServer.h」を、自分のスケッチのフォルダにコピーしておきましょう。

インクルード文を書き換える

インクルードでライブラリを指定するとき、<>で囲むとIDEにインストールされているライブラリ、""で囲むとスケッチと同じフォルダを見に行くそうです。

ここでは改造版ライブラリをスケッチと同じフォルダに置くので、関係するところを""囲みに書き換えましょう。 書き換えるのはこの2箇所です。

  • スケッチの<ESP8266HTTPUpdateServer.h>
  • 「ESP8266HTTPUpdateServer.cpp」の<ESP8266HTTPUpdateServer.h>

HTML部分を改造する

さて、「ESP8266HTTPUpdateServer.cpp」の中を見てみると、もう見るからにHTMLな値が入った変数serverIndex[]successResponse[]があるので、あとはここを書き換えていくだけですね。

ちなみにR"()"の部分はローリテラルといって、文字列をエスケープしないで変数に突っ込むことができる書き方だそうです。

cpprefjp.github.io

あとはもう、煮るなり焼くなりお好きに。

とりあえず、文章を変えつつCSSを追加してみました。

static const char serverIndex[] PROGMEM =
  R"rawliteral(
<html>

<head>
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
        <meta charset="UTF-8">
        <style>
                body {
                        -webkit-text-size-adjust: 100%;
                        font-family: "游ゴシック Medium", YuGothic, YuGothicM, "Hiragino Kaku Gothic ProN", "Hiragino Kaku Gothic Pro", メイリオ, Meiryo, sans-serif;
                }

                h2 {
                        text-align: center;
                        font-size: 1.75rem;
                        line-height: 1.225;
                        padding-bottom: 0.5em;
                        border-bottom: 2px solid rgb(190, 190, 190);
                }

                .Button {
                        line-height: 30px;
                        width: 350px;
                        height: 30px;
                        cursor: pointer;
                        font-size: 1em;
                }

                input[type='submit'] {
                        background-color: #6279c7;
                        border: 1px solid #6279c7;
                        border-radius: 2px;
                        color: #fff;
                        line-height: 30px;
                        font-size: 1em;
                        font-weight: bold;
                        width: 8em;
                        height: 40px;
                }

                .container {
                        margin-top: 1em;
                        text-align: center;
                }
        </style>
</head>

<body>
        <div class="container">
                <h2>ESP8266 Web Update</h2>
                <form method='POST' action='' enctype='multipart/form-data'>
                        <p><small>.binファイルを選択し、「アップデート」ボタンを押してください</small></p>
                        <input type="file" name='update' class="Button">
                        <br><br>
                        <input type='submit' value='アップデート''>
    </form>
  </div>
</body>

</html>
)rawliteral";


static const char successResponse[] PROGMEM =
  R"rawliteral(
<html>

<head>
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
        <meta charset="UTF-8">
        <META http-equiv="refresh" content="15;URL='\'">
        <style>
                body {
                        -webkit-text-size-adjust: 100%;
                        font-family: "游ゴシック Medium", YuGothic, YuGothicM, "Hiragino Kaku Gothic ProN", "Hiragino Kaku Gothic Pro", メイリオ, Meiryo, sans-serif;

                }

                h2 {
                        text-align: center;
                        font-size: 1.75rem;
                        line-height: 1.225;
                        padding-bottom: 0.5em;
                        border-bottom: 2px solid rgb(190, 190, 190);
                }

                .container {
                        margin-top: 1em;
                        text-align: center;
                }
        </style>
</head>

<body>
        <div class="container">
                <h2>ESP8266 Web Update</h2>
                <p>アップデートに成功しました! 再起動しています...</p>
        </div>
</body>

</html>
)rawliteral";

成果物

その結果がこちら。デフォルトの見た目からすれば、だいぶ良くなりましたね!

f:id:at_you_key:20191001205551p:plain
アップロード画面

f:id:at_you_key:20191001205603p:plain
完了画面

では、今日はここまで。素敵なOTAライフを!

f:id:at_you_key:20191002224520p:plain