3秒でTHETA Sとつながるリモートシャッターを作る

この記事はRICOH THETA Advent Calendar 2015 16日目の記事です。

ESP-WROOM-02というWi-Fiモジュールを使って、THETA Sのリモートシャッター装置を作ります。

各所で様々なリモコンが作られていますが、この記事では次の4点を目標にしたリモコンを作ります。

  • THETA Sのシャッターを切れる
  • 3秒でつながる
  • だいたいフリスクサイズ (タカチのCS90に収める)
  • USBで充電できる

f:id:shrhdk:20151203235959j:plain

ESP-WROOM-02とは

ESP-WROOM-02はArduinoとして動くWi-Fi機能搭載モジュールです。 Arduino言語というC++風の馴染みやすい言語を使ってプログラミングができます。

Wi-FiTCP/IPプロトコルスタックを積んでいるので、 ネットに接続するデバイスを簡単に作ることができます。

OS等はありませんので起動が速いです。これを使うことで3秒くらいでつながるリモコンが作れます。

技適マーク付きなので、日本国内でも白昼堂々と使える合法モジュールです。

ハードウェア構成

ハードウェアのブロック図は以下のようになります。(回路図はこちら)

f:id:shrhdk:20151213185114p:plain

PCとESP-WROOM-02の接続 (USB-シリアル変換)

PCとESP-WROOM-02の間は3.3Vのシリアル通信で接続して、PCからESP-WROOM-02へプログラムを書き込みます。

最近のPCにはシリアル通信のインタフェースは搭載されていないので、USBから変換して接続します。 USBとシリアル通信を変換するモジュールは電子工作では一般的なもので、各社から様々なモジュールが発売されています。

今回は、秋月電子超小型USBシリアル変換モジュールを利用します。

電池と充電制御

フリスクサイズに収めようとすると、単3電池や単4電池は大きくて使えません。 また、ESP-WROOM-02はそこそこ電流が必要なのでコイン電池も使えません。 よって、小型で大容量・大出力のリチウムイオン電池を使います。

リチウムイオン電池の充電制御には専用IC(MCP73831T-2)を使います。

DC-DCコンバーター

ESP-WROOM-02は3.3Vの電源を必要としますが、リチウムイオン電池の電圧は残量によって2.5Vから4.2Vくらいに変化します。 そのため、リチウムイオン電池の電圧を3.3Vに変換する必要があります。

この変換に特化したTPS63000というモジュールがあるのでこれを使います。

このコンバーターとESP-WROOM-02の組み合わせについては次のブログが詳しいです。

ねむいさんのぶろぐ | ESP-WROOM-02を使ってみる3 -そんな電源で大丈夫か-

基板

フリスクサイズにしたいので、基板を作って表面実装部品を多用します。

基板はオープンソースKiCadを使って作図しFusion PCBに発注しました。 10枚作成して送料込みで$14.22と格安でした。

まだ届いていないですが、こんな感じになる予定です。

f:id:shrhdk:20151213235305p:plain

ソフトウェア開発環境

PlatformIOという組み込みシステム用のビルドツールを使います。

PlatformIOはplatformio.iniというプロジェクトファイルを書いておけば、 ビルドコマンドを叩くだけでビルド環境のインストールからライブラリのインストール、ビルド、ボードへの転送までを自動で実行してくれます。 ツールチェーンの構築などに悩まされることもありません。

Pythonが使える環境でしたら、以下のコマンドでインストールできます。

$ pip install -U pip setuptools     
$ pip install -U platformio

PlatformIOではsrcディレクトリの下にArduino言語のコードを置きます。 プロジェクトの構成は次のようになります。

project-dir/
 |-- platformio.ini
 |-- src/
     |-- xxx.ino
     |-- yyy.ino
     |-- zzz.ino

PlatformIOでESP-WROOM-02の開発をする方法については次の記事が詳しいです。

また、今回のプロジェクトをGitHubにアップしましたので、以後はこれに使って説明します。

Arduinoの基本

PlatformIOではArduino言語でプログラムを開発できます。

Arduinoのプログラムではエントリーポイントとして、 最初に一度だけ呼ばれるsetup関数と繰り返し呼ばれるloop関数を書きます。

setup関数には初期化処理を書き、loop関数にはメインの処理を書きます。

void setup() {
  // 起動時に一度だけ実行したい処理を書く
  // I/Oの初期化等をする。
}

void loop() {
  // この中は繰り返し実行される。
  // ボタンが押されたことを検知してシャッターを切ったり、
  // Wi-Fiの状態を見て接続を開始したりする。
}

プログラムのビルドと書き込み

ESP-WROOM-02は各ピンの電圧を次のようにした状態でリセットすることで、プログラムダウンロードモードで起動します。

PIN 電圧
GPIO0 LOW (0V)
GPIO2 LOW (0V)
GPIO15 HIGH (3.3V)

今回の回路はGPIO2はプルアップ、GPIO15はプルダウンしています。 そして、GPIO0にはシャッターボタンが接続されていて、ボタンを押すとLOWになるようになっています。

つまり、シャッターボタンを押した状態で電源を入れるとプログラムダウンロードモードで起動します。

プログラムダウンロードモードで起動している状態で以下のコマンドを実行すると、プロジェクトをビルドしてボードにアップロードします。

platformio run --target upload

ここまでの手順をまとめると次のようになります。

# (1) PlatformIOのインストール
$ pip install -U pip setuptools     
$ pip install -U platformio

# (2) シャッターボタンを押した状態でリモコンの電源を入れて、
# リモコンをプログラムダウンロード状態で起動する。

# (3) リモコンをPCにUSBで接続する。

# (4) 今回のプロジェクトをクローン
$ git clone https://github.com/shrhdk/theta-remote-release.git
$ cd theta-remote-release
$ git checkout 0.0.1

# (5) ビルドしてリモコンにアップロード
$ platformio run --target upload

プログラムについて

撮影の流れ

THETA Sの撮影はRICOH THETA API v2を叩くことで実現できます。RICOH THETA API v2はHTTPでJSONをやり取りする極めてシンプルなAPIです。

RICOH THETA API v2には多数のコマンドがありますが、今回は次の2種類のコマンドだけを使います。

最低限の撮影の流れは次のようになります。

  1. ESP-WROOM-02からTHETA SにWi-Fi接続
  2. ESP-WROOM-02からTHETA Sにcamera.startSessionコマンドを送信
  3. レスポンスとしてsessionIdが得られる。
  4. ESP-WROOM-02からTHETA Sにcamera.takePictureコマンドを送信
  5. このコマンドは先ほど得たsessionIdを指定する必要がある。

f:id:shrhdk:20151214004309p:plain

THETA Sへの接続

THETA SはWi-Fiアクセスポイントとして動いているので、ESP-WROOM-02から接続します。 スマホから接続するのと同じで、THETA S固有のSSIDに接続します。(使用説明書:スマートフォンと接続する)

THETA Sのポートは192.168.1.1:80に固定されているので、こちらにコマンドを送信していきます。

プログラムの流れ

プログラム(src/main.ino)の流れは次のようになります。

f:id:shrhdk:20151216171844p:plain

setup関数 (最初に一度だけ実行)

  1. シリアル通信の初期化 (シリアル通信でログを吐く)
  2. I/Oの初期化 (シャッターボタンが接続されたIO0を入力モードに設定)

loop関数 (setup関数の後に呼ばれて、以後繰り返し呼ばれる)

  1. Wi-Fiが接続されていないなら接続 (THETA SのSSIDとパスワードはsrc/wifi.inoに設定)
  2. シャッターボタンが押されていたら、以下の処理を行う
  3. camera.startSessionコマンドを送信
  4. レスポンスからsessionIdを取得
  5. camera.takePictureコマンドを送信
  6. 3秒間待機 (撮影完了を待つ)

本来であれば、camera.startSessionコマンドははじめに一回だけ送信し、以後は定期的にcamera.updateSessionコマンドでセッションを更新するべきです。

また、camera.takePictureコマンドの送信後は3秒待機するのではなく、コマンドの実行状況をチェックするべきです。

今回はいずれも簡単のために省略というかサボっています。

試作品

最後に試作品の動画を載せます。THEA SのWi-FiのLEDが点滅から点灯に変わると接続完了です。 電源ONからだいたい3秒くらいで接続できるのがわかります。

基板が届いたら完成品の記事をアップしたいと思います。

完成品の記事をアップしました。

shrhdk.hatenablog.com