さて、Advent Calendarですよ!
めりーくりすまーす!!!
Arduinoも遂に無線の時代に突入!!
そこで、WIFI-TNGだ!というわけで、今回の記事です。
WIFI-TNGとは?
ESP-WROOM-02(ESP8266EX搭載モジュール)は大人気のモジュールなのですが、外部IOのピン間隔が狭く、変換基板などを使わないと、ブレッドボードやユニバーサル基板で使えません。
さらにArduinoからスケッチの書き込みを行うには、USBシリアル変換モジュールも必要になります。
人気がある割には少しハードルが高いなぁ、というのが正直な感想でした。
そんな時に、作者の@morecat_labさんから頂いたのがWIFI-TNGです。
WIFI-TNGは、@morecat_labさんオリジナルのESP-WROOM-02用基板で、ESP-WROOM-02とFTDI231Xを1枚のボードにコンパクトに収めることで、まるでArduino UNOのような感覚で使うことができるボードが作れます。
WIFI-TNGの一般公開・販売はまだ始まっていないようですが、少しフライングして紹介させてください。
WIFI-TNGの作成
作り方や作るのに必要な部品などについては『ESP8266をArduino環境で使う』by @morecat_labさんを参照しました。
基本は上記サイトの通りに作成しましたが、何点か注意点とか補足とか書いておきます。(おそらく数ヶ月後の自分のためにw)
1. レギュレータ
部品表中のLODについては、AZ1117H-ADJが指定されていますが、可変レギュレータに慣れてなかったこともあり、同じサイズのAZ1086H-3.3に変更しました。
これで抵抗を2つ節約もできます。
2. FT231X
秋月にFT231XSが置いてありますので、これを使いました。
3. コンデンサ
様々なサイズ指定がありますが、無理矢理手持ちの0805サイズのものを付けたら。。。付きましたw
もちろん、推奨はしませんが、何かの参考にでも。
4. チップLED
チップLEDのはんだ付け!これマジで難しいです。
LEDのプラスチックの部分が、あっという間に溶けます。。。
5. ジャンパー
『ESP8266をArduino環境で使う』by @morecat_labさんの記事にあるジャンパー、なかなか難易度が高いのですが、新しいバージョンの基板では問題解消されていて、ジャンパーは不要になっています。
その他
温度調整機能ハンダごてが無いとベタGND側のハンダ付けが難しくて泣けます。
というか、まだ持ってないので泣いています。。。
Arduino IDEから使う準備
次に、Arduino IDEの準備です。
なななななんと!1.6.5以降でないと駄目です。
あと、arduino.orgの1.7.x系もよくわかりません。
arduino LLCの1.6.5を使いました。
既に1.6.6が出てますが、確認できていません。。。
WIFI-TNGにプログラム(スケッチ)を書き込むには、Arduino IDE 1.6.5にesp8266/Arduinoをインストールする必要があります。
もちろん、esp8266/Arduinoで紹介されている手順通りにやれますが、下記記事にめちゃめちゃ詳しく書いてありました!
『技適済み格安高性能Wi-FiモジュールESP8266をArduinoIDEを使ってIoT開発する為の環境準備を10分でやる方法』by azusa9さん
というわけで、ここでは割愛しますw
使ってみる
さっそく始めてみます。
Lチカ
念のため、最初はLチカです。
これは、完全に他のArduinoと同じです。
(UNOとPIN番号がちがうだけ)
# define LED_PIN 4
void setup() {
  pinMode(LED_PIN, OUTPUT);
}
void loop() {
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}
なんだろ、この安心感。というわけで、続き行きます!
WiFi経由でLチカ(APモード)
Lチカだけだと面白くないので、早速WIFIならではの機能を使ってみます。
Arduino Yunとか、Linino Oneとか、全然使ったことのない私にとって無線Arduino初体験です。ドキドキ!
最初は、単純そうなAPモードを試してみます。PCからWIFI-TNGにWIFIで直接繋いで「遠隔Lチカ」です!
実はこれ、ArduinoのFile>Examples>ESP8266Wifi>WiFiAccessPointを少し改造するだけで出来ます。
# include <ESP8266WiFi.h>
# include <WiFiClient.h> 
# include <ESP8266WebServer.h>
const char *ssid = "esp";
const char *password = "12345678";
ESP8266WebServer server(80);
void handleRoot() {
	server.send(200, "text/html", "<h1>You are connected</h1>");
}
void LedOn(){
  server.send(200, "text/html", "<h1>LED is ON</h1>");
  digitalWrite(4,HIGH);
}
void LedOff(){
  server.send(200, "text/html", "<h1>LED is Off</h1>");
  digitalWrite(4,LOW);
}
void setup() {
  pinMode(4,OUTPUT);
	delay(1000);
	Serial.begin(115200);
	Serial.println();
	Serial.print("Configuring access point...");
	WiFi.softAP(ssid, password);
	IPAddress myIP = WiFi.softAPIP();
	Serial.print("AP IP address: ");
	Serial.println(myIP);
	server.on("/", handleRoot);
  server.on("/on/", LedOn);
  server.on("/off/", LedOff);
	server.begin();
	Serial.println("HTTP server started");
}
void loop() {
	server.handleClient();
}
WIFIのSSIDから「esp」と書いてあるのを選んで、パスワードに「12345678」を入力して接続します。
接続後、ブラウザを起動して、192.168.4.1/on/と入力!LEDランプが着いたら成功です〜
192.168.4.1/off/と入力すればLEDが消えます。
雑ですが、あっと言う間にリモート感のあるものが作れました!
WiFi経由でLチカ(STAモード)
さて、APモードもいいのですが、これだとネットに繋がらなくなるのでSTAモードでも使いたいですね。
STAモードの場合、接続するWIFIルータからDHCPでIPが振られるので、IPアドレスだと接続しにくいですね。
そこで、mDNS(マルチキャストDNS)と言う仕組みを使って、ローカルネットワーク内でだけ有効な名前を使ってアクセスできるようにしましょう。
と書くと、超めんどくさそうですが、そこはArduino!さすが!サンプルがあるので簡単です。
今度は、PCと同じWiFiネットワークにWIFI-TNGを繋いで、wifi-tng.localでアクセスできるようにしてみます。
mDNSで名前を有効にする
mDNSのサンプルはArduinoのFile>Examples>ESP8266mDNS>mDNS_Web_Serverにあります。

下記のようにすれば良いみたいです。
# include <ESP8266mDNS.h>
void setup(void){
 :
  if (!MDNS.begin("wifi-tng")) {
    Serial.println("Error setting up MDNS responder!");
    while(1) { 
      delay(1000);
    }
  }
 :
  MDNS.addService("http", "tcp", 80);
}
これだけで良さそうですね。
STAモードで他のAPに接続する
今回はAPモードではないので、STAで他のAPに接続するようにしましょう。
void setup(void){
  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);  // Disable Access Point
  Serial.println("");  
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  :
}
こんな感じで接続できるようになります。
こんな感じになりました。
# include <ESP8266WiFi.h>
# include <ESP8266mDNS.h>
# include <WiFiClient.h>
# include <ESP8266WebServer.h>
const char* ssid = "...";
const char* password = "...";
ESP8266WebServer server(80);
void handleRoot() {
  server.send(200, "text/html", "<h1>You are connected</h1>");
}
void LedOn(){
  server.send(200, "text/html", "<h1>LED is ON</h1>");
  digitalWrite(4,HIGH);
}
void LedOff(){
  server.send(200, "text/html", "<h1>LED is Off</h1>");
  digitalWrite(4,LOW);
}
void setup(void)
{  
  pinMode(4,OUTPUT);
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);  // Disable Access Point
  Serial.println("");  
  
  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("wifi-tng")) {
    Serial.println("Error setting up MDNS responder!");
    while(1) { 
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
  
  server.on("/", handleRoot);
  server.on("/on/", LedOn);
  server.on("/off/", LedOff);
  server.begin();
  Serial.println("HTTP server started");
  MDNS.addService("http", "tcp", 80);
}
void loop(void)
{
  server.handleClient();
}
せっかくなので、Ajaxにしてみる
さきほどの2つで、とりあえずはURL叩けばLEDが点いたり消えたりするようにはなったのですが、Ajaxにしろよ。という感じです。なので、やってみます。
- wifi-tng/ にアクセスしたら、ON/OFFボタンを表示
- ON / OFF ボタン押したらajaxで通知
こんな感じにしてみましょう。
index.htmlを返せるようにする
ボタン表示だけの簡単なHTMLとはいえ、さすがに文字列直で返すのは辛いです。
index.htmlを作って、それを読み込んで返すようにしましょう。
index.htmlファイルを作成する
HTMLはこんな感じで。↓
<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<title>LED Button</title>
<style>
button{
  font-size:48px;
  width:100%;
  height:120px;
}
</style>
</head>
<body>
<script>
function sendOn(){
  send("/on/");
}
function sendOff(){
  send("/off/");
}
function send(url){
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.send();
}
</script>
<button id="on" onClick=sendOn()>LED ON</button>
<button id="off" onClick=sendOff()>LED OFF</button>
</body></html>
これを、index.htmlという名前で保存して、作成するスケッチのフォルダに下記のように(スケッチ名のフォルダ/data/の下に)保存しましょう。
今回、スケッチは、ajaxという名前で作成しています。
次に、Arduino IDEから、Tools>ESP8266 Sketch Data Upload を選択します。
必ず、ajaxスケッチを開いた状態で実施してくださいね!
すると、index.htmlをESP-WROOM-02に転送してくれます。
ファイルシステムを使おう
index.htmlを読み込むには、ファイルシステムを利用します。
# include <FS.h>` // <- これでファイルシステムが利用可能に
:
  #define BUFFER_SIZE 16384  // <- これでもか!というくらいでかいバッファw
  uint8_t buf[BUFFER_SIZE];
  SPIFFS.begin(); // <- ファイルシステム利用開始!
  File htmlFile = SPIFFS.open(path_root, "r"); // 読み込みモードでファイルOpen
  size_t size = htmlFile.size(); // ファイルサイズが取れます
  htmlFile.read(buf,size);		 // バッファにファイルサイズ分読み込みます。
こんな感じでバッファにindex.htmlが読み込まれましたので、あとはserver.send()で返せばOKです。
やっとサーバーっぽくなって来ました。
いえい!
スケッチは下記のようになりました。
# include <Arduino.h>
# include <ESP8266WiFi.h>
# include <WiFiClient.h> 
# include <ESP8266WebServer.h>
# include <ESP8266mDNS.h>
# include <FS.h>
const char* path_root   = "/index.html";
const char* ssid        = "....";
const char* password    = "....";
# define BUFFER_SIZE 16384
uint8_t buf[BUFFER_SIZE];
ESP8266WebServer server(80);
void handleRoot(){
  Serial.println("Access");
  server.send(200, "text/html", (char *)buf);
}
boolean readHTML(){
  File htmlFile = SPIFFS.open(path_root, "r");
  if (!htmlFile) {
    Serial.println("Failed to open index.html");
    return false;
  }
  size_t size = htmlFile.size();
  if(size >= BUFFER_SIZE){
    Serial.print("File Size Error:");
    Serial.println((int)size);
  }else{
    Serial.print("File Size OK:");
    Serial.println((int)size);
  }
  htmlFile.read(buf,size);
  htmlFile.close();
  return true;
}
void LedOn(){
  Serial.println("ON");
  digitalWrite(4,HIGH);
  server.send(200, "text/html","OK");
}
void LedOff(){
  Serial.println("OFF");
  digitalWrite(4,LOW);
  server.send(200, "text/html","OK");
}
void setup() {
  pinMode(4,OUTPUT);
  Serial.begin(115200);
  SPIFFS.begin();
  if(!readHTML()){
    Serial.println("Read HTML error!!");
  }
  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  Serial.println("Connecting to Access Point");
  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("wifi-tng")) {
    Serial.println("MDNS responder started");
  }
  server.on("/", handleRoot);
  server.on("/on/", LedOn);
  server.on("/off/", LedOff);
  server.begin();
  MDNS.addService("http", "tcp", 80);    
}
void loop() {
  server.handleClient();
}
まとめ
ESP-WROOM-02(ESP8266)めちゃめちゃ面白いです!
Arduinoと殆ど同じ使い方で使えて(これはWIFI-TNGとesp8266/Arduinoのお陰)、でもWebサーバーっぽくも使えるのでデバイスのコントローラーUIもホストできたりします。
今回は紹介しませんでしたが、Links2004/arduinoWebSocketsなどを使えば、WebSocketsにも対応できたり!
Webで出来るだけやっちゃう系にはタマりません。。
。。調子に乗って10個も買ってしまった。。。w
しかし、WIFI-TNGみたいなボードが無いと、ちょっと使う元気が無いというか、ヒマがないというか、という私みたいな人、結構多いと思います。
やはり、ArduinoはUSBで直接書き込めるから、これだけ人気が出たのだと思います。
WIFI-TNGのようなボードがもっと出てほしいと本気で思いました!
ESP8266搭載ボード海外は超沢山あるけどTELEC認証がないのが多いんですよね。。。










