四つの選択肢
WiFi シールド
Arduino に接続することで WiFi の機能を拡張できるボードです。公式ページは以下のとおりです。
- Arduino WiFi Shield (旧シールド)
- Arduino WiFi Shield 101 (新シールド)
- Arduino Yún Shield (Arduino Yún の機能を提供するシールド)
Arduino Yún
数ある Arduino シリーズのうち、Yúnはシールドなしで WiFi の機能を有しているのが特徴です。公式ページはこちらです。ただし、価格が他の選択肢と比較すると高めです。
Arduino MKR1000
Yún と同様に WiFi の機能を内蔵した Arduino です。公式ページはこちらです。しかしながら 2016/07/24 現在、日本での販売は開始されていません。
WiFi モジュール
Arduino とは関係のない汎用の WiFi 接続用 IC を利用する方法です。
XBee
WiFi (Wi-Fi, Wifiとも。IEEE 802.11シリーズの総称のようなもの) と同様に、1対1の無線通信を行うための規格に ZigBee (IEEE 802.15) があります。XBee は WiFi ではなく当初 IEEE 802.15.4 に基づいて通信を行うように設計された IC のブランド名です。後に WiFi を用いて通信するタイプの XBee (XBee WiFi) も登場しました。XBee シリーズは Digi International 社によって Arduino とは全く関係なく設計されたものですのでこのままでは Arduino のシールドとして使えません。そこで、Wireless Proto シールドという、Arduino のための XBee アダプタシールドが用意されました。公式ページはこちらです。XBeeWiFi は日本国内で適法に使用できる「認証」がある製品ですので、安心して使用できます。SWITCH SIENCE 社から 4,000 円程度で購入できます。
ESP-WROOM-02 (ESP8266 を内蔵)
ESP8266 は 32 bit Tensilica MCU (マイコン; MicroController Unit) を内蔵した WiFi モジュールです。更に ESP8266 を内蔵して作られたのが ESP-WROOM-02 です。ESP-WROOM-02 は日本での技適も取得済みのため安心して使用できます。SWITCH SIENCE 社から 900 円程度で購入できます。通常の電子工作では以下のピッチ変換されたものを利用します。Amazon でもやはり SWITCH SCIENCE 社から販売されています。
- ESP-WROOM-02ピッチ変換済みモジュール (シンプル版) ← ピンヘッダは付属していません
本ページでは Arduino をインターネット接続することを考えていますので対象外ですが、ESP8266 自体がマイコンを内蔵しているため、Arduino なしで単体でも Arduino 互換機として電子工作に利用できます。そのための商品も販売されています。
- ESP-WROOM-02ピッチ変換済みモジュール (フル版) ← 今回の目的においては不要です
- ESP-WROOM-02開発ボード ← 今回の目的においては不要です
WiFi モジュール ESP-WROOM-02 と Arduino の接続方法
日本国内で安心して使用でき、情報も充実しており、価格も安い ESP-WROOM-02 を使用することにします。
参考資料
- 回路図におけるピンの接続方法
- AT コマンドの公式リファレンス
- Documentation → Getting Started →
ESP8266 AT Instruction Set
およびESP8266 AT Command Examples
- Documentation → Getting Started →
- ESP-WROOM-02 を経由して TCP/IP 通信するためのライブラリ (ライブラリ内部で AT コマンドを実行)
回路図
Arduino シリーズの中でも安価な UNO を利用することにします。2016/07/24 現在の最新版は R3 (Rev3) です。以下のように回路を組みます。ESP-WROOM-02 と Arduino UNO の動作電圧が 3.3v および 5v と異なるため、厳密に作るためには電圧レベルをシフトする必要がありますが、今回のような簡単な回路ではあまり気にせずにそのまま接続しても動きます。シリアル通信の方式の一つである I2C に関するページからも該当箇所を引用します。
Connecting the 5V Arduino directly to a single 3.3V-powered I2C chip usually works, even though it violates official specifications in multiple ways.
http://playground.arduino.cc/Main/I2CBi-directionalLevelShifter
SoftwareSerial を使用
回路図に記載のとおり、以下の構成で接続します。
ESP-WROOM-02/TXD <-> Arduino/2番ピン (SoftwareSerial で RX に設定)
ESP-WROOM-02/RXD <-> Arduino/3番ピン (SoftwareSerial で TX に設定)
公式ページに記載されているように、Arduino には HardwareSerial の 0 番ピン (RX) と 1 番ピン (TX) が備わっています。この HardwareSerial を利用して以下のように接続しても ESP-WROOM-02 と通信できます。
ESP-WROOM-02/TXD <-> Arduino/0番ピン (Hardwareserial RX)
ESP-WROOM-02/RXD <-> Arduino/1番ピン (Hardwareserial TX)
しかしながら、この HardwareSerial は Arduino IDE から Arduino に USB ケーブルを介してシリアル通信でプログラムを書き込むときにも使用されるため、以下の書き込みエラーが発生する原因になります。0 番ピンと 1 番ピンから ESP-WROOM-02 への接続線を外せば書き込みに成功するようになります。
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x68
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x69
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x2d
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x70
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x72
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x65
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x0d
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x68
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x69
開発中に毎回ピンから外すのは手間になるため、以下では SoftwareSerial を使用します。ESP-WROOM-02 の出荷時の設定ではシリアル通信の baudrate が 115200 bps に設定されていますが、SoftwareSerial を UNO で使用した場合は 115200 bps まで設定できるため問題ありません。
HTTP 通信のサンプルコード
ITEADLIB_Arduino_WeeESP8266 は TCP/IP 通信を行う汎用のライブラリですが、シリアル通信用のバッファサイズの既定値が 64 bytes となっている Arduino UNO などについて、そのままでは利用できません。そこで、上述の参考資料をもとに HTTP クライアント用のクラスをライブラリ化してみます。今回は IoT 電子工作に最低限必要な機能を提供するシンプルな設計を目標とします。目的に応じてライブラリの設計を変えてみてください。UNO をサポートしない、SoftwareSerial をサポートしない、電圧レベルシフタの使用を許容する、等によって制約を緩めれば送信だけでなく受信もできるライブラリが作成できます。
- シリアルバッファが 64 バイトの Arduino UNO でも使用可能 (ESP-WROOM-02 経由)
- HTTP GET と POST に対応
- データ受信ではなく「送信」を目的とします。
- メモリが少ない UNO などが存在することを考えると HTTP レスポンスをすべて処理することは現実的ではありません。
- SoftwareSerial にはパリティビットの付与設定が begin で指定できないため、電圧レベルシフタを用意しない今回の回路では、3.3v デバイスの ESP-WROOM-02 からデータを受信するときにデータが壊れやすくなります。
- レスポンスボディを取得する関数は提供せず、ステータスコード取得関数のみ提供します。
- SSL/TLS 通信には非対応
ライブラリのインストール方法について
今回サンプルとして作ったライブラリは zip 形式で github からダウンロードできます。Arduino IDE のメニューから追加してご使用ください。ライブラリ追加方法に関する公式ページはこちらです。
WiFi アクセスポイントに接続するだけのサンプル
ConnectWiFi.ino
#include <HttpClient_ESP8266_AT.h>
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
const byte txPin = 3; // Wire this to Rx Pin of ESP8266
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
void setup() {
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
Serial.begin(9600);
// ESP-WROOM-02 との接続確認を行います。
while(true) {
if(httpClient.statusAT()) {
Serial.println("AT status OK");
break;
}
else {
Serial.println("AT status NOT OK");
}
delay(1000);
}
// SSID と PASSWORD でアクセスポイントに接続します。
while(true) {
if(httpClient.connectAP("SSID", "PASSWORD")) { // <- 書き換えてください。
Serial.println("Successfully connected to an AP");
break;
}
else {
Serial.println("Failed to connected to an AP. retrying...");
}
delay(1000);
}
}
void loop() {
// 本サンプルでは特に通信はせず、WiFi の接続が切れていないかどうかを
// 1 秒毎に確認して結果を出力しつづけます。
if(httpClient.statusWiFi()) {
Serial.println("WiFi status OK");
}
else {
Serial.println("WiFi status NOT OK");
}
delay(1000);
}
HTTP GET リクエストのサンプル
HTTPGET.ino
#include <HttpClient_ESP8266_AT.h>
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
const byte txPin = 3; // Wire this to Rx Pin of ESP8266
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
void setup() {
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
Serial.begin(9600);
// SSID と PASSWORD でアクセスポイントに接続します。
// シリアル接続確認と WiFi 接続確認を行い、設定不備があれば出力します。
while(true) {
if(httpClient.statusAT()) { Serial.println("AT status OK"); break; }
else Serial.println("AT status NOT OK");
delay(1000);
}
while(true) { // 書き換えてください↓
if(httpClient.connectAP("SSID", "PASSWORD")) { Serial.println("Successfully connected to an AP"); break; }
else Serial.println("Failed to connected to an AP. retrying...");
delay(1000);
}
while(true) {
if(httpClient.statusWiFi()) { Serial.println("WiFi status OK"); break; }
else Serial.println("WiFi status NOT OK");
delay(1000);
}
}
void loop() {
// ノイズの影響でリクエストに失敗することがあるため while ループで囲います。
while(true) {
// HTTP GET リクエストを実行します。
httpClient.get("www.example.com", "/");
// レスポンス status code が 0 以上であればリクエスト成功です。
// -1: ノイズ等でシリアル通信ができず、そもそもデータ送信ができなかった。
// 0: データ送信はできたが、受信データがノイズで壊れてしまっていた。
// else (>0): 受信データから正常に HTTP レスポンス status code が得られた。
if(httpClient.responseStatusCode() >= 0) {
// 本ページでは電圧レベルシフタを用意していない想定のため、
// 受信データが壊れている可能性が高く、したがって 200 が 100 になっていたりするため、
// 値には興味をもたず、0 以上の値が得られることが重要であると考えてコーディングします。
Serial.println("SUCCESS");
break; // 成功したので while を抜けます。
}
else {
Serial.println("FAILURE, retrying...");
}
}
// 本サンプルでは 1 秒毎に GET を繰り返します。
delay(1000);
}
HTTP POST リクエストのサンプル
HTTPPOST.ino
#include <HttpClient_ESP8266_AT.h>
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
const byte txPin = 3; // Wire this to Rx Pin of ESP8266
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
void setup() {
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
Serial.begin(9600);
// SSID と PASSWORD でアクセスポイントに接続します。
// シリアル接続確認と WiFi 接続確認を行い、設定不備があれば出力します。
while(true) {
if(httpClient.statusAT()) { Serial.println("AT status OK"); break; }
else Serial.println("AT status NOT OK");
delay(1000);
}
while(true) { // 書き換えてください↓
if(httpClient.connectAP("SSID", "PASSWORD")) { Serial.println("Successfully connected to an AP"); break; }
else Serial.println("Failed to connected to an AP. retrying...");
delay(1000);
}
while(true) {
if(httpClient.statusWiFi()) { Serial.println("WiFi status OK"); break; }
else Serial.println("WiFi status NOT OK");
delay(1000);
}
}
void loop() {
// ノイズの影響でリクエストに失敗することがあるため while ループで囲います。
while(true) {
// HTTP POST リクエストを実行します。
httpClient.post("www.example.com", "/", "name=hoge%27hoge&val=123", "application/x-www-form-urlencoded");
// レスポンス status code が 0 以上であればリクエスト成功です。
// -1: ノイズ等でシリアル通信ができず、そもそもデータ送信ができなかった。
// 0: データ送信はできたが、受信データがノイズで壊れてしまっていた。
// else (>0): 受信データから正常に HTTP レスポンス status code が得られた。
if(httpClient.responseStatusCode() >= 0) {
// 本ページでは電圧レベルシフタを用意していない想定のため、
// 受信データが壊れている可能性が高く、したがって 200 が 100 になっていたりするため、
// 値には興味をもたず、0 以上の値が得られることが重要であると考えてコーディングします。
Serial.println("SUCCESS");
break; // 成功したので while を抜けます。
}
else {
Serial.println("FAILURE, retrying...");
}
}
// 本サンプルでは 1 秒毎に POST を繰り返します。
delay(1000);
}
IFTTT と連携して IoT 電子工作
IFTTT (If This, Then That) は、もしも (if) ある入力 (this) があったならば、別のある出力処理 (that) を実行する多目的な Web サービスです。様々な入力方式 (if this) が提供されており、特に Maker を入力 (this) に指定して、Arduino から HTTP GET または POST でデータを送信することで IoT 電子工作が実現できます。出力方式 (that) には Gmail, Slack, Twitter, スマホ通知 など様々なものが提供されています。ここでは特に Gmail を出力にして HTTP POST でメール送信してみます。
JSON データを POST の body で指定することで、メールタイトルや本文に値を埋め込むことができます。レシピを作成するときに認証許可したアカウントの gmail から、レシピ作成時にカンマ区切りで指定した複数の宛先にメールが送信されます。Arduino の設定に必要な認証情報は以下の二つです。Key はこちらのページで確認できる値です。
Event Name: arduino_esp8266_gmail
Key: sw8UBoTxxKAykBbG7y_8H
gmail.ino
#include <HttpClient_ESP8266_AT.h>
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
const byte txPin = 3; // Wire this to Rx Pin of ESP8266
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
void setup() {
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
Serial.begin(9600);
// SSID と PASSWORD でアクセスポイントに接続します。
// シリアル接続確認と WiFi 接続確認を行い、設定不備があれば出力します。
while(true) {
if(httpClient.statusAT()) { Serial.println("AT status OK"); break; }
else Serial.println("AT status NOT OK");
delay(1000);
}
while(true) { // 書き換えてください↓
if(httpClient.connectAP("SSID", "PASSWORD")) { Serial.println("Successfully connected to an AP"); break; }
else Serial.println("Failed to connected to an AP. retrying...");
delay(1000);
}
while(true) {
if(httpClient.statusWiFi()) { Serial.println("WiFi status OK"); break; }
else Serial.println("WiFi status NOT OK");
delay(1000);
}
}
void loop() {
// ノイズの影響でリクエストに失敗することがあるため while ループで囲います。
while(true) {
// IFTTT への HTTP POST リクエストを実行します。SSL/TLS 通信である必要はなく 80 番ポートを利用できます。
// 以下の二つの項目は、お使いのアカウントで表示されているものに書き換えてください。
// - Event Name: arduino_esp8266_gmail
// - Key: sw8UBoTxxKAykBbG7y_8H
httpClient.post("maker.ifttt.com", // IFTTT のホスト名
"/trigger/arduino_esp8266_gmail/with/key/sw8UBoTxxKAykBbG7y_8H", // <- 書き換えてください。
"{\"value1\":\"ABC\",\"value2\":\"123\",\"value3\":\"456\"}", // JSON データ
"application/json");
// レスポンス status code が 0 以上であればリクエスト成功です。
// -1: ノイズ等でシリアル通信ができず、そもそもデータ送信ができなかった。
// 0: データ送信はできたが、受信データがノイズで壊れてしまっていた。
// else (>0): 受信データから正常に HTTP レスポンス status code が得られた。
if(httpClient.responseStatusCode() >= 0) {
// 本ページでは電圧レベルシフタを用意していない想定のため、
// 受信データが壊れている可能性が高く、したがって 200 が 100 になっていたりするため、
// 値には興味をもたず、0 以上の値が得られることが重要であると考えてコーディングします。
Serial.println("SUCCESS");
break; // 成功したので while を抜けます。
}
else {
Serial.println("FAILURE, retrying...");
}
}
// 本サンプルでは特に他の処理はしません。
while(true); // ずっと待機
}
送信される予定のメール
タイトル
The event named "arduino_esp8266_gmail" occurred on the Maker Channel
本文の例
What: arduino_esp8266_gmail
When: August 4, 2016 at 01:10AM
Extra Data: ABC, 123, 456,
Qoosky API と IFTTT を同時に使ってみる
Qoosky API はインターネット接続されたデバイスをスマートフォンや PC から操作するための BaaS API です。専用の SDK を用いてライブラリをインストールします。
先程の IFTTT と併用することで、スマートフォンや PC から入力 (if this) を制御できるようになります。UNO を使用する場合は特に不足しがちな SRAM を節約するために F()
マクロで文字列を囲んでいます。
gmail_controller.ino
#include <Qoosky_ESP8266_AT.h>
#include <HttpClient_ESP8266_AT.h>
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
const byte txPin = 3; // Wire this to Rx Pin of ESP8266
SoftwareSerial softwareSerial(rxPin, txPin);
Qoosky_ESP8266_AT qoosky(softwareSerial); // 同じ SoftwareSerial を共有
HttpClient_ESP8266_AT httpClient(softwareSerial); // 同じ SoftwareSerial を共有
void setup() {
Serial.begin(9600); // PC との通信で使用する baudrate
softwareSerial.begin(115200); // ESP-WROOM-02 との baudrate
while(true) {
if(qoosky.statusAT()) { Serial.println(F("AT status OK")); break; }
else Serial.println(F("AT status NOT OK"));
delay(1000);
}
while(true) { // 書き換えてください↓
if(qoosky.connectAP(F("SSID"), F("PASSWORD"))) { Serial.println(F("Successfully connected to an AP")); break; }
else Serial.println(F("Failed to connected to an AP. retrying..."));
delay(1000);
}
while(true) {
if(qoosky.statusWiFi()) { Serial.println(F("WiFi status OK")); break; }
else Serial.println(F("WiFi status NOT OK"));
delay(1000);
}
while(true) { // 書き換えてください↓
if(qoosky.connectQoosky(F("XXXX-XXXX-XXXX-XXXX"))) { Serial.println(F("Successfully connected to Qoosky.")); break; }
else Serial.println(F("Failed to connect to Qoosky, retrying..."));
delay(1000);
}
}
void loop() {
int key = qoosky.popPushedKey();
if(key) {
Serial.println("Received: " + String(key) + " (send gmail if key is '8')");
if(key == 8) { // コントローラの 8 番ボタンが押されたら gmail を送信します。
while(true) {
// WebSocket 通信は一旦切断されます。90 秒以内に再接続されます。
httpClient.post(F("maker.ifttt.com"), // 書き換えてください↓
F("/trigger/arduino_esp8266_gmail/with/key/ck8xvpYdBOUeFj2nfZY9yE"),
"{\"value1\":\"" + String(key) + "\",\"value2\":\"" + String(key) + "\",\"value3\":\"" + String(key) + "\"}",
F("application/json"));
if(httpClient.responseStatusCode() >= 0) {
Serial.println(F("send gmail SUCCESS"));
break; // 成功したので while を抜けます。
}
else Serial.println(F("send gmail FAILURE, retrying..."));
}
// 本サンプルでは特に他の処理はしません。
while(true); // ずっと待機
}
}
else Serial.println(F("No pushed key."));
delay(100);
}
関連記事
- 部屋の温度をツイートする Arduino (外出先から制御)作品の簡単な説明 Arduino をインターネットに接続する方法の一つは WiFi モジュール ESP-WROOM-02 を利用することです。こちらのページで紹介されている IFTTT を利用することで、温度センサで測定した値を Twitter に投稿できます。更に Qoosky API を利用することで、外出先からでも好きなタイミングで処理を開始できます。 ![](/ugc/techimages...
- 内蔵LEDを点灯させるまで (Arduino)Arduinoとは Arduino は初心者でも入門しやすいマイコンボードです。アルデュイーノと読みます。マイコンとは家電などに内蔵されている小さなコンピュータで、マイコンが必要とする周辺機器一式と一緒に一つのボードにまとめたものがマイコンボードです。数あるマイコンの中で特にArduinoにはAVRマイコンが使用されています。2005年にイタリアで開始されたオープンソースハードウェアのプロジェクト...
- 虚仮威しの防犯装置 (Arduino)人が接近すると防犯用の音を鳴らします。インターネットに接続してメール送信機能を追加すれば、虚仮威しどころか立派な防犯装置になります。センサの性能は視野角が約 120 度と広範囲で、距離もおおよそ 2m まで検知可能です。赤外線を発する人体や動物などが動くと反応します。自動ドアや照明の自動点灯にも応用されています。
- Arduino で作る温度と気圧の計測基板専用の IC を利用すると、簡単に温度や気圧を測定できます。インターネットに接続してグラフ化したりボットを作ったりと応用先は様々ですが、ここでは LCD に結果を表示する測定基板を作成します。 必要なパーツ 以下のパーツが必要になります。画像ではコンデンサを直列に接続したり抵抗を並列に接続したりしていますが、これは手元に適切な値のパーツがなかったためです。 高精度
- 電力の無駄遣い (定電圧電源)マイコンを含む様々な IC を動作させるためには定電圧電源が必要です。USB ケーブルなどで供給する場合を除き、定電圧を出力するための回路が必要になります。ここでは、乾電池 9V 形から得られる電圧を 5V に変換し、更に 3.3V に変換し、最後に 5V に昇圧するという電力の無駄遣いともとれる基板を作ります。動作させるものはマイコンではなく燦然と輝く LED です。汎用基板として様々な場面で利...