LED 調光を、SPIFFS を使用して HTML を別ファイルにする。
方法:
"ESP32/arduino : SPIFFS アップローダーを使用する "に従って HTML を別ファイルにする。
変数部分(
LEDの明るさ :led_brightness) は、送信前に変数名の文字列を数値に置換して送信する。
2019/06/26追加
XHR を多重で発行すると通信がハングアップする事があるようなので、レスポンスが返るまで発行しない様に修正。
→ 本問題は、
Arduino core for the ESP32 の Ver 1.0.2 の問題と思われる。
Ver.1.0.3 以降では問題無い。
例: (スケッチ、HTML、レスポンス用HTML )
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /* * WiFi LED ON/OFF TEST * PWM Control * slider control2 */ #include <WiFi.h> #include "FS.h" #include <SPIFFS.h> #define DEBUG const char* ssid = "hogehoge"; const char* password = "hogehogepaswd"; IPAddress ip(192, 168, 1, 32); // for fixed IP Address IPAddress gateway(192,168, 1, 1); // IPAddress subnet(255, 255, 255, 0); // IPAddress DNS(192, 168, 1, 90); // WiFiServer server(80); String html_1; String resp_1; byte led_brightness = 0 ; void setup() { Serial.begin(115200); SPIFFS.begin(); //SPIFFSを開始 pinMode(2, OUTPUT); // set the LED pin mode WiFi.config(ip, gateway, subnet, DNS); // Set fixed IP address delay(10); // We start by connecting to a WiFi network ----------------------------- Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.begin(); //index.htmlファイルの読み込み File index1 = SPIFFS.open("/test_pwm_slid.html", "r"); if(!index1) Serial.println("file open failed"); else{ html_1 = index1.readString(); //index.htmlをstringで読み込み index1.close(); //ファイルを閉じる } //resp.htmlファイルの読み込み File index2 = SPIFFS.open("/resp_slid.html", "r"); if(!index2) Serial.println("file open failed"); else{ resp_1 = index2.readString(); //index.htmlをstringで読み込み index2.close(); //ファイルを閉じる } // for LED PWM Control --------------------------------------------------- ledcSetup(0, 5000, 13); // setup channel 0 with frequency 5000 Hz, 13 bit precission for LEDC timer ledcAttachPin(2,0); // attach pin 2 to channel 0 ledcWrite(0, 0); // initialize channel 0 to off } void loop(){ WiFiClient client = server.available(); // listen for incoming clients int pos ; int val ; int xhr ; String cmd = "" ; String htmlwk = "" ; String respwk = "" ; if (client) { // if you get a client, # ifdef DEBUG Serial.println("***** Client access start *****"); // print a message out the serial port #endif xhr = 0 ; while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, String line = client.readStringUntil('\n'); // Get Line data until '\n' # ifdef DEBUG Serial.println(line); #endif if ((pos= line.indexOf("GET /?slid")) != -1) { pos += 11 ; while((line.charAt(pos) >='0') & (line.charAt(pos) <='9')) { cmd += line.charAt(pos++) ; } val = cmd.toInt() ; if (val>256) val = 255 ; led_brightness = (byte)val ; xhr=1; # ifdef DEBUG Serial.print("led_brightness : "); Serial.println(led_brightness) ; #endif } if ((pos= line.indexOf("GET /?led_v")) != -1) { pos += 12 ; while((line.charAt(pos) >='0') & (line.charAt(pos) <='9')) { cmd += line.charAt(pos++) ; } val = cmd.toInt() ; if (val>256) val = 255 ; led_brightness = (byte)val ; # ifdef DEBUG Serial.print("led_brightness : "); Serial.println(led_brightness) ; #endif } if ((pos=line.indexOf("GET /?on")) != -1) { // Client request was "GET /?on" led_brightness += 1 ; # ifdef DEBUG Serial.print("led_brightness : "); Serial.println(led_brightness); #endif } if ((pos=line.indexOf("GET /?off")) != -1) { // Client request was "GET /?off" led_brightness = 0 ; # ifdef DEBUG Serial.print("led_brightness : "); Serial.println(led_brightness); #endif } ledcWrite(0, 8191*led_brightness/255) ; // set PWM value to channel#0 if (line.length() == 1 && line[0] == '\r'){ // end of HTTP request if (xhr == 0) { htmlwk = html_1 ; htmlwk.replace("$led_brightness",String(led_brightness)) ; send_html(client,htmlwk) ; // send response to client } else { respwk = resp_1 ; respwk.replace("$led_brightness",String(led_brightness)) ; send_html(client,respwk) ; // send response to client } break; // break while loop } } } delay(1); // give the web browser time to receive the data // close the connection: client.stop(); # ifdef DEBUG Serial.println("Client Disconnected."); Serial.println("--------------------------------------------------"); #endif } } // ------------------------------------------------------------------ void send_html(WiFiClient client, String html ) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); client.print(html) ; # ifdef DEBUG Serial.println( " --- send html --- "); #endif } |
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'> <style>input.button {margin:8px;width:100px;} input.button2 {margin-left:8px; width:40px;} input.text {margin-left:8px; width:25px;} input.slid {width:230px;} div {font-size:16pt;text-align:center;width:250px;border:solid 4px #93ff93;} </style> <title>Color LED Controller</title></head> <body> <div><p>LED ON/OFF</p> <form method='get' style='text-align:left' > <span style='padding-left:15pt; font-size:8pt ;text-align:left'> LED brightness (0-255)</span> <input class='text' type='text' name='led_v' id='led_v' value=$led_brightness > <input class='button2' type='submit' name='set' value='SET'> </form> <form name='slidform' method='get' style='text-align:left'> <input class='slid' type='range' name='led_s' value=$led_brightness min='80' max='255' step='1' onchange='setval(this.value)' oninput='setval(this.value)' > </form> <form method='get'> <input class='button' type='submit' name='on' value='UP'><input class='button' type='submit' name='off' value='OFF'><br> </form> </div> <script> var xhr_busy = 0 ; function setval(ledval){ if (xhr_busy == 0) { xhr_busy = 1 ; var xhr = new XMLHttpRequest(); xhr.open('get', '?slid='+ledval ); xhr.timeout = 1000 ; xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr.responseType = 'document' ; xhr.onreadystatechange = function() { if( (xhr.readyState == 4) && (xhr.status == 200) ) { document.getElementById('led_v').value = xhr.response.getElementById('output1').innerHTML; xhr_busy = 0 ; } } xhr.ontimeout = function(e) { xhr.abort() ; xhr_busy = 0 ; } xhr.send(); } } </script> </body> </html> |
1 2 3 4 5 | <!DOCTYPE html><html lang='ja'> <head> <title>Color LED Controller</title></head> <html> <body> <output id='output1'>$led_brightness</output> </body> </html> |
以下、変更点の覚書など。
--- < スケッチ > ---
( 行# 8,9 )
SPIFFS を使用するための include。
( 行# 23,24 )
HTML本体,レスポンス用HTML を格納する String 変数。
( 行# 30)
SPIFFS ファイルシステムのマウントを行う。
( 行# 55~62)
HTML本体を読み込み、String 変数に格納。
( 行# 64~71)
レスポンス用HTMLを読み込み、String 変数に格納。
( 行# 85,86 )
変数部分を値に置き換える為の ワーク用 HTML本体,レスポンス用HTML を格納する String 変数。
( 行# 144~146 )
HTML本体を送信する。
フラッシュメモリから読みだした HTML をワーク用の String 変数にコピーした後、変数部分(値を変えたい部分) を値に置き換え、送信する。
( 行# 148~150 )
レスポンス用 HTMLを送信する。
フラッシュメモリから読みだした HTML をワーク用の String 変数にコピーした後、変数部分(値を変えたい部分) を値に置き換え、送信する。
( 行# 168~178 )
HTML送信用関数。
--- < HTML本体 > ---
( 行# 14,19 )
変数部分は、$付きの名前にした。
2019/06/26追加
( 行# 30,33,34,45,50 )XHR 発行中を示すフラグ xhr_busy を準備。
XHR 発行中は '1' にして 多重で発行しない様にする。
--- < レスポンス用HTML > --- ( 行# 4 )
変数部分は、$付きの名前にした。
過去のプログラムは動作確認ができて、内容も順番に確認してきました。
返信削除このプログラムで悩んでます。
アップロードできているはずです。Hard resetting via RTS pin...
thlmのファイル名は、index.htmlとresp.htmlで良いですか?WiFi connected.
+IPaddressの表示は、OK
ブラウザー表示しません。接続エラーのメッセージも無。
F5の更新で
GET /favicon.ico HTTP/1.1
Host: 192.168.0.123
Connection: keep-alive
Pragma: no-cache
のメッセージの表示?
お助けお願いしたいです。よろしくお願いします。
ESP32をもう少し、勉強していきます。
参考にして頂き、ありがとうございます。
削除HTML のファイル名は、test_pwm_slid.html と resp_slid.html になります。
スケッチ本体の 56行目 と 65行目 でファイル名を指定しています。
2つの HTML のファイルは "DATA" ディレクトリ の下に格納します。
ファイル名 もしくは スケッチ本体の記述を変更して 試してください。
よろしくお願いいたします。
早い回答ありがとうございます。返答がいただけるだけでも助かるのに・・・
削除ファイル名の件、確認実行します。
(現在までのプログラムはすべて動いているので大丈夫と思います。)
よく、プログラムを見なければいけませんね!
コメント記載か何かで、思い込んでいました。
「まず、動かして!」「次は理解」の考えではどこかで詰まりますね!
現在、「スマホからIPアドレス等のWiFi設定を行う」を勉強中です。
全てが目からウロコです。
passwordの間違いでなかなか動きませんでしたが、(1,l)お恥ずかしい!
それで現在、何度かの再接続でAPモードに戻るを追加してみようと試行中です。
俺のレベルで行けるかな?
問題がも山の様に有りますが、一つづつ解決していきたいと思ってます。
カベを乗り越えれない場合は。また御指南をお願いしたいです。
私に判る事であれば、答えたいと思います。(と言っても私も素人ですし、すぐには応答出来ない事もあるかと思いますが、、)
削除問題等ありましたら、投稿ください。
温かいコメントありがとうございます。
返信削除よろしくお願いします。
「スマホからIPアドレス等のWiFi設定を行う」には、ほど遠く
「 LED調光_WEBからと外付けのボリュームからを切り替えて調光」
のお勉強中ですが、"GET /?pol"は、何の動作で?
THLMも少しがじった程度で、scripの復習を行おうと思っています。
local 時、定期的にgetval() を実行(109,128行目)し、XHR で GET /?pol を発行して led_brightness (ボリュームの値) を取得します。
削除返信ありがとうございます。
返信削除XHRは、THMLのscriptですね!復習中です。
「接続不具合(Arduino core for the ESP32 Ver 1.0.2)」でHTMLも書き換えました。
ボリュームの習得は100msで割り込み。ローカル判断で演算。割り込み可。でわないですか?
「get/polを発行してVR取得」????凡人には理解できるようにお願いします。
あと、resp_slidのhtmlの勉強中です。が?、
get/?pol の発行が多くてシリアルモニターの更新が早すぎて、
確認が大変でしたのでお聞きした次第です。
質問ばかりですみません。頑張って理解していますが自分の技量では?見捨てないでください。
ボリュームの値の取得は理解されている通り、100mS毎の割込み(Ticker) で取得し、
返信削除演算(0~255 の範囲に変換)し、変数(led_brightness) に保持します。
( Local 時は、ボリュームの値を 一度'0'にした後でないと更新しません )
XHR(XMLHttpRequest)は ブラウザのボリューム値(brightbess value) を更新するために使用します。 (ESP32側からこの値のみを更新することができない為)
ブラウザのボリューム値更新は、
ブラウザ側:
local 時、Javascript で定期的(100mS毎)に getval を実行。
(setInterval(getval,100))
getval は XHR で GET /?pol を発行し、レスポンスを待つ。
ESP32:
GET /?pol 受信により、レスポンス用HTML を使用して led_brightness の値を
返す。
ブラウザ側:
レスポンスで帰ってきた値 (led_brightness) を brightness value (id:o1) に
セットする。
という流れになります。
( Local 時、ブラウザ側から100mS毎に GET /?pol が発行され、ボリューム値を応答する。)
以上で判るでしょうか?
XMLHttpRequest については、いろいろ解説されているサイトがありますので、調べてください。
忙しいと思われる中、くわしわかるように返答を頂いて助かります。
削除出先なので、帰って良く理解します。
鉄道模型をやられる方なのですね。
自分も友達の手伝いをしているときに、この世界にのめり込みました。
初めは、配線の手伝いだけでしたが、順番に制御などを。踏切などから作りだしました。PICで行っていたのが懐かしいです。
ESP32は、PCやモバイルで制御や確認ができるので、PIC環境を離れESP32に移行中です。
周りには、相談出来る人もおらず独学でやっています。
なので、返答を頂けて本当に嬉しくおもっています。
話しがそれますたが、これからもよろしくお願いします。
現在、WiFiモード切替など勉強中です。