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