Edited at
ArduinoDay 13

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

More than 3 years have passed since last update.

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