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 )
/* * 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 }
<!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>
<!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モード切替など勉強中です。