ESP-WROOM-02を使用し、インターネットが利用できる「Wi-Fiモジュールをステーションサーバとして使うためのプログラム」を
例に上げ解説します。ネットワークは図1のような構成です。
以下の手順でプログラムの開発環境を準備し、プログラムのコンパイル、ボードへの書き込みを行います。
1. Wi-Fiモジュールのハードウェア
プログラムを開発する上で必要なハードウェアについて説明します。
ハードウェアを作製する際に必要なパーツは、Wi-Fiモジュールの他に数点しかないので、
ブレッドボードなどで組み立てても動作します。
図2は実際の配線図です。電源は+3.3V 1A出力のACアダプタでOKです。
シリアル通信でPCのRS232Cコネクタに接続する場合は、信号のレベル変換が必要です。
PCにRS232Cコネクタが無い場合には、RS232CとUSBのコンバータを使用してUSBコネクタに接続してください。
シリアル信号の接続では、注意が必要です。Wi-FiモジュールのRXD信号はPC側のTXD信号に接続し、
Wi-FiモジュールのTXD信号はPC側のRXD信号に接続してください。
ジャンパーポストについては、プログラム実行(Flash Bootモード)時にオープン状態にし、
プログラム書き込み(UARTダウンロードモード)時にジャンパーピンでショートします。
以上でハードウェアの準備が整いました。次に進んでください。
2. Arduino IDEのインストール
ESP-WROOM-02に書き込むプログラムは、ArduinoIDEを使用するため、Arduino開発と同じスタイルで進めることができます。
以下のサイトからダウンロードし、インストールしてください。ArduinoIDEのバージョンは1.6.5を使用してください。
Download
the Arduino Software
図2はArduino IDEを起動した画面です。
3. Arduino IDEのボードマネージャーにESP8266をインストール
ここでは、プログラムを書き込むボードを設定するため設定を行います。 インターネットからGitHubのESP8266ボードデータがあるホームページを開きます。
ページの中ほどにある「Available versions」の項目で、「Stable version」の「Boards
manager link:」に書かれているURLをコピーします。
http://arduino.esp8266.com/stable/package_esp8266com_index.json(ここに書かれたものは最新のURLではありません。
Webページからコピーしてください。)
先ほどインストールしたArduino IDEを起動して、メニューから「ファイル」 -
「環境設定」をクリックし、「Additional Boards Manager URLs:」の右に
コピーしたURLをペーストします。(図3を参照)
次に、メニューから[ツール] - [ボード: "Arduino xxx"] - [Boards
Manager...]をクリックし、一番下の[esp8266 by ESP8266 Community]の
[Install]ボタンをクリックします。このときバージョンは最新のものを選んでください。
するとすぐにダウンロードが開始されます。(図4を参照)
インストールが終わったら、メニューから[ツール] - [ボード: "Arduino xxx"] - [Generic
ESP8266 Module]をクリックし、 ボードの設定を終了します。
4. スケッチの書き込み
ボードの設定が終わりましたら、このWebページにあるプログラムソースリストを全てコピーし、Arduino
IDEのスケッチにペーストします。 次に、スケッチをコンパイルします。メニューから[スケッチ] -
[検証・コンパイル]をクリックします。コンパイル後にエラーがなければ、 スケッチを書き込みます。エラーなどはArduino
IDEの下側のエリアに表示されます。スケッチの書き込みの前に、シリアル通信用のCOMポート番号を設定します。
設定はメニューから[ツール] - [ポート:"COM1"]で選択できます。
COMポートの設定が終わりましたら、メニューから[スケッチ] -
[マイコンボードに書き込む]をクリックし、プログラムを書き込みます。
これで、ターゲットボードにプログラムが書き込まれました。実際に動作させて確認してください。
5. プログラムソースの解説
プログラムを順に解説します。
6~12行目は、定数の設定です。
6、7行目で、既にネットワークやインターネット接続で使用している、 Wi-Fiルータ(無線LANルータ)のSSIDとパスワードを設定します。8~10行目は、IFTTTで使用するMaker
ChannelやIFTTTのトリガーイベント名、
シークレットキーなどを設定します。IFTTTについては、IFTTTのホームページから設定してください。
11行目は、LEDを接続するポートを設定しています。12行目は、LEDの点滅間隔を設定します。ここでは1,000ミリ秒
= 1秒を設定します。
14~19行目は、変数の初期設定です。
22行目でWi-FiモジュールをWebサーバとして使用する設定を行います。
25~52行目は、WebサーバからWebブラウザ(クライアント)に送るHTMLデータの関数です。
ここではWebブラウザに送るHTMLデータを作成し、Webブラウザに送信します。
55~74行目は、クライアント(Webブラウザ)からWebサーバが見つからない時に実行する関数です。
77~116行目は、最初に一度だけ実行する関数です。この中で初期設定などを行っています。
78、79行目で、LEDを接続したポートを出力に設定し、LEDを消灯します。
80行目は、シリアル通信のボーレートを115.2Kbpsに設定します。
81行目で、Wi-Fi通信を開始します。
85~88行目は、APに接続するまで待機します。
90~94行目は、シリアルポートにWi-Fi関係の情報を出力します。
100~102行目は、DNSを使用して、名前からアクセスできるように設定します。使用する名前は「esp8266」す。
104~115行目は、Webブラウザ(クライアント)から、このプログラム(サーバ)に送られてきたレスポンスがあれば
handleRoot関数を実行し、無ければhandleNotFound関数を実行します。その後、HTTP(Web)サーバを開始し、
クライアントからの接続を待ちます。
119~196行目は、繰り返し実行する関数です。この中でLEDの点灯や消灯、IFTTTとのやり取りなどをプログラムします。
120行目は、5,000ミリ秒(5秒)間プログラムを停止します。次の行で、現在の時刻を変数に入れます。
122行目で、Webブラウザ(クライアント)からの接続を、呼び出す処理を行います。
124~156行目は、IFTTTに渡すためのLEDの状態や更新時間を作成し、実際のLEDの状態を変更しています。
160~165行目は、Webブラウザ(クライアント)が接続に来たかどうかチェックし、接続が無ければsetup関数の先頭に戻ります。
167~186行目は、IFTTTに渡すためのURLを組み立て、そのURLをサーバにリクエストとして送信します。
189~195行目は、サーバからの応答をそのままシリアルポートに返します。
以上でプログラムソースの解説を終わります。
IFTTTの設定でツイッターにLEDの状態を書き込む場合、このプログラムでは約5秒に1回書き込むため、
短時間でツイート数が増えてしまいます。ツイート数の増加を抑えたい場合には、
120行目のdelay関数の値を大きくしてください。
ソースリスト
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
// 定数
const char *ssid = "***********"; // 既設WiFiルータのSSID
const char *password = "*************"; // 既設WiFiルータのパスワード
const char* host = "maker.ifttt.com"; // IFTTTのMaker Channel
const char* event = "ESP-WROOM-02"; // IFTTTのトリガーイベント名
const char* secretkey = "**********************"; // IFTTTのシークレットキー
const int led = 13; // LEDをIO13(5番ピン)に設定
const long interval = 1000; // LEDの点滅間隔(ミリ秒)
// 変数
unsigned long previousMillis = 0; // 前回のLED状態の更新時間
int ledS = LOW; // LEDの論理状態
String val1 = "OFF"; // LEDの状態、初期値はOFF(消灯)
String val2 = ""; // 未使用
int val3 = 0; // 未使用
int sec, min, hr; // Webに表示する「Uptime」の時、分、秒
// WiFiモジュールをwebサーバとして使用。ポートは80番
ESP8266WebServer server ( 80 );
// webサーバとしてクライアントに送るHTMLデータ関数
void handleRoot() {
char temp[500];
snprintf ( temp, 500,
"<html>\
<head>\
<title>ESP8266 Demo</title>\
<style>\
body { background-color: #cccccc;\
font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>Hello from ESP8266!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
<form method=\"POST\" action=\"#\">\
LED:<input name=\"test\" type=\"submit\" value=\"ON\">\
<input type=\"submit\" name=\"test\" value=\"OFF\">\
<input type=\"submit\" name=\"test\" value=\"FLASH\">\
</form>\
</body>\
</html>",
hr, min % 60, sec % 60
);
server.send ( 200, "text/html", temp ); // 要求は成功
}
// webサーバが見つからない時に実行する関数
void handleNotFound() {
digitalWrite ( led, 1 );
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += server.method();
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 ); // 見つかりません
digitalWrite ( led, 0 );
}
// 最初に一度だけ実行する関数
void setup ( void ) {
pinMode ( led, OUTPUT ); // LEDを出力に設定
digitalWrite ( led, 0 ); // LED消灯
Serial.begin ( 115200 ); // シリアルのボーレートは115.2Kbps
WiFi.begin ( ssid, password ); // WiFiの使用を開始する
Serial.println ( "" );
// APに接続するまで待つ
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Serial.println ( "" );
Serial.print ( "Connected to " );
Serial.println ( ssid ); // SSIDを表示
Serial.print ( "IP address: " );
Serial.println ( WiFi.localIP() ); // IPアドレスを表示
// マルチキャストDNSを使用して、名前でもアクセスできます。
// ただし、Windows PCでアクセスする場合、AppleのBonjour for Windowsを
// インストールする必要があります。
// 使用する名前は「esp8266」です。
if ( MDNS.begin ( "esp8266" ) ) {
Serial.println ( "MDNS responder started" );
}
server.on ( "/", handleRoot ); // "/"が現れたら、handleRoot関数を実行する
// "/inline"が現れたら、以下の成功レスポンスを送る。
server.on ( "/inline", []() {
// 成功レスポンス、成功 = 200。
server.send ( 200, "text/plain", "this works as well" );
} );
// 見つからなければhandleNotFound関数を実行
server.onNotFound ( handleNotFound );
server.begin(); // HTTP(web)サーバスタート、クライアントからの接続待ち
Serial.println ( "HTTP server started" );
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
}
// 繰り返し実行する関数
void loop ( void ) {
delay(5000); // 5,000ミリ秒(5秒)待つ
unsigned long currentMillis = millis(); // 現在までの経過時間を代入
server.handleClient(); // Webブラウザからの接続を、呼び出す処理を行う
// LEDの状態を代入(LED=ONのような形式)
String ledState = server.argName ( 0 ) + "=" + server.arg ( 0 ) + "\n";
// Webに表示するLEDの状態を、IFTTTの1つ目の引数としてURLに渡す
val1 = server.arg ( 0 );
Serial.println(val1);
// ON: 点灯、OFF: 消灯、FLASH: 点滅
if ( server.arg ( 0 ) == "ON" ) {
digitalWrite ( led, 1 );
} else if ( server.arg ( 0 ) == "OFF" ) {
digitalWrite ( led, 0 );
} else if ( server.arg ( 0 ) == "FLASH" ) {
// LEDの点滅時間を計算
if(currentMillis - previousMillis >= interval) {
// LEDが一番最後に点滅した時間を保存する
previousMillis = currentMillis;
// LEDの状態を切り替える
// LOW: 点灯、HIGH: 消灯
if (ledS == LOW) {
ledS = HIGH;
ledState = "ON";
} else {
ledS = LOW;
ledState = "OFF";
}
digitalWrite(led, ledS); // 実際のLEDポートに、LEDの状態を出力する
}
}
// Webに表示するUptimeを、IFTTTの2つ目の引数としてURLに渡す
sec = millis() / 1000; // 秒
min = sec / 60; // 分
hr = min / 60; // 時
val2 = (String)hr + ":" + (String)(min % 60) + ":" + (String)(sec % 60);
// Webブラウザ(クライアント)とTCP接続を作成するために、
// Wi-Fiクライアントクラスを使用し、チェックします。
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// HTTPリクエストのためのURIを作る
String url = "/trigger/";
url += event;
url += "/with/key/";
url += secretkey;
url += "?value1=";
url += val1;
url += "&value2=";
url += String(val2);
url += "&value3=";
url += String(val3);
Serial.print("Requesting URL: ");
Serial.println(url);
// サーバにリクエストを送信する
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(10);
// サーバからの応答のすべての行を読み、シリアルにそれらを送信する
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection"); // 接続を閉じる
}
|
図1
図2(クリックで拡大)
図3(クリックで拡大)
図4(クリックで拡大)
図5(クリックで拡大)
|