前回、Webserver.cppのソースを見つけました。Webのページでユーザーインターフェイスを行う時、下記の関数がとても役に立ちます。
- String argName(int i);
- get request argument name by number
- String arg(int i);
- get request argument value by number
- String arg(String name);
- get request argument value by name
- int args();
- get arguments count
ソースをそのままコピーしました。意味が良く分からないですよね。下のHTMLと合わせて説明します。
<!DOCTYPE html>
<html>
<head>
<title>LED Control</title>
</head>
<body>
<h2>Hello ESP32</h2>
<form method='get'>
<button type='submit' name='submit1' value='1'>Button_1</button>
<button type='submit' name='submit2' value='2'>Button_2</button>
</form></body>
</html>
これはブラウザでは、
この様に表示されます。ここで、”Button_1”を押すと上のHTMLの9行目が実行され、クライアントはサーバにGET方式で、”Button_1”を押したレクエストを出します。この時サーバに文字列、”…/?submit1=1″が送られます。この文字列をクエリと言います。クエリはサーバURLの後に、”?”マークを付けて、名前=値の形式になります。例のHTMLでは、名前=name=”submit1” 値=value=”1”よってクエリは、…/?submit1=1となるのです。
- String argName(int i);
- この関数はクエリの引数で指定された”name”を返します。引数はint型。 1番目が0です。つまりargName(0)とすると、”submit1”が帰って来ます。
- String arg(int i);
- 引数で指定された、”value”を返します。1番目が0です。arg(0)とすると、”1”が帰って来ます。
- int args();
- ”name”と”value”で1つの組み合わせとした場合、クエリに幾つ組み合わせがあるかを返します。
- クエリが、…/?submit1=1 なら 組み合わせは1つですので、1が帰って来ます。
実際にスケッチを書いて確認して見ます。
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char* ssid = "XXXXXX";
const char* password = "YYYYYY";
WebServer server(80);
String index_HD =
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
"<title>LED Control</title>\n"
"</head>\n"
"<body>\n"
"<h2>Hello ESP32</h2>\n"
"<form method='get'>\n"
"<button type='submit' name='submit1' value='1'>Button_1</button>\n"
"<button type='submit' name='submit2' value='2'>Button_2</button>\n</form>"
"</body>\n"
"</html>\n";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp32")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handleRoot() {
Serial.print("argName(0)=");
Serial.println(server.argName(0));
Serial.print("arg(0)=");
Serial.println(server.arg(0));
Serial.print("args()=");
Serial.println(server.args());
server.send(200, "text/html", index_HD);
}
- 10から22行:URLの定義
- 58から59行:シリアルモニタにargName(0)を表示
- 61から62行:シリアルモニタにarg(0)を表示
- 64から65行:シリアルモニタにargs()を表示
コンパイル後、シリアルモニタを上げてから実行して下さい。ブラウザに表示された、”Button_1″を押すとシリアルモニタに
と表示されます。Get方式の場合、サーバへのリクエスト文字列(クエリ)がブラウザのURL入力画面に表示されます。
これで何のボタンが押されたかサーバ側で認識出来ます。ちなみに、”Button_2″を押すと下記の様にちゃんと認識出来ています。
次は、”name”と”value”の組み合わせが多数有る場合、つまり入力が複数ある場合です。
<!DOCTYPE html> <html>
<head>
<title>LED Control</title>
</head>
<body>
<h2>Hello ESP32</h2>
<form method='get'>
<p>para_01:<br>
<input type='text' name='pr01'></p>
<p>para 02:<br>
<input type='text' name='pr02'></p>
<p>para 03:<br>
<input type='text' name='pr03'></p>
<p><input type='submit' value='OK'></p>
</form>
</body>
</html>
入力の欄が3つ有り、”OK”ボタンを押すとサーバに送信されるHTMLです。前回のスケッチで、String index_HD = の部分を
String index_HD =
"<!DOCTYPE html> <html>\n"
"<head>\n"
"<title>LED Control</title>\n"
"</head>\n"
"<body>\n"
"<h2>Hello ESP32</h2>\n"
"<form method='get'>\n"
"<p>para_01:<br>\n"
"<input type='text' name='pr01'></p>\n"
"<p>para 02:<br>\n"
"<input type='text' name='pr02'></p>\n"
"<p>para 03:<br>\n"
"<input type='text' name='pr03'></p>\n"
"<p><input type='submit' value='OK'></p>\n</form>\n"
"</body>\n</html>\n";
に変更して、同じ様に実行して下さい。ブラウザの画面
入力欄、para_01, para_02, para_03に値を入れて、”OK”ボタンを押して下さい。
これは、para_01に”a”, para_02に”b”, para_03に”c”といれた場合です。URL入力欄に、”http://esp32.local/?pr01=a&pr02=b&pr03=c”と表示されています。この様に、”name”と”value”の組み合わせが多数有る場合、入力が多数有る場合は、それぞれの組を&で繋いだ文字列になります。モニターには
と表示されます。一番目の、”name”は”pr01″。その”value”は”a”。”name”と”value”の組み合わせは3個。その通りです。
最後に簡単な計算機
このスケッチを、”OK”ボタンを押すと、para_01 と para_02に入力した数字を足して、para_03に表示する様に変更します。
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char* ssid = "XXXXXX";
const char* password = "YYYYYY";
WebServer server(80);
String index_HD =
"<!DOCTYPE html> <html>\n"
"<head>\n"
"<title>LED Control</title>\n"
"</head>\n"
"<body>\n"
"<h2>Hello ESP32</h2>\n"
"<form method='get'>\n"
"<p>para_01:<br>\n"
"<input type='text' name='pr01'></p>\n"
"<p>para 02:<br>\n"
"<input type='text' name='pr02'></p>\n"
"<p>para 03:<br>\n"
"<input type='text' name='pr03' value='";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp32")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handleRoot() {
String buf;
int a;
buf=server.arg(0);
a=buf.toInt();
buf=server.arg(1);
a += buf.toInt();
buf = index_HD + String(a);
buf +=
" '></p>\n"
"<p><input type='submit' value='OK'></p>\n</form>\n"
"</body>\n</html>\n";
server.send(200, "text/html", buf);
}
- 23行:pr03に値を表示する為、”value”ラベルを追加。value =’で文字列を終了
- 62から65行:arg(0), arg(1)の値の読み込み。これらの型は、”String”で整数に変換してから足し算を行う。
- 67行:頭のHTMLに足し算の結果をStringに型変換して付け足し
- 68行:残りのHTMLを足して、HTMLの完成
- 73行:クライアントに送信
簡単な計算機でした。この様な作業の繰り返しでユーザーとESP32との通信を行います。