Help us understand the problem. What is going on with this article?

ESP-WROOM-02 で、モバイル物理スイッチを作る

More than 3 years have 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の面白さかもしれません。
ie4
iotlt
IoT縛りの勉強会です。 毎月イベントを実施しているので是非遊びに来てください! 登壇者を中心にQiitaでも情報発信していきます。 https://iotlt.connpass.com
https://iotlt.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした