[作業ログ]ESP8266をAP・Webサーバーとして使ってみる

More than 1 year has passed since last update.

・目的

スマフォから外部デバイスとしてESP8266に繋げてコントロールする為の予備実験。

加えて表示するHTMLをSPIFFSにてリソースから取って表示させてみる。

・準備

1.

とりあえず、AP/Webサーバーを立ち上げてスマフォからみれるかどーかをテスト。

以下、書き込むソース。

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

static const char *ssid = "gkgk";
static const char *pwd = "12341234";

ESP8266WebServer server(1234);
IPAddress ip( 192, 168, 128, 21);
IPAddress subnet( 255, 255, 255, 0 );

void handleRoot() {
Serial.println("receive req: /");
server.send(200, "text/html", "<h1>Welcome GKGK</h1>");
}

void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip, ip, subnet);
WiFi.softAP(ssid, pwd);
server.on("/", handleRoot);
server.begin();
Serial.println("ap setup...");
}
void loop() {
server.handleClient();
}

AP

SSID:gkgk

pwd:12341234

WebServer

192.168.128.21:1234/

とした。

ビルドして書き込んで実行。

iphoneでesp8266にwifi接続してみる。

ap_cap.png

繋がった。

chromeで見てみる。

http://192.168.128.21:1234

cap_1.png

Aruduinoのコンソール上でも確認。

cap_2.png

リクエストを受信してシリアルに出力している。

なんという手軽さ。。。

2.

SPIFFSで内部フラッシュ?に書いたリソースを読めるように環境を作る。

[1]

下記のページに飛び、

https://github.com/esp8266/arduino-esp8266fs-plugin

Download the tool archive from releases page

のリンクをクリックし、zipファイルをダウンロードして解凍。

[2]

解凍したものを以下のように置く。

[Aruduinoインストールフォルダ]/Arduino/tools/ESP8266FS/tool/esp8266fs.jar

[3]

IDEが起動しているなら、再起動。

IDEのツールに、「ESP8266 Sketch Data Upload」が出ていればOK。

3.

リソースの準備

[1]

スケッチのフォルダに、dataディレクトリを作成

ap_cap_5.png

[2]

indexページのテンプレートをファイルで用意。

以下ソース。

<html lang="ja">

<head>
<meta charset="utf-8">
<title>GKGK TEST</title>
</head>
<body>
<h1>Welcome...</h1>
<h2>GKGK Test Resource HTML...</h2><br/>
<form name="g_form" method="post" action="/">
<img src="${img}" onclick="forms['g_form'].submit();"/><br/>
<input type="hidden" name="FLAG" value="${flag}" />
<input type="submit" value="${submit_msg}"/>
</form>
</body>
</html>

サブミットボタンもしくは、画像を押したら表示が切り替わる感じ。

[3]

dataフォルダ内に、表示させるリソースを配置。

ap_cap_6.png

表示させるindexページのテンプレートと、そのHTML内に表示する

画像を用意した。

[4]

IDEのツール->ESP8266 Sketch Data Uploadをクリック。

ESP8266への書き込みが始まる。

ap_cap_7.png

4.

Aruduino側の実装。

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>
#include <FS.h>

static const char *ssid = "gkgk";
static const char *pwd = "12341234";

ESP8266WebServer server(1234);
IPAddress ip( 192, 168, 128, 21);
IPAddress subnet( 255, 255, 255, 0 );

String strIndexHtml;
boolean flagGod;

// indexページ
void handleRoot() {

Serial.println("receive req: /");
// Postの場合、パラメータからフラグを設定
if (server.method() == HTTP_POST) {
String s = server.arg("FLAG");
if (s == "1") {
flagGod = true;
} else {
flagGod = false;
}
}
// テンプレートのindexページ文字列をフラグによって設定
String msg = "";
if (!flagGod) {
msg = "チェンジ・ぷらいべーとモード!";
} else {
msg = "チェンジ・ビジネスモード!";
}
String arg1 = "${submit_msg}";
String tmpl = "" + strIndexHtml;
tmpl.replace(arg1, msg);
tmpl.replace("${flag}", flagGod ? "0" : "1");
tmpl.replace("${img}", flagGod ? "/img2.gif" : "/img1.gif");
Serial.println(tmpl);

// クライアントに返す
server.send(200, "text/html", tmpl);

}

// /img1.gifハンドラ
void handleImg1() {
Serial.println("receive req: /img1.gif");
// リソースから読み込んで画像をかえす。
SPIFFS.begin();
File hogeFile = SPIFFS.open("/god_on.gif", "r");
// バイナリのリソースを返すならこんな感じ。
server.streamFile(hogeFile, "image/gif");
hogeFile.close();
}
// /img2.gifハンドラ
void handleImg2() {
Serial.println("receive req: /img2.gif");

// リソースから読み込んで画像をかえす。
SPIFFS.begin();
File hogeFile = SPIFFS.open("/god_off.gif", "r");
// バイナリのリソースを返すならこんな感じ。
server.streamFile(hogeFile, "image/gif");
hogeFile.close();
}

// テキストファイルを読み込み
String loadTextFile(String path) {
String txt = "";
String line = "";
char c;
File hogeFile = SPIFFS.open(path, "r");
strIndexHtml = "";
if (hogeFile) {
Serial.println("file open success...");

while (hogeFile.available()) {
// 1文字読み込み
c = hogeFile.read();
// 改行の場合
if (c == '\n' || c == '\r') {
// 行文字列の長さが1以上の場合
if (line.length() > 0) {
txt = txt + line + "\n";
//Serial.println(line);
}
// 改行文字が来たので行文字列をクリア
line = "";
} else {
// 改行文字でなければ行文字列に読み込んだ1文字を追加
line = line + String(c);
}
}
if (line.length() > 0) {
txt = txt + line;
}

hogeFile.close();
} else {
Serial.println("file open failed...");
}
Serial.println(path + " is loaded...");

return txt;

}

// リソース読み込み
void loadHtmlResource() {

String line = "";
char c;

SPIFFS.begin();
// Dir dir = SPIFFS.openDir("/");
// while (dir.next()) {
// Serial.print(dir.fileName());
// File f = dir.openFile("r");
// Serial.println(String(" ") + f.size());
// }

strIndexHtml = loadTextFile("/index.html");
}

void setup() {
flagGod = false;
Serial.begin(9600);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip, ip, subnet);
WiFi.softAP(ssid, pwd);

// ハンドラ設定
server.on("/", handleRoot);
server.on("/img1.gif", handleImg1);
server.on("/img2.gif", handleImg2);

server.begin();
Serial.println("ap setup...");
loadHtmlResource();
Serial.println(strIndexHtml);
Serial.println("load complete...");
}
void loop() {
server.handleClient();
}

フラグで画像を切り替える感じの処理にしている。

スレッドセーフとかは、とりあえず、無視。。。

処理の切り替えによるアクションをLチカでしても良かったが、

画像のよーなリソースをどう扱うか試してみたかったので、こんな感じにした。

・実行確認

前述のソースをビルドしてESP8266上にロードし、実行。

iphoneで接続して、画面を見る。

pg_1.png

リソースから読み込んだものを表示出来たことを確認。

日本語も何も気にせず出るんだなぁ。。。

で、ビジネスモードにする為、ボタンを押す。

pg_2.png

POSTの処理もうまくいっている。

再度、ボタンを押して元の画面が出るか確認する。

pg_3.png

プライベートモードに無事戻るw

・TODO

スレッドセーフな感じにするのはどーした良いか調べる。

(そもそも、Arduino的にはどーなんだろう。。。)

Basic認証とかできるっぽいので、調べておく。