前回は、ArduinoからUARTでESP-WROOM-02をコントロールしてWebサーバーを起動させて、ブラウザでのアクセス成功まで。
今回は、更にブラウザからArduinoのLEDを制御してみたいと思います。
まずは、どの様にデータを受け渡しするかを考えます。
手始めに考えてみたのは、アドレスに要素を付加する方法。
簡単に書くと以下の様にアドレスを指定する。
- http://XXX.XXX.XXX.XXX:80/0 // 消灯
- http://XXX.XXX.XXX.XXX:80/1 // 点灯
一方、サーバー側で判断するのは、
+IPD,0,XXX:GET / HTTP/1.1
Host: XXX.XXX.XXX.XXX
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_XX_X) AppleWebKit/XXX.XX (KHTML, like Gecko) Chrome/XX.X.XXXX.XXX Safari/XXX.XX
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: ja,en;q=0.9,und;q=0.8
の赤枠で囲んだ赤太字の箇所。
アドレスの指定によって下記の様に変化する。
- +IPD,0,XXX:GET /0 HTTP/1.1 // 消灯
- +IPD,0,XXX:GET /1 HTTP/1.1 // 点灯
以上から得られるのは、":GET
/"の位置情報を取得して、7文字目の値を参照すれば良いのでは?って事。
で、該当箇所のみスケッチを書いてみる。
if (mySerial.available()) {
String ret = mySerial.readString();
if ( ret.indexOf("IPD") > 0 ) {
int pos = ret.indexOf(":GET /") + 6;
int led = ret.charAt(pos);
~ ここに"led"による条件分岐処理を記述 ~
}
}
変数"led"に格納された値が取得値。
点灯させるためのスケッチも確認しておく。
まぁ、Blinkのスケッチ例のパクリなんだけど。
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // LED(GPIO13)の設定
}
void loop() {
digitalWrite(LED_BUILTIN, led);
}
"LED_BUILTIN"は、Arduinoの各機種でオンボードのLEDに割り当てられているGPIOを指します。
と、まぁ色々考えたものの、点/消灯だけであれば"digitalRead(LED_BUILTIN)"を参照するだけでも問題なさそうなので、前回最後のスクリプトに以下の箇所を追加、修正するだけに留めています。
#include <SoftwareSerial.h>
String ret, ip_add;
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
Serial.begin(9600); // ハードウェアシリアルポートのデータレートを設定する
mySerial.begin(9600); // ソフトウェアシリアルポートのデータレートを設定する
pinMode(LED_BUILTIN, OUTPUT); // LED(GPIO13)の設定
mySerial.write("AT+CIPMUX=1\r\n"); // サーバーを複数接続に設定
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
mySerial.write("AT+CIPSERVERMAXCONN=1\r\n"); // 複数接続の最大数を設定
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
mySerial.write("AT+CIPSERVER=1,80\r\n"); // サーバを起動
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
mySerial.write("AT+CIFSR\r\n"); // ESP-WROOM-02のIPアドレス取得
ret = mySerial.readString();
int first = ret.indexOf('"')+1;
int last = ret.indexOf('"', first+1);
ip_add = "http://"+ret.substring(first, last)+":80";
Serial.println(ip_add);
}
void loop() {
if (mySerial.available()) {
ret = mySerial.readString();
if ( ret.indexOf("IPD") > 0 ) {
String btn = "ON";
boolean led = !digitalRead(LED_BUILTIN);
digitalWrite(LED_BUILTIN, led);
if ( led ) {
btn = "OFF";
}
String html_code = "<button type=\"button\" ";
html_code += "onClick=\"location.href=\'";
html_code += ip_add+"\'\"><H1>"+btn+"</H1></button>";
mySerial.write("AT+CIPSEND=0,"); // 指定された長さのデータを送信
mySerial.println(html_code.length());
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
mySerial.println(html_code); // HTML書式のデータを指定
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
mySerial.write("AT+CIPCLOSE=0\r\n"); // 接続を閉じる
ret = mySerial.readString();
ret.replace("\r\n\r\n", "\r\n");
Serial.println(ret);
}
}
}
実行させると、ブラウザには下の様に"ON"ボタンが表示される。
ボタンを押すとArduinoのLEDが点灯し、
ブラウザのボタン表記が"OFF"へと変化する。
この後"OFF"ボタンを押せばLEDは消灯し、ブラウザのボタン表記が"ON"に戻る。
以降は、ボタンを押すたびに点灯、消灯が繰り返される。
以上で、ArduinoからESP-WROOM-02のWiFi機能を使用してみる検証は終了。
例として揚げているスケッチは、Stringを多用しているのでメモリを無駄使いしているし、文字列操作を行うためにString変換も行なっているので処理全般重くなっていると思います。
実際に使用する場合は、その辺りを踏まえて記述しないと使い物にならないでしょう。
あえて80MHzで動かせるESP-WROOM-02を16MhzのArduinoからWiFIの機能だけ使用してみるのも案外勉強になりました。
0 件のコメント:
コメントを投稿