WIFI-TNGとESP-WROOM-02で始めるWIFI Arduino

  • 38
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

さて、Advent Calendarですよ!

めりーくりすまーす!!!

いつもの謎画像

Arduinoも遂に無線の時代に突入!!
そこで、WIFI-TNGだ!というわけで、今回の記事です。

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チカ」です!

遠隔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」を入力して接続します。

APモード

接続後、ブラウザを起動して、192.168.4.1/on/と入力!LEDランプが着いたら成功です〜
192.168.4.1/off/と入力すればLEDが消えます。

雑ですが、あっと言う間にリモート感のあるものが作れました!

WiFi経由でLチカ(STAモード)

さて、APモードもいいのですが、これだとネットに繋がらなくなるのでSTAモードでも使いたいですね。

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にあります。
mDNSサンプルの場所

下記のようにすれば良いみたいです。

#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という名前で作成しています。

スケッチフォルダの下にindex.htmlを置く

次に、Arduino IDEから、Tools>ESP8266 Sketch Data Upload を選択します。

スケッチフォルダの下にindex.htmlを置く

必ず、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認証がないのが多いんですよね。。。

この投稿は Arduino Advent Calendar 201513日目の記事です。