Wi-Fiについての解説

ここではWi-Fiについての簡単な説明と、Wi-FiモジュールであるESP-WROOM-02を使用した応用例を

示し解説します。

   

Wi-Fiとは

Wi-Fiとは無線LANの規格で、この規格により無線LANを使用したデバイス間の相互接続が認められたことを表します。 つまりこのWi-Fiの規格に認定されていれば、全てのWi-Fi機器に接続が可能となります。
Wi-Fiは国際標準規格IEEE802.11規格を使用しており、使用する規格により周波数帯や通信速度が決められています。右側の表に、一般的に使用されている規格の種類と最大通信速度、使用周波数帯を示します。

 

 

Wi-Fiモジュール(ESP-WROOM-02)について

WiFiモジュール、ESP-WROOM-02は、機器への組み込み用に作られたもので、Wi-Fi通信とシリアル通信(RS-232C)を相互に送受信することが可能となっています。
また、モジュールに内蔵されているマイコンにプログラムを書き込むことで、I/Oやシリア通信の制御ができます。
無線を使用するための認証についても、「技術基準適合証明」の認証がされているので、安心して国内で使用する事ができます。

 

 

Wi-FIとして一般に使用されている規格

規格 最大通信速度 使用周波数帯
IEEE802.11a 54Mbps 5GHz
IEEE802.11b 11Mbps 2.4GHz
IEEE802.11g 54Mbps 2.4GHz
IEEE802.11n 600Mbps 2.4GHz/5GHz
IEEE802.11ac 6.9Gbps 5GHz
IEEE802.11ad 6.8Gbps 60GHz
 

 

 Wi-Fiモジュールの基本的な使用例

 

右図では、モータを搭載した模型自動車を、Wi-Fiを使い離れたところからコントロールしています。
図の左側「Wi-Fiモージュール+模型コントローラ」には、模型自動車をコントロールするためのスイッチと、Wi-Fiモジュールが搭載されています。
一方、模型自動車には、模型コントローラからの信号を受信するためのWi-Fiモジュールが搭載されており、模型コントローラから送られてきた「前進」、「停止」などの信号によってコントロールされています。
 Wi-Fiの通信を中心に見ていくと、模型コントローラはWi-Fiステーションとして動作し、模型自動車はWi-Fiアクセスポイントとして動作します。
ステーションとアクセスポイントが一つずつあり、これがWi-Fiで通信するための最低限のシステムになります。


 

 

 Wi-Fiモジュールをアクセスサーバとして使用した例

 

 

右図の上の方に書かれている「Wi-FiモジュールAP」はアクセスポイントサーバであり、 LEDを点灯、消灯したり、温度を測定することができます。

このアクセスポイントはHTTP通信を行っており、右図のステーションであるノートPCやスマートフォン、Wi-Fiモジュールから、 Webブラウザを使用したアクセスやテキストデータなどにより、LEDなどをコントロールすることができます。

例えばスマートフォン・ステーションを例に挙げると、Webブラウザに「ON」「OFF」ボタンなどが表示され、これを押すことでLEDを点灯、消灯させることができます。
スイッチを搭載したWi-Fiモジュール・ステーションであれば、スイッチを押すことでLEDを点灯させる事ができます。

 

 Wi-Fiモジュールをステーションサーバとして使用した例

 

右図Wi-Fiモジュール・ステーションサーバは、LEDを点灯、消灯したり、温度を測定することができます。

この構成の場合、アクセスポイントは図の上の方に描かれている「無線LANルータ」が担います。 このアクセスポイントは既に設置されているものを使用するものとします。

図のスマートフォンから、無線LANルータ・アクセスポイントを経由し、Wi-Fiモジュール・ステーションサーバと スマートフォンのWebブラウザにより通信します。スマートフォンからはWebブラウザにある「LED ON」「LED OFF」などのボタンを押すことにより、Wi-Fiモジュール・ステーションのLEDを点灯、消灯することができます。

また、スマートフォンのブラウザから「温度を表示する」というボタンを用意し、押すことによってWi-Fiモジュール・ステーションの温度データをブラウザに表示することができます。

 

 

 Wi-Fiモジュールをステーションサーバとして使用した例(IFTTTを利用した例)

 

図の左下のWi-Fiステーションサーバを無線LANルータに接続し、スマートフォンから無線LANルータAP経由でWi-FiステーションサーバのWebサイトにアクセスします。そして、インターネットのWebサービスとして IFTTT※1)を使用し、Wi-Fiステーションサーバの温度データをWebサービスのTwitter※2)に書き込みます。
実際の手順としては、最初にスマートフォンのWebブラウザから、Wi-FiステーションサーバのURLにアクセスします。ステーションサーバにアクセスするとブラウザ上に「温度を記録する」ボタンが現れます。
このボタンをクリックすることで温度データが、「IFTTT」の「Maker Channel※3)」のURLに書き込まれます。
IFTTTではMaker ChannelをトリガーにしてTwitterがアクションとなり、URLに書き込まれた温度データをTwitterに書き込みます。
 これでスマートフォンから「温度を記録する」ボタンをクリックする毎に、Twitterに書き込みが行われます。


※1 IFTTT(イフト)
  TwitterやFacebook、InstagramなどのWebサービスを連結させ、
  相互に情報のやり取りを可能にしたWebサービスです。
  簡単に言うとWebサービスの仲介者みたいなものです。
  ここの解説では、温度データをTwitterに書き込むために、
  IFTTTによりMaker Channelをトリガー(きっかけ)にして、
  Twitterにアクション(働きかけ)を行います。


※2 Twitter(ツイッター)
  140文字以内の投稿文を共有するWebサービス。


※3 Maker Channel
  アメリカ発のテクノロジー系DIY工作専門雑誌として誕生した
  コミュニティが、IFTTTに対応して作ったチャンネル。
  IFTTTを介してRaspberry PiやArduinoを簡単につなげられる
  チャンネルです。

 

 

 

 Wi-Fiモジュールをステーションサーバとして使用するプログラム例

 

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(クリックで拡大)