Hello Server (Webserver.cpp)

前回、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との通信を行います。