ESP-WROOM-02にArduinoでプログラムを書き込む(3)

前回に続き、いよいよプログラミングに入っていきます。

【プログラミング】
早速、ソースプログラムすべてを載せます。
27行目のSSIDと28行目のセキュリティキーは、接続するネットワークのものを入れましょう。

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
extern "C"{
#include "user_interface.h"
}

#define LEDPIN 0

const char INDEX_HTML[] =
"<!DOCTYPE HTML>"
"<html lang=¥"ja¥">"
"<head>"
"<meta charset=¥"UTF-8¥">"
"<title>ESP8266 LED web turn ON-OFF</title>"
"<style></style>"
"</head>"
"<body>"
"<form>"
"<button type=¥"submit¥" name=¥"led¥" value=¥"lighton¥">LED On</button>"
"<button type=¥"submit¥" name=¥"led¥" value=¥"lightoff¥">LED Off</button>"
"</form>"
"</body>"
"</html>";

const char* ssid = "Your SSID";
const char* password = "Your Security Key";

ESP8266WebServer server(80);

/*
* root process for receiving server request successfully
*/
void handleRoot(){
if(server.hasArg("led")){
handleSubmit();
}else{
server.send(200, "text/html", INDEX_HTML);
}
}

void handleSubmit(){
if(!server.hasArg("led")){
return returnFail("BAD ARGS");
}

char temp[400];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;

snprintf(temp, 400, INDEX_HTML, hr, min % 60, sec % 60);

if(server.arg("led") == "lighton"){
digitalWrite(LEDPIN, HIGH);
server.send(200, "text/html", temp);
}else if(server.arg("led") == "lightoff"){
digitalWrite(LEDPIN, LOW);
server.send(200, "text/html", temp);
}else{
returnFail("Bad LED value");
}
}

/*
* Irregular response for server request
*/
void handleNotFound(){
String message = "File Not Found¥n¥n";
message += "URI: ";
message += server.uri();
message += "¥nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "¥nArguments: ";
message += server.args();
message += "¥n";
for(uint8_t i = 0; i < server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "¥n";
}
server.send(404, "text/plain", message);
}

void handleLEDon(){
digitalWrite(LEDPIN, HIGH);
returnOK();
}

void handleLEDoff(){
digitalWrite(LEDPIN, LOW);
returnOK();
}

void returnOK(){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "OK¥r¥n");
}

void returnFail(String msg){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(500, "text/plain", msg + "¥r¥n");
}

void setup() {
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW);

Serial.begin(115200);
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("esp8266")){
Serial.println("MDNS responder started");
}

//Server start up
server.on("/", handleRoot); //on access
server.on("/lighton", handleLEDon);
server.on("/lightoff", handleLEDoff);
server.on("/inline", [](){
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound); //not found event

server.begin();
Serial.println("HTTP server started");
Serial.print("Access to http://esp8266WebForm.local or http://");
Serial.println(WiFi.localIP());
}

void loop() {
//int adc = system_adc_read(); //TOUT(pin 16)
server.handleClient();
}

これを、前回で環境構築したESP-WROOM-02に書き込むことで、WebブラウザからESP-WROOM-02にアクセスし、表示された2種類のボタン(On/Off)からLEDを点灯、あるいは消灯させることができます。
IMG_20170914_142946.jpg

それでは、ソースを上から順に追っていきましょう。
まずは必要なライブラリをインクルードしていきます。

#include <ESP8266WiFi.h>
#include <WiFiClient.h> //クライアント処理
#include <ESP8266WebServer.h> //サーバー処理
#include <ESP8266mDNS.h> //DNS設定(独自のドメイン名でアクセスできるようにする)

続いて、INDEX_HTMLという文字列(char配列)が出てきますが、こちらはESP_WROOM_02に格納されたHTMLファイルで、いわばアクセスするサイトの中身ということになります。

const char INDEX_HTML[] =
"<!DOCTYPE HTML>"
"<html lang=¥"ja¥">"
"<head>"
"<meta charset=¥"UTF-8¥">"
"<title>ESP8266 LED web turn ON-OFF</title>"
"<style></style>"
"</head>"
"<body>"
"<form>"
"<button type=¥"submit¥" name=¥"led¥" value=¥"lighton¥">LED On</button>"
"<button type=¥"submit¥" name=¥"led¥" value=¥"lightoff¥">LED Off</button>"
"</form>"
"</body>"
"</html>";

直下の部分は、接続するWi-FiネットワークのSSIDとパスワード、そしてサーバーのインスタンスを生成します。
今回はSSIDとパスワードは決め打ち、サーバーはポート80番で接続するようにしています。

const char* ssid = "Your SSID";
const char* password = "Your Security Key";

ESP8266WebServer server(80);

この後は、クライアントからのアクセスに対するコールバックメソッドを定義しています。
まず、handleRootは最初にアクセスを受けた際のイベント処理を定義し、アドレスにledというパラメータがあればhandleSubmitを呼び出し、それ以外は格納されているHTMLファイルをそのまま開くという処理になっています。

/*
* root process for receiving server request successfully
*/
void handleRoot(){
if(server.hasArg("led")){
handleSubmit();
}else{
server.send(200, "text/html", INDEX_HTML);
}
}

void handleSubmit(){
if(!server.hasArg("led")){
return returnFail("BAD ARGS");
}

char temp[400];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;

snprintf(temp, 400, INDEX_HTML, hr, min % 60, sec % 60);

if(server.arg("led") == "lighton"){
digitalWrite(LEDPIN, HIGH);
server.send(200, "text/html", temp);
}else if(server.arg("led") == "lightoff"){
digitalWrite(LEDPIN, LOW);
server.send(200, "text/html", temp);
}else{
returnFail("Bad LED value");
}
}

続いて、handleNotFoundはサーバー側、つまりESP-WROOM-02にエラーが発生した場合の処理を定義します。

/*
* Irregular response for server request
*/
void handleNotFound(){
String message = "File Not Found¥n¥n";
message += "URI: ";
message += server.uri();
message += "¥nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "¥nArguments: ";
message += server.args();
message += "¥n";
for(uint8_t i = 0; i < server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "¥n";
}
server.send(404, "text/plain", message);
}

こちらは、ブラウザのボタンを押した際のイベントを定義します。
(文字通り)handleLEDonが点灯、handleLEDoffが消灯の処理となります。

void handleLEDon(){
digitalWrite(LEDPIN, HIGH);
returnOK();
}

void handleLEDoff(){
digitalWrite(LEDPIN, LOW);
returnOK();
}

そして、クライアントへ送るステータスメッセージの内容を定義します。
イベント処理ではないのですが、前述のイベントメソッドの一部で呼び出されます。returnOKがアクセス成功、returnFailがアクセス失敗をクライアントに通知するメソッドです。

void returnOK(){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "OK¥r¥n");
}

void returnFail(String msg){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(500, "text/plain", msg + "¥r¥n");
}

一連の準備が完了したところで、いよいよメイン処理に移ります。
まず、setupメソッドで出力ピン設定、シリアル通信とWi-Fi、そしてサーバーを起動します。
ピン設定は、IO0を出力ピンにするため、0(LEDPIN)をデジタル出力と設定します。
続いて、Wi-Fiおよびシリアル通信ですが、まずWiFi.biginメソッドで接続先のSSIDとパスワードを入れてネットワークへの接続を確立します。Wi-Fiへの接続は、WiFi.status()WL_CONNECTEDになるまで待機しています。
ESP-WROOM-02とのシリアル通信は必須ではないのですが、デバッグ処理に便利なため設定しています。ただ、ESP-WROOM-02の初期設定がボーレート115200bpsとなっているため、プログラム側でも同じ速度に設定します。
最後のサーバー設定は、大まかに(1)コールバック設定、(2)サーバー立ち上げに分かれます。
まず、コールバック設定については、前述のコールバックメソッドを各イベントに合わせて設定します。server.onはクライアントのアクセス時、server.onNotFoundはサーバー内部のエラー発生時の処理を与えます。
必要なコールバック処理を追加したら、server.beginでサーバーとして起動します。

void setup() {
//pin configuration (IO 0 as output)
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW);

//Serial setting
Serial.begin(115200);
//Wi-Fi initialization (input SSID and password to enter)
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());

//start DNS
if(MDNS.begin("esp8266")){
Serial.println("MDNS responder started");
}

//Server start up
server.on("/", handleRoot); //on access
server.on("/lighton", handleLEDon);
server.on("/lightoff", handleLEDoff);
server.on("/inline", [](){
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound); //not found event

server.begin();
Serial.println("HTTP server started");
Serial.print("Access to http://esp8266WebForm.local or http://");
Serial.println(WiFi.localIP());
}

最後のメインループは、常にクライアントからのアクセスを待機するのみです。

void loop() {
server.handleClient();
}


なお、今回使用したモジュール(部品については初回参照)の注意点として、出力に使えるピン番号が0, 2のみのため、プログラムのピン設定も0、あるいは2のどちらかを設定してください。
ちなみに、アナログ出力(PWM)は可能ですが、入力ピンとしてはどちらも一切使えないため、実質このモジュールは出力ピンが2つだけとなっています。

【テスト】
プログラムを書き込んだら、さっそくテストしてみましょう。
手順は以下の通り。
(1)Webブラウザを開く
(2)IPアドレス(あるいはhttp://esp8266WebForm.local)を入力してアクセス
(3)サイトに出てきたボタン(LED On / LED Off)を押す
(4)回路のLEDが点灯/消灯すれば成功


これですべての実装が終わりました。いかがだったでしょうか。
まだまだいろいろと必要な知識も残っていますが、これがIoT電子工作の入門になれば幸いです。
では(・ω・)ノ))

テーマ : 電子工作
ジャンル : 趣味・実用

コメントの投稿

非公開コメント

プロフィール

Reveちゃん

Author:Reveちゃん
コンビでやってます。
夢担当と技術担当がいます。

大学院卒業 → ロボットベンチャー(漆黒)就職 → 1年で退職 → ベトナムで仕事中(今ここ) → メディアアーティスト(未来☆)

リンクフリーです。

最新記事
最新コメント
月別アーカイブ
カテゴリ
アクセス数
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR