これまでの電子工作では、ESPr Developer からWebサーバに、なんらかのセンサデータを送信するものばかりを作ってきました。
今回は逆に、家の外からESPr Developerに、なんらかの指示を与えるようなものを作ってみようと思います。
具体的な処理としては、以下のようなものを考えました。
- Webサーバ上に「btn_state.txt」というテキストファイルを置いておく。
- Webサーバ上に「write_text.php」というPHPプログラムを準備し、スマホからこのプログラムにアクセスすることにとり、「btn_state.txt」の内容を書き換えることができるようにする。
- Webサーバ上に「read_text.php」というPHPプログラムを準備し、ESPr Developerからこのプログラムにアクセスすることにとり、「btn_state.txt」の内容を読むことができるようにする。
- ESPr Developerに、一定の時間毎に「read_text.php」にアクセスするスケッチを準備し、「btn_state.txt」の内容に応じて何らかの処理を行えるようにする。
これにより、家の外から、スマホで「btn_state.txt」の内容を書き換えることにより、家の中にあるESPr Developerに、その内容に応じた処理をさせることができます。
実際には、簡単にするために、以下のようなものを作ることにしました。
- 「btn_state.txt」には、「0」または「1」の1文字だけを格納する。
- 「write_text.php」にはボタンをひとつだけ準備し、ボタンを押すたびに「btn_state.txt」の内容を「0」⇔「1」に書き換える。
- ESPr DeveloperにはLEDを接続する。スケッチでは、一定時間毎に「read_text.php」にアクセスして「btn_state.txt」の内容を読み込み、「1」であればLEDを点灯、「0」なら消灯させる。
「write_text.php」の内容は以下のとおりです。formでボタンを準備し、タップするたびに、色が「灰色」⇔「赤」と切り替わるようにしました。
<?php // ファイル書き込み(ボタンが押された時) if(isset( $_POST['button1'] )) { $f_button1 = $_POST['f_button1']; $fp = fopen("./btn_state.txt", "w"); fwrite($fp, $f_button1); fclose($fp); } // ファイル読み出し $fp = fopen("./btn_state.txt", "r"); $f_button1 = fgetc($fp); fclose($fp); // フォーム作成 if($f_button1==1) { $color = "red"; $f_button1 = 0; } else { $color = "gray"; $f_button1 = 1; } $res = "<form action=\"\" method=\"post\">\n"; $res .= "<input type=\"hidden\" name=\"f_button1\" value=" .$f_button1 .">\n"; $res .= "<button type=\"submit\" name=\"button1\" style=\"background-color:" .$color .";\" class=\"hw\">ESPr Developer 1</button>\n"; $res .= "</form>\n"; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=320" > <title>Control Window</title> <style type="text/css"> <!-- body{ font-family: sans-serif; } .hw { width:280px; height:40px; font-size:1.5em; color:white; border-style:none; } --> </style> </head> <body> <?php echo $res; ?> </body> </html>
「read_text.php」の内容は以下のとおりです。ファイルから最初の1文字を読み出すだけです。
<?php $fp = fopen("./btn_state.txt", "r"); print(fgetc($fp)); fclose($fp); ?>
「btn_state.txt」には「0」という1文字だけを書いておき、全ユーザに対するwrite権を付けておきます。
Webサーバに「study_html」というディレクトリを準備し、これら3つのデータを置きます。
ESPr Developerでは、12番ピンとGNDピンの間に、LEDと330Ωの抵抗を、直列に繋げます。
ESPr Developerのスケッチは以下のとおりです。setup()では、WiFi接続を行います。loop()では、1秒毎にGETで「read_text.php」にアクセス、取ってきた値に基づいてLEDのHIGH、LOWを切り替えます。
#include <ESP8266WiFi.h> const char* ssid = "XXXXXXXX"; const char* password = "XXXXXXXX"; const char* host = "XXXXXXXX"; #define LED1 12 void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.print("Connecting "); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); pinMode(LED1, OUTPUT); digitalWrite(LED1, LOW); } void loop() { delay(1000); WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } client.print(String("GET ") + "/study_html/read_text.php HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n"); unsigned long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000) { Serial.println(">>> Client Timeout !"); client.stop(); return; } } String line; while(client.available()){ line = client.readStringUntil('\r'); } char c = line.charAt(1); Serial.println(c); if(c=='1') { digitalWrite(LED1, HIGH); } else { digitalWrite(LED1, LOW); } }
結果は以下のとおりです。ESPr DeveloperがWiFiにアクセスするのに数秒かかりますので、結構遅れますが、スマホでの操作に基づいて、LEDのON、OFFが切り替わることが確認できました。