More than 1 year has passed since last update.

追記:申し訳ありません。pullupの仕方に、誤りがありました。
更に追記:そもそも pullup/pulldown が不要である事が分かりました。

ESP8266 Advent Calendar 2015 の2日目担当 ie4 と申します。

このエントリーでは、「ESP-WROOM-02を使うと、結局どんなものが作れるのか。」という疑問に答えるべく、その1例を挙げてみたいと思います。

携帯できるインターネット物理ボタンを作ろう

ESP_WROOM_02_NETBOTTUN_403.jpg

Web上のアプリケーションに、ON/OFFの信号を送る物理ボタンを作ります。
で、その物理ボタンにバッテリーを繋いで、持ち歩けるようにするのが目標です。

ぶっちゃけ、物理ボタンである事にこだわらなければ、スマホで実現可能な機能です。

ただ、物理ボタンには、こだわるだけの価値があります

  • 操作する人への案内が簡単:「このQRを読んで、このURLにアクセスして、それから…」と長々と説明しなくても、この物理ボタンを手渡せば終了
  • 操作が簡単で、誤操作がない: 余計なボタンや機能がないので、ホームボタンやメニューボタンなど、変なボタンを押してしまって、アタフタする事がない
  • ボタンをカチカチすることの楽しさ: 説明しづらいけど、ボタンカチカチは楽しい

この辺が、私の考える物理ボタンの良さです。

ESP_WROOM_02_NETBOTTUN_401.jpg

で、作るのは良いけど、その物理ボタンが結局何の役に立つの、という点ですが、ON/OFFを通知するだけの機能なので、Webアプリ側の作り方次第で何でも出来ます。

オフィスの隅にあるコーヒーメーカーにコーヒーを淹れさせる事も、ドローンにぶら下げたクス玉を割って門出を祝うことも、作り方次第では可能です。(本エントリーより難しい実装が別途必要ですが…)

ESP_WROOM_02_NETBOTTUN_402.jpg

とりあえず今回は、YesかNoかを回答するボタンを作成する事にします。
ユースケースは、エントリー後半に記載します。

完成品はこちら

ESP_WROOM_02_NETBOTTUN_001.jpg

かなり雑な作りですが、これでも立派にインターネットに繋がります・・・

白いボタンで1、赤いボタンで10をサーバーに送信します。
同時に押した場合は、11が送信され、何も押してない状態に戻ると0が送信されます。

ケースを開けると、中身は
ESP_WROOM_02_NETBOTTUN_002.jpg
このようになっており、
基板を裏返すと
ESP_WROOM_02_NETBOTTUN_003.jpg
このようになっております… (お見せするのが恥ずかしい有様です…)

次に、ただサーバーへ数値を送信するだけでも意味がないので、それをモニタリングします。
サーバー側はNode.jsで実装し、socket.ioを使って、Web画面を切り替えています。

ESP_WROOM_02_NETBOTTUN_101.jpg
ボタンを何も押していない時は、?が表示されます。

ESP_WROOM_02_NETBOTTUN_102.jpg
赤いボタンを押せばNoが表示され、

ESP_WROOM_02_NETBOTTUN_103.jpg
白いボタンを押せばYesが表示されます。

以上が、最終的に作るモノになります。
以下、作り方となります。

用意したモノ

ESP-WROOM-02 ピッチ変換済みモジュール (フル版)

https://www.switch-science.com/catalog/2347/

  • これが無いと始まりません。
  • ピッチ変換済みのESP-WROOM-02モジュールは、各社から出ていますが、今回はスイッチサイエンスさんのフル版を利用しました。
  • ボタンの入力に使うのは2ピンだけなので、デジタル入力できるピンが2つ空いていれば、どのモジュールでも良いかと思います。ただ、ケースに収まるサイズを選ぶようにしましょう。
  • ピンヘッダを付けるために、はんだ付けする作業が必要です。

リチウムイオンポリマー電池 3.7V 400mAh

https://www.switch-science.com/catalog/821/

  • 今回の工作の要は、なんと言ってもこの電源(バッテリー)です。サイズ的にもジャストサイズで、電圧も容量もジャストです。電源の確保については、CR2032・CR2450・18650等など、色々と試行錯誤した結果、最終的にココに落ち着きました。
  • 先日まで品切れ状態でしたが、大量入荷したようです。
  • スイッチサイエンスさんのページにも記載がありますが、取扱いには十分にご注意ください。

リチウムイオン電池充電器 (マイクロUSBタイプ)

https://www.switch-science.com/catalog/506/

  • 上記バッテリーと一緒に購入しておきましょう。
  • PCでの充電用にマイクロUSBケーブルが別途必要ですが、マイクロUSBタイプの携帯充電器があれば、その携帯充電器から充電可能なので、マイクロUSBケーブルは不要です。

JST製2ピンPHコネクタ用ソケット

https://www.switch-science.com/catalog/2090/

  • 基板へバッテリーを接続する際に必要になります。

普通のピンヘッダ10本セット

https://www.switch-science.com/catalog/92/

  • ESP-WROOM-02を基板に取り付ける際に必要になります。
  • また、他の用途にも活躍するので、ぜひ持っておきたい消耗品です。

スライドスイッチ

http://www.marutsu.co.jp/pc/i/14846/

  • 基板に取り付け、電源のON/OFFに使用します。

ポータブル プラスチックケース

http://www.marutsu.co.jp/pc/i/101676/

  • もろもろ、このケースに収めます。手のひらに完全に収まるサイズです。

ユニバーサル基板 (44mm×69mm)

http://www.marutsu.co.jp/pc/i/14190/

  • 上記ケースにスッポリ収まる基板です。
  • ケースにカチッとはハマらないので、ケースの中身がカタカタするのが嫌な場合は、ケースにねじ止めするなりする必要があります。

タクトスイッチキャップ 2個 + タクトスイッチキャップ (赤、白 各1個)

http://www.aitendo.com/product/9609
http://www.aitendo.com/product/9530

  • 押しボタンはこちらを使います。

カーボン抵抗 10kΩ

http://akizukidenshi.com/catalog/g/gR-25103/

  • 追記:今回のケースでは、pullup/pulldown抵抗は不要でした。
  • プルアップ/プルダウン抵抗に使用します。
  • 実は、うっかりコレを実装するのを忘れてしまったのですが、それでも動くには動くようです。とはいえ、パーツを破損させない為にも、「なぜか動かない!><」という事態を回避する為にも、実装しておいた方が良いです。 追記:今回のケースでは、スイッチング等の開放状態が発生しない為、電流制限抵抗等の目的がない限り、プルアップ/プルダウンは不要でした
  • プルアップ/プルダウン抵抗に関しては、後述します。

その他

電子工作用はんだ

http://www.amazon.co.jp/dp/B0029LGANO/

  • 電子工作と言えば、はんだですね。
  • ブレッドボードのおかげで、「とりあえず動くもの」を作るのは簡単になりましたが、色んなパーツと組み合わせたり、ケースに入れて云々…とこだわりだすと、やはり避けては通れないのが、はんだ付けです。
  • ワイヤラッピング - Wikipediaという、はんだ付けを行わない電子配線もあるみたいです。⇒ ラッピングツール - 共立エレショップ

ダイヤル式温度制御はんだこて

http://www.amazon.co.jp/gp/product/B006MQD7M4/

ラッピングワイヤ 5色セット

http://www.amazon.co.jp/gp/product/B005FNVOWU/

  • 映画などで、ニッパーでちょきんと切ると、タイマーが止まったり、早まったりする奴ですね。
  • 剥き出しの銅線だと、基板の裏で交差したり出来ないので、被膜付きの銅線が必要です。
  • 太すぎると取り回しが不便ですが、細すぎると加工が難しいです。

スズメッキ線 φ0.6mm

http://www.amazon.co.jp/dp/B00FIXM89U/

  • ほとんど使ってないので、不要かもしれませんが、持っておくと役に立ちます。
  • 抵抗やコンデンサなどの、切り落とした余分な足を再利用するケースも多々あります。

FTDI USB・シリアル変換ケーブル (3.3V)

http://akizukidenshi.com/catalog/g/gM-05840/

  • ESP-WROOM-02 へのプログラミングは、コレ経由でやることにします。
  • 電圧をお間違えなく(5Vではないです)。
  • いささか高いので、この辺もある程度自作したい感じではあります。(まぁ、いくつも必要なモノではありませんが)

ホットナイフ

http://www.amazon.co.jp/gp/product/B0016V7JII/

  • ケースから押しボタンを出すため、矩形の穴を開けるのに使用しました。
  • ただ、プラスティックを溶かして穴を開ける為、バリも大きく、嫌な臭いも出るので、ドリルで小さな穴をたくさん開けて、矩形状にくり抜く方が良さそうです。

配線・回路図

本エントリーでは、ESP-WROOM-02へのスケッチの書き込み方や接続の方法については触れません。
後日、誰かがきっと、そのようなエントリーを投稿してくれるでしょうし、もうあるかもしれません。

というわけで早速、完成した携帯できる物理スイッチが、どのような構成になっているかを見てみます。

配線は、下記のようにしました。
※スケッチ書き込み済みの FLASH Boot Mode での配線です。

追記: pullupの配線に誤りがありました。正しくは、2つ目の図の配線となります。

▼誤りがある方の図
ESP_WROOM_02_NETBOTTUN_301_NG.jpg

▼正しい方の図
ESP_WROOM_02_NETBOTTUN_301_OK.jpg
※手書きで申し訳ありません…

  • pullup抵抗とpulldown抵抗が入っていますが、「pullup/pulldwonってなんぞ!」という方は、こちらの動画「【実況?】 零からの電子工作 第10回:タクトスイッチ 後編」で非常に分かり易く解説されているので、視聴をオススメします(9分20秒辺りからpullup抵抗を無くした場合の実際の挙動が見れます)。 追記:動画は、不安定になるのを防止する目的でpullup/pulldownを入れていますが、上図では開放状態(不安定になる状態)が発生しない為、実際は、電流制限抵抗としての役割しかありません。電流制限抵抗としての役割が不要であれば、pullup/pulldown抵抗も不要です。

書き込み済みのスケッチは、下記になります。

#include <ESP8266WiFi.h>

const char* ssid     = "お使いのWiFiのSSIDを入れてください";
const char* password = "お使いのWiFiのPasswordを入れてください";
const char* host = "IPアドレス or ホスト名"; // Webアプリを設置するサーバー
const int port = 20000; // 接続を受け付けるポート

const int btnYes = 12;
const int btnNo  = 13;
int curData ;
int tmpData ;

void setup() {
  pinMode(btnYes, INPUT_PULLUP);
  pinMode(btnNo, INPUT_PULLUP);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void loop() {
  int yesState = digitalRead(btnYes);
  int noState = digitalRead(btnNo);
  curData = 0 ;
  if(!yesState){
    curData = 1 ;
  }
  if(!noState){
    curData |= 1 << 1 ;
  }
  if ( tmpData != curData ) {
    sendMessage(curData);
    tmpData = curData;
  }
  delay(50);
}

void sendMessage(int data) {

  WiFiClient client;
  if (!client.connect(host, port)) {
    return;
  }

  client.print(data, BIN);

  while (client.available()) {
    String line = client.readStringUntil('\r');
  }

}

WiFiへの接続が成功すれば、これで該当サーバーのポート:20000番へデータを送信します。

サーバー側

サーバー側では、Node.js でデータを受け付けます。

Webアプリですが、通常の80番ポートは使用せず、下記の2つのポートを使用する事にしました。

8888番ポート: モニタリングWebアプリ用ポート
20000番ポート: 物理ボタンからのデータの受け取り

app.js
var net = require('net'),
    http = require("http"),
    socketio = require("socket.io"),
    fs = require("fs");

// モニタリング画面の用意
var server = http.createServer(function(req, res) {
    res.writeHead(200, {"Content-Type":"text/html"});
    var output = fs.readFileSync("./index.html", "utf-8");
    res.end(output);
}).listen(8888);
var io = socketio.listen(server);

// 物理ボタンからのデータ受け口
var server = net.createServer(function(conn){
  conn.on('data', function(data){
    console.log(data.toString('ascii'));
    // モニタリング画面へデータ送信
    io.sockets.emit("message", {value:data.toString('ascii')});
  });
}).listen(20000);
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Yes/No Bottun</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect();
socket.on("connect", function(){});
socket.on("disconnect", function(client){});
socket.on("message", function(data){ addMessage(data.value); });
function addMessage(val) {
    if(val==1){
        color = "#fff";
        fontc = "#000";
        text = "Yes";
    }else if(val==10){
        color = "#f00";
        fontc = "#fff";
        text = "No";
    }else{
        color = "#333";
        fontc = "#fff";
        text = "?";
    }
    $("#answer").css("background-color",color);
    $("#answer").css("color",fontc);
    $("#answer").text(text);
}
</script>
<style>
body{
  background-color: #000;
}
#answer{
  height: 300px;
  width:  300px;
  font-size: 150px;
  font-weight: bold;
  color: #fff;
  display: table-cell;
  vertical-align: middle;
  text-align: center;
  background-color: #333;
}
</style>
</head>
<body>

<div id="answer">?</div>

</body>
</html>

必要に応じて、requireされているモジュールをnpmなりでインストールしておいてください。

動作確認

ユニバーサル基板へ各パーツをはんだ付けし、配線を済ませ、バッテリーを繋いで、node appすれば、準備はすべて完了です。

http://WebアプリのIPアドレス:8888/へアクセスすると、以下のような?マークの画面が表示され
ESP_WROOM_02_NETBOTTUN_104.jpg
白と赤の物理ボタンで、YesNoの表示に切り替わります。
※離すとまたに戻ります

また、ターミナル上にも

$ ls
app.js  index.html
$ 
$ node app
1
0
10
0

のように、物理ボタンから送信された数値が、ほぼリアルタイムで表示されます。

以上で、インターネット接続可能な持ち歩ける物理ボタンの完成です。

おまけ

ユースケース

Webアプリ側は作り変える必要がありますが、例えばこんな使い方。

  • 100個作って、その場で人気投票大会
  • 10個作って、審査員10名によるオーディション (8イイネ以上が合格)
  • 5個作って、審査員5名による、紅白戦 (3イイネ以上が勝利)
  • 1個作って、誰かが隠し持ち、みんなの質問にYes/Noで答えて(Yes/Noの回答は画面で確認)、誰がもってるか当てる

ちょうど忘年会シーズンですので、何かのゲームに使ってみてはいかがでしょうか。

書き終えてみて

  • Advent Calendar 初投稿でした。作法とかよく分かっていないので、至らぬ点もあったかも。
  • スイッチという表記と、ボタンという表記が混在し、統一できていない…スイッチは機能として、ボタンはUIとして、書き分けているとお考えください。
  • イメージが湧きやすいようにと、イラスト付きで臨みましたが、逆効果だった可能性も。
  • 作っても作っても、作りたいモノが無くならないのが、ESP-WROOM-02の面白さかもしれません。
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.