2024年4月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
無料ブログはココログ

« ESP32-WROVER-E PSRAM有効化 | トップページ | MACアドレス登録は許可か制限か »

2023年7月12日 (水)

ESP32 Wi-Fi Lチカのスケッチを読解

30年程前にPICをやったっきりで、Arduinoとかも知らかなった自分が、はやりのIoTをやってみたくてESP32を買い、ネット記事を真似してWi-FiでLチカをやってみました。関連情報も探せばたくさん出てきますし、それこそコピペでできてしまう便利な時代ではありますが、仕組みを知らないと面白くないし、応用もきかないので、自分なりに頑張って読解してみました。

目次

 前置き
 基本的な理解から
 処理全体の流れ
 クライアントとサーバーのやり取り
 リクエストの中身
 リクエストの文字列処理の詳細
 HTMLの生成

 読解を終えて
 おまけ:高速化のあがきと顛末

参照した記事を書いた諸先輩達に感謝。この記事が少しでも誰かの役に立てば幸いかな。

 

前置き

ESP32を買ってから1か月半経ちました。
Wi-Fiを使った初IoTのWi-Fi Lチカですが、下の動画の様にスマホのブラウザ画面のボタンを押して、ESP32に繋いだLEDをOn/Offさせる事が出来ます。初めてだからか、これだけでもなんだか感動するものがありましたね。

スマホでESP32に繋いだLEDをOn/Offさせる様子。

でも実は、スマホでLEDを制御しているブログにあったスケッチ(これ)をコピペしただけで、中身の理解が出来ておらず、実はチンプンカンプン、やったら簡単にできたと言う印象だけの状態で、まともな応用もできないでしょう。

ワンショットリモコンのIoT化もそうでしたが独自のIoT工作やスケッチ作成をするにも、エイヤなカットアンドトライになるので、良くありません。
今後のために、ここで一旦Wi-Fi Lチカのスケッチ1行1行をにらめっこし、分からない事をネットで調べ、先人達の知恵も借りて、各行の処理の役割、全体の制御の流れなど自分なりに読解し、理解を深めたいと考えました。
何でもそうですが、分かっていないと面白くないですしね。

ネットにだいぶ助けて貰いましたが、部分部分を個々に解説した記事や言葉で説明した記事は良く見かけるものの、自分の頭の中で多数の記事の断片を繋ぎ合わせ、全体を把握するのに数日掛かりました。
自分は分かり易く全体が見える様にするのが好きなので、Excelでテキストや図・矢印等を付けて分かり易い資料を作成し本記事にpdfで添付してみました。

                    

上記動画では、ボタンを押してから約2秒でLEDが切り替わるので、もっさりと遅いです。
本記事の最後では応答を高速化したくて少しあがき原因が判明。約0.2秒と大幅に改善(下)。果たしてその原因は?

 

基本的な理解から

Wi-Fiを使ったIoT工作の基本的な理解からですが、Lチカの事例ではESP32側がサーバーで、PCやスマホのブラウザ画面がクライアントになります。(中間のWi-Fiルーターとのやり取り等は省略)

クライアントからはリクエストが送られ、サーバーがレスポンスを返すというやり取りの繰り返しです。
Photo_20230712165401_20230806090501


ESP32側のWi-Fiルーター接続時のIPアドレスを、クライアント側ブラウザに入力する事で初めて、クライアントとサーバーが接続し、クライアントからリクエストが送られ、サーバーからレスポンスとしてブラウザ画面用のHTMLを返す事で、クライアントのブラウザ画面が構成されます。

以下、Wi-Fi Lチカでクライアントがサーバーに接続した直後のブラウザ画面です。
サーバー側からのレスポンスとして受信したHTMLでブラウザ画面の各パーツが配置されます。
予めボタンにはLEDをOn/Offするためのリンク先を、HTMLの<a href=リンク先>~ボタン配置~</a>の形式で付けてあります。
1_20230713205601_20230806090501

画面のボタンをクリックすると、ボタンに貼られているLEDのOn/Offのためのリンク先へのリクエストがサーバーに送信され、サーバー側でリクエストの文字列から"GET /26/on"等を見付け、必要なGPIOを操作し、次の操作のためのブラウザ画面の更新用のHTMLデータをクライアントへ送信し、接続を解除します。

その後の動作は、ブラウザのボタンを押すたびに、ボタンのリンク先へのリクエストが送られ、サーバーで必要な処理をしてレスポンスを返すという繰り返しですね。

 

処理全体の流れ

簡単には、ざっとこんな感じですが、中身は細かい処理が並んでいて結構複雑ですね。
リクエストの中身を知らないと、サーバー側での必要な処理の仕方が分かりませんし、どう言う構成でレスポンスを返すかも知っておく必要があります。HTTPプロトコルと言うらしいですけどね。
特にサーバー側でのリクエストの中身の文字列を、どんな方法で判別しているかを理解する事が重要に思います。

とは言え、まずは全体の流れを追い、大まかでも良いので全体を理解するのが良い気がします。
と言う事で、先ずは全体の大まかな流れを書いてみました。

大雑把には、初期化・Wi-Fi接続を終えたら、クライアントからのリクエストを待ちます。
リクエストが来たら、リクエストの受信完了後に、GETコマンドに従った処理と、レスポンス送信(HTMLも更新)をして、再度リクエスト待ちを繰り返すって感じですね。
Photo_20231225161701
注意:シリアルモニタへのメッセージ送信とか、レスポンス送信後のクライアントとのWi-Fi接続の切り離し処理とか、タイムアウト処理とかは先ずは考えないで書いています。

前項で書いたように、リクエストで大事な所は”GET /リンク先"です。
最初にIPアドレスだけでアクセスすると、”GET /"だけがクライアントから送られますが、/以降のリンク先(26/onとか)が無いので、LED点灯の操作は実施されず、ブラウザ画面を構成するためのHTMLをクライアントへ送信するだけです。
それ以降は、ブラウザ画面のボタンを押す事で、"GET /26/on"とかのリクエストが送られ、GPIO26のLEDを点灯させる操作が実施され、その状態にブラウザ画面も更新されます。

この大まかな流れを、細かい処理で実現しますが、細かい処理では良く分からない部分が残ってしまうでしょうから、後で詳細を追えば良いと思います。

と言う事で細かい処理の全体像として、スケッチ1行1行を読解し説明を加えてみた図です。クリックでpdfが開きます。
先人達のWi-Fi Lチカの解説ブログやHTTPプロトコルのネット情報など、書き加えて全体が見える様に書いてみました。
Photo_20230805165601_20230806090601

左側がESP32側がWi-Fiルーターに接続するまでの部分で、ESP32の電源OnでWi-Fiに繋ぐまで1回だけ実行されます。
右側がクライアントと接続し、ブラウザのボタン操作でLEDの点灯/非点灯をする部分で、クライアントとの接続と切り離しを繰り返します。

クライアント側ブラウザ画面のボタンが押されるとサーバーと接続し、ボタンのリンク先を含むGETリクエストがクライアントがサーバーに送信されるので、サーバー側ではリクエスト文字列を1字づつ受信しながら、行末判定と行末処理を全行繰り返し、最後のリクエスト受信終了の判定の後、レスポンス送信・リンク先文字列により必要なGPIO操作・更新用HTML送信を行い、接続を切り離し、次の接続を待つと言う流れです。

自分もそうでしたが初めてだと、しばらく頭をもやもやさせて脳内の情報整理と定着が必要でしょうし、ネット検索でヒント探しを繰り返すとか、必要な気がします。コツは何度も繰り返して考えながら見る事かな。

 

クライアントとサーバーのやり取り

クライアントとサーバーのやり取りの、たぶん通例的な形式であろう部分が、予備知識ほぼゼロの自分にはとっても分かりにくいと感じたので、少し補足です。

クライアントからのリクエストはGETメソッドを使っていて、リクエスト内のリンク先を示すURI文字列は、ブラウザのURL欄にも表示される様です。以下、少し順を追って実際の画面例を見ながら説明してみます。

ブラウザでURLに192.168.1.8を入力し、クライアントと最初に接続した場合のリクエストには、ボタンからのリンク等何もないので、サーバー側の"GET /26/on"等の検索にヒットすることなく、初期値のoutput26State = "off"、output27State = "off" のまま、サーバーからHTML構成のレスポンス送信が行われ、下記の画面が表示されます。
注意:このスケッチ例では、ブラウザ画面のボタンの文字や色は押した後の状態を示す様になっています。

接続直後のクライアントのブラウザ画面。URL欄は"192.168.1.8"だけです。
1_20230713205601_20230806090501

この状態で、GPIO26の ON ボタンを押すと、URL欄は192.168.1.8/26/on になり、GET /26/on リクエストがサーバーに送られ、サーバー側でGET /26/onの検索がヒットし、GPIO26出力がHIGHになり、HTML生成を含むレスポンスにより、GPIO 26 - State on で  OFF  にブラウザ画面が変わります(下図)。
GPIO26の ON ボタンを押した後の画面。URL欄は"192.168.1.8/26/on"に変わっています。
2_20230713205701_20230806090801

更に、GPIO26の OFF ボタンを押すと、URL欄は192.168.1.8/26/off に変わり、GET /26/off リクエストがサーバーに送られ、サーバー側でGET /26/offの検索がヒットし、GPIO26出力がLOWになり、HTML生成を含むレスポンスにより、GPIO 26 - State off で  ON  にブラウザ画面が変わります(下図)。
GPIO26の OFF ボタンを押した後の画面。URL欄は"192.168.1.8/26/off"に変わっています。
3_20230713210101_20230806090901

注意:上記画面はPCでの画面ですが、スマホ(iPhoneのSafari)では画面が小さいためかドメイン表示しかせず、URL欄に/26/on等の文字は一見表示されませんが、URL欄を選択すれば表示されました。

で、ここで肝心なのは、上記URL欄にも表示される、GETリクエストの1行目にあるリンク部分です。
その文字列によって、GPIO操作の判別を行えば良い事になります。
下記は、最初の全体像のpdfの一部拡大です。
Photo_20230805171801_20230806091001

最初だけ取り出したのが、以下の記述です。

// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
    Serial.println("GPIO 26 on");
    output26State = "on";
    digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
...

リクエスト文字列は文字列変数headerに入っているので、"GET /26/on"の文字を検索し、ヒットすればGPIO26をonにするため、digitalWrite(output26, HIGH);を実行しています。

これで、リクエスト文字列から、GPIO操作に必要な情報を得る方法が分かりました。
HTML書式に則り、ボタンのリンク先の部分へGPIO操作のキーワードを埋め込んでおき、ボタンが押されたら指定されたGPIO操作を行う感じで、なかなか上手い方法と思います。

尚、上記では文字列変数output26stateに現在の状態として"on"を代入しています。
この変数は更新用HTMLの生成で、現在の状態に応じてボタンの色や文字とGPIOの状態表示を変えるためです。

 

 URL欄GPIOコマンド操作 

この方法では、サーバーとの最初の接続時に、例えば 192.168.1.8/26/on とURL欄に入力すると、接続時点でGPIO26のLEDをOnさせる事も出来ます。
接続とブラウザ画面の立ち上がりを待ってボタンを押す操作をするまでもなく、URL欄だけの情報で操作できる訳で、まさに「GPIOコマンド操作」と言えそうです。
ブラウザ上のボタンが無くても操作できるので、面倒なボタン配置用HTMLのスケッチ記述を後回しにして、GPIO操作のスケッチ記述のデバッグに集中できますし、ブラウザ画面にボタンすらない簡易サーバーで済ませるとか、いろいろと応用できそうです。
ボタンがある方がIoTって感じが強くなりますし、何よりカッコいいですけどね。

PCブラウザのURL欄だけでGPIO操作をしている動画です。ボタンは一切押していません。

やってみたことはありませんが、26/onとか、27/offの文字列は、ESP32側の処理の振り分けのためのキーワードになっているだけなので、26onでも27offでも良いはずです。その場合は、if文での検索文字も合わせる必要があります。
HTMLのリンクの仕組みをそのままESP32側での処理の振り分けに利用した方法と言えます。

 

リクエストの中身

上記やり取りの背景となるりリクエストの中身の理解も必要です。
具体的に、リクエスト文字列を見た方が早いので、スケッチの一部を変えて、リクエスト文字列をシリアルモニタに送るSerial.write(c);を有効と無効とした各々で、シリアルモニタ画面の差を見てみました。

Serial.write(c);の有効・無効でのシリアルモニタ画面。クリックでpdfが開きます。
Photo_20230806091101

これで、リクエストの中身の構成が分かりました。
シリアルモニタでは改行されるだけで文字として見えないので少し分かりにくいですが、各行末には実際には CR LF (\r\n or ¥r¥n or 0x0d 0x0a ASCII文字)が定型的に付加される様です。

リクエストのフォーマット 参考(*1)の説明を抜粋
Photo_20230715121001_20230806091201

上記の様に行末が\r\nとなる複数行と、最後の\r\nだけの空行で、GETリクエストをクライアントが送ってくるので、この特徴を使ってサーバー側の処理をする事になります。
Wi-Fi Lチカのスケッチでは、参考(*2)での説明(下)が分かり易いです。

HTTPでは「\n」と「\r\n」のどちらにも対応することを定めています。
しかし「\r\n\r\n」だと煩雑になるので、読み取った文字が「\r」の場合はcurrentLineに追加しないことで、「\r」の排除を行っています。
currentLineの長さが0になるのは「\n」を読み取った後です。
その後に他の文字を読み取ればcurrentLineの長さは1以上になります。

「\n」を読み取った直後にまた「\n」を読み取った場合、currentLineの長さが0の状態で「\n」を読み取ったということは、HTTPリクエストの区切りの空白行なので、これでリクエストが完了したとみなし、HTTPレスポンスの送信を開始しています。

 

リクエストの文字列処理の詳細

リクエストの文字列は把握できましたが、今度はサーバー側での具体的な処理のアルゴリズムをどうしているのか、具体的に知っておく必要がありそうです。
サーバー側でのリクエストの1文字処理を行う部分は結構長い記述ですので、元のスケッチのまま処理を追っていては、目が上下に行き来してしまうし、頭もこんがらがってしまいます。
途中をはしょって、受信するリクエストも4行と簡略化して、スケッチに従って1文字ずつ単純に処理するCPUの身になり、処理の流れを追ってみました。

以下、リクエストの処理の読解図です。クリックでpdfが開きます。
Photo_20230806091301

上記では矢印が多すぎてかえって分かりにくいかもしれませんが、大事な所は\nを受信した際の処理です。
\n受信で、行末判定とリクエスト受信終了判定が行われます。

\n受信での行末判定は、受信した行の\rの直前までの文字列がcurrentLineに入っているので、\n受信時かつcurrentLine.length()==0が成り立たない事で行の終わりと判断され、currentLine=""でクリアするだけで次の行の文字受信に移行します。

\n受信でのリクエスト受信終了判定は、リクエストの最後は\r\nだけの空行の受信となるので、一つ前の行末処理でcurrentLine=””のまま、\r\nの受信に入る事になり、\n受信時かつcurrentLine.length()==0が成立する事でリクエストの終了と判断し、レスポンス送信・GPIO操作・更新用HTML送信に移行します。

尚、受信した文字はそのまま文字列変数headerにため込んでいきますし、1行毎の可読文字(\r\n以外)は文字列変数currentLineへ取り込みます。文字列変数headerはGPIO操作にも使われますが、文字列変数currentLineは行末判定とリクエスト受信終了判定に使われるだけですね。

以上、ざっとした説明ですが、スケッチ1行1行の処理内容・流れが追えたので、やっと全貌が把握できた気がします。
やれやれでした。

スケッチで最初にインクルードされる WiFi.h に定義されているライブラリの説明が、以下参考(*3)にありました。
元のスケッチ内のコメントと綴りでだいたいの意味は分かりますが、一度きちんと見ておいた方が良いと思われます。

WiFiServer begin() WiFiサーバを開始
available() WiFiクライアントからの接続を取得
WiFiClient connected() ホストとの接続状態を返却
available() ストリームで利用可能なバイト数を取得
read() 受信したデータを1バイト読む
stop() ホストとのTCP接続を切断

ESP32をサーバー側として、クライアントPC・スマホとやり取りするのですが、ESP32側のスケッチ内にあるread()がWiFiClient側にあって、WiFiServer側にないのかとか、良く分からない部分もあるので、知っておくべきタイミングで調べる必要がありそうです。
この辺まで来ると、本当に詳細を知るのが必要な時に調べれば良いと思います。

 

HTMLの生成

上記まででほぼWi-Fi Lチカのスケッチの重要な部分は読解できました。
あと残りはサーバー側のレスポンスで更新用HTMLをクライアントへ送る部分で、HTMLとして一般的な文字列表示、ボタン配置、リンクの埋め込み、CSSでの見え方指定などで、本Wi-Fi Lチカの例もそうですが、比較的簡易なブラウザ画面構成を生成する部分と思います。

スケッチでは、client.println(”HTMLの各行”)を多数並べHTML各行を順にクライアント側に送信する形になります。
以下は、実際のスケッチのclient.println(”HTMLの各行”)の”HTMLの各行”部分だけを取り出し、そのままブラウザで見れる様に少し加工したHTMLファイルを作成し、PCで見たものです。
ブラウザの右クリックで「ページのソース表示」を選択すればHTMLテキストが見れます(Edgeの場合)。
Photo_20230809134601
注意:このブログにHTMLファイルを置いたので、ボタンを押しても/26/on等のLink先が無く、ココログ サーバーは「ページが見つかりません」とエラーを返します。
この時ブラウザのURL欄を見ると、末尾に/26/on等のリンク先が付加されているのが分かります。


下が上記のテキストで、<html><head><body>の順の一般的な構成です。
赤字の部分は実際にはESP32側のスケッチで処理する部分になります。

<!DOCTYPE html>
<html>

   <head>
      <meta name="viewport" content="width=device-width, initial-scale=1">
     <link rel="icon" href="data:,">

     <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
         .button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;
                       text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
         .button2 {background-color: #555555;}
      </style>
   </head>

   <body>
      <h1>ESP32 Web Server</h1>
      <!-- 以下GPIO26の現在の状態表示は、実際はoutput26State変数を表示させている-->
      <p>GPIO 26 - State output26State変数の中身</p>

      <!-- 以下はif文でoutput26Stateの内容によりどちらか選択して表示させている-->
      <p><a href="/26/on"><button class="button">O N</button></a></p>
      <p><a href="/26/off"><button class="button button2">OFF</button></a></p>

      <!-- 以下GPIO27の現在の状態表示は、実際はoutput27State変数を表示させている-->
      <p>GPIO 27 - State output27State変数の中身</p>

      <!-- 以下はif文でoutput27Stateの内容によりどちらか選択して表示させている-->
      <p><a href="/27/on"><button class="button">O N</button></a></p>
      <p><a href="/27/off"><button class="button button2">OFF</button></a></p>

   </body>

</html>

現在の状態表示の赤字部分は、実際にはESP32側スケッチでは以下の記述で、現在の状態を保持している文字列変数output26Stateの中身の"on"か"off"の文字列を表示させています。
client.println("<p>GPIO 26 - State " + output26State + "</p>");

ボタンの文字と背景色の赤字部分も、実際にはESP32側スケッチでは以下の記述で、リンク先・ボタンのクラス・ボタンの文字を、output26Stateが"off"か否かで、どちらかを選択しています。
// If the output26State is off, it displays the ON button
if (output26State=="off") {
    client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
    client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}

GPIO27の方も同様です。

IoT工作では、ブラウザ画面のボタンの色や表示内容を変えたり、ハードウェアの状態表示や、センサーから得た数値の表示を行う程度で、そんなに複雑なブラウザ画面にはならないと思いますし、HTMLの文法・構成等は一般的な内容です。
今回のWi-Fi Lチカのスケッチ読解の趣旨目的から少し外れるので、ざっとした説明に留めます。
もっと複雑な画面構成が必要な場合は、HTMLエディタ等でひな形を作成し、1行ずつclient.println()内に記述してクライアントへ送るか、文字列変数htmlbodyへ htmlbody += HTMLの各行毎記述; を繰り返し、文字列全体を作り一気に送るとかで、対応できると思われます。

 

読解を終えて

やっとほぼ読解できたと思います。
クライアントサーバー間のリクエストとレスポンスの形式、リクエスト文字列からのサーバー側処理内容の検出方法、HTMLのheaderやbodyの書式、など理解しESP32言語で必要な処理を記述すると言う、IoTならではの知識が必須なのを痛感しました。

今回読解したWi-Fi Lチカのスケッチですが、かなり理解が少し進みました。

ブラウザ画面にボタンを数個並べてクリックする事で、ESP32側でGPIOの操作等をするのが、IoT工作の第一歩でしょうし、そんなの常識、当たり前って言われる気もします。
が私にとってはES32を入手した約1か月前までは何にも知らなかった訳ですので、今回の読解でIoT工作の階段を一段登れたって感じでいます。

でも、まだまだ知らない事だらけでしょうから、今後も分からない事は、ネットの情報検索で先人達の知識や情報を借りながら、更に理解を深めながらIoT工作等をしていきたいと思います。

 

おまけ:高速化のあがきと顛末

実はこのWi-Fi Lチカは、ブラウザのボタンを押してから、体感で2秒程しないとLEDが変わらないもっさり感があります。最初の動画です。
スケッチの読解により、GETリクエストの1行目だけでやりたい事はできるので、残りの文字列全部の1文字づつの処理は時間の無駄に思えます。
最初の1行目の最後の改行を受信し終えたら、GPIO操作やブラウザ画面更新に移行してしまえば、応答が早くなるとは思いますが、リクエストの受信途上でサーバー側の処理を始めてしまうと、それはそれで、リクエスト・レスポンスのやり取りの同期が取れなくなり、見えないライブラリの内部処理とかで不都合が発生する気もします。
特に最初にクライアントと繋がった際は、一旦全部リクエストを受け取らないといけない気もしますが、今回のスケッチがクライアント-サーバーのやり取りの全てであるならば、今回のスケッチではリクエストの最初の1行目でしか意味ある処理はしていません。
ならば、無知な私に考えつくのは、1行目の\r\nを受信したら、レスポンス送信・GPIO操作・更新用HTML送信動作へ直ぐに移行させ、接続を切ってしまうスケッチにしたら、高速化できるのか? 不都合は生じるのか? 見えない内部処理からのエラーに見舞われるのか? など試してみたい気がします。ESP32だと手軽に試せますしね。
今のスケッチでも、接続時間が2秒をこえるとタイムアウトが働き、Whileループを抜け、client.stop(); で強制的に接続を切っているくらいですし、大丈夫な感じもします。

-----------------------------------------------------
2023-7-17 上記やってみましたが、特にエラーとかは発生しないものの、高速な応答にはならず、体感的には余り変わらないかな。
ボタンを押してももっさりLEDが切り替わる状況は変わりませんでした。
ハハハ 我 浅はかなり! まだまだ修行が足りません。

変更してみたスケッチです。
最初に\nを受信したら、currentLine ="" にして、リクエストの最後だと勘違いさせる方法です。

77行目が追加した部分。
Photo_20230717211901_20230806091501

シリアルモニタを見ると、IPアドレス表示後の、リクエストを返す部分には、1行目の GET / HTTP/1.1 や GET /26/on HTTP/1.1 等しか表示されないので、2行目以降のリクエスト文字列は見ていません。やった事は正しそうです。
Serial_20230717212201_20230806091501

比較のための元のスケッチでのシリアルモニタ画面です。2行目以降のリクエスト文字列も表示されています。
Motonoserial_20230806091601

-----------------------------------------------------
2023-7-18追記
参照したwak-techさんの記事にあった動画では、ボタンを押してからLEDが変わるまでの応答が早いです。
【ESP32】Wi-Fi経由でスマホからLチカ - YouTube
スケッチはタイムアウト処理がないくらいですが、コピペして実行しましたが、全く早くなりません。
それどころか、スマホのブラウザ画面では通信データ待ちのクルクルが回る状態になったりします。
しばらくしてから実行すると反応が早くなっていたりと、安定しません。
どうも、自宅のWi-Fi通信環境の問題な気がしてきました。
これとは別に、Freenove社へ質問しているので、回答来たらUpdate予定です。
今となっては、MACアドレスフィルターリングを止めてみろとか、Wi-Fi通信環境を調べるべきとの回答が期待かな。
-----------------------------------------------------
2023-7-20追記
Freenove社への質問は、「最初に\nを受信したら、currentLine ="" にして、リクエストの最後だと勘違いさせる方法」でも早くならないので、簡単で一般的な高速化のアイデアとかを問いかけたものです。
回答としては、「You can refer to chapter 30 of our esp8266 kit.」(esp8266 kitのChapter 30 を参照できるよ)だけで、以下の紹介を受けました。

https://github.com/Freenove/Freenove_Ultimate_Starter_Kit_for_ESP8266/archive/refs/heads/main.zip
 
以前の記事にも書いたのですが、Freenove社の各種キットのドキュメント・スケッチ類はフリーでダウンロード可能で、上記はFNK0073と思います
Photo_20230721090501_20230806091701

DLして出てきたスケッチ sketch_30.1_control_led_through_web.ino を試してみましたが、高速化されませんでした。

この結果は今の認識としては思っていた通りで、スケッチやESP32の処理の問題ではなさそうなので効果はありません。

------------------------------------------------------------------
しかし、このスケッチ、今まで試したWi-Fi Lチカ スケッチ(ブラウザ画面は以下、ボタン2つで、LED 2個をOn/Offのもの)と中身ほぼ同じでした。
1_20230713205601_20230806091701
オリジナルがどれなのか分かりませんが、世界中でほぼ同じスケッチを使ってWi-Fi Lチカのブログ記事やYoutube動画が発信されているんですね。
それだけお手軽で誰でもできるって事でなのでしょう。
------------------------------------------------------------------

別アイデアとして試したのが、MACアドレスフィルターリングの停止です。
停止させると、早い時は0.5秒位でLEDが切り替わり高速化されましたが、不安定で遅いときは2秒くらいかかりました。
やはり自宅のWi-Fi環境が原因の可能性が高そうです。
ははは、今のWi-Fiルーターは約8年前から使っていますが、MACアドレスフィルターリングで10台程度の機器をWi-Fiで繋いでいるので、性能が足りていないのでしょう。
3年程前にNifty光にした際にキャンペーンでもらっていたWi-Fiルーターがあるので、取り替えてみるのが良いかな。

 

  もっさり応答の原因はWi-Fiルーターでした   
2023-7-21追記
今日Wi-Fiルーターを更新しました。高速応答の効果が出ました。
ボタンを押してからLEDが変わるまで体感的には0.2秒程度、応答時間は大幅に短縮されました。
今までの2秒程度のもっさり感はなくなり、指で押して直ぐ反応、ストレスを感じません。
以下、動画です。

動画をWindows10のビデオエディターを使いコマ送りで変化点を追ってみました。
見たのは16秒過ぎ辺りで、ボタンを押した瞬間⇒LEDが点灯した瞬間⇒ブラウザ画面が更新された瞬間の順です。
コマが荒いのですが、ボタンを押してから LED点灯まで0.16秒、画面更新まで0.33秒 なのが分かります。
タイミングによって多少の時間差がありますが、最大でも0.5秒以内に画面更新までされるようになりました。

ボタンを押した瞬間16.50秒 LEDが点灯した瞬間16.66秒 画面が更新された瞬間16.83秒
1_20230726094701 2_20230726094701 3_20230726094701

ちなみに、77行のcurrentLine ="" を有効にしてみましたが、より早くなる感じはなく、ほぼ上記と同じ反応速度でした。
リクエスト全行の処理よりもWi-Fiルーターの応答速度が、もっさり応答の主因で間違いなさそうです。

Wi-Fiルーターの更新でインターネット通信速度も改善しました。
今まで100Mbpsを超える事は無かったのですが、超えるケースが出てきました。
Photo_20230726120301_20230806091901

Wi-Fiルーター起因は全く予想もしていない原因でしたが、更新により内外の速度が早くなり良かったです。
これで、サクサク動くESP32 IoT工作ができそうです。

 

続報あればまた。

 


参考
ESP32を使ってスマホからLチカ(LED点滅)する【webserver】 | Wak-tech
SimpleWiFiServer (fc2.com)
 └client.available()で、読み込み可能なバイト数を取得します。1文字以上読み取りできる場合は、client.read()で1文字読みます。
ESP32入門 通信機能が標準搭載されたマイコン・ボード (4) サンプル・プログラムを用いてWi-Fi経由でLEDのON/OFFを行う(2) - Arduinoクックブック (denshi.club)
・(*1)HTTP リクエストとレスポンスの形式に関する注記 | AppExpert (netscaler.com)
・(*2)ESP-WROOM-32でWebサーバーを作ってHello World!をする - Qiita
HTTPプロトコル (quu.cc)
「HTTPリクエスト」と「HTTPレスポンス」 | ITSakura
・(*3)https://garretlab.web.fc2.com/arduino/esp32/reference/libraries/WiFi/

 

« ESP32-WROVER-E PSRAM有効化 | トップページ | MACアドレス登録は許可か制限か »

電子工作:ESP32」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« ESP32-WROVER-E PSRAM有効化 | トップページ | MACアドレス登録は許可か制限か »