2017-12-23

Arduino ESP8266で一眼レフ用無線リモートレリーズを作ってみた

Arduino ESP8266

こんばんは、kat-kai (@katkai3) です。かなり遅くなってしまいましたが、本記事はArduino Advent Calendar 2017の12日目の記事でした。今回はスマートフォンから一眼レフを撮影できるようにするリモートレリーズの制作記事です。 camera_man

9日目には Arduino ESP8266を使ったIoTキッチンスケールの記事を書いていますので、良ければこちらもご覧ください。

今回、Arduino ESP8266と一眼レフカメラを接続しますが、本サイトの記事・内容によって、利用者に被害・損害が生じても、著者は一切の責任を負わず補償も一切致しません。ご自身の自己責任の上でご利用頂きますようお願い致します。

はじめに

作ろうとしたきっかけ

bg_uchu_space_resize

きれいな星空や月の写真を見て、自分でも一眼レフを使って星空の写真を撮ってみたいなーって思うようになったことが発端です。 そうした星空の撮影には、リモートレリーズと呼ばれるカメラに直接触れることなく撮影できるリモコンがあると便利と知り、リモートレリーズに興味を持ちました。

そこでリモートレリーズについてちょっと調べてみると、実際にリモートレリーズを自作されている人がいて、なおかつArduinoを使って制御している人もいました。

例えば、私が使っているCanon EOS Kiss X7の場合ではリモートレリーズ用の端子にφ2.5ステレオプラグが使われています。(φ2.5プラグは、普通のイヤホンのφ3.5プラグよりも一回り小さいです)   stereo

このφ2.5ステレオプラグの先端・真ん中・根本(GND)に繋がっている信号線をショートさせれば良く、先端をショートさせるとシャッター、真ん中でショートさせるとオートフォーカスとなります。  

これならArduino ESP8266を使って制御することでリモートレリーズが作れそう、その上でESP8266はWiFiが使えるから無線リモートレリーズを作ってみよう!ということで取り組みました。

今回はトランジスタを使ってφ2.5ステレオプラグの信号線のON/OFFをArduino ESP8266から制御することによって一眼レフのシャッターを切れるようにします。

出来たもの

plug

こんな感じでEOS Kiss X7に接続してます。単3電池2本で駆動、タッパーに入れて使ってます。

inside

中身はこんな感じ。パターンカットした基板の表にトランジスタをはんだ付け、裏面にはESP8266用の金属皮膜抵抗と、スイッチング回路用のチップ抵抗をはんだ付けしています。

使ったもの

  • Espressif WiFiモジュール ESP8266
  • スイッチサイエンス ピッチ変換用基板《フル版》(パターンカットして使っています)
  • φ2.5ステレオジャック, ケーブル
  • 電池ボックス(単3x2本用)
  • トランジスタ 2SC1815 x2
  • チップ抵抗 10kΩ x2
  • 容器用の小さいタッパー

回路/ソースコードについて

今回はESP8266のIO16をシャッター用に、IO14をオートフォーカス用に使っています。それぞれで抵抗とトランジスタを使って、スイッチング回路を組みます。

Arduino ESP8266をアクセスポイントにしてWebサーバーとして動かすことで、スマートフォンからアクセス出来るようにします。スマートフォンからESP8266のアクセスポイントに接続している時は、インターネットに接続できなくなってしまうので、少し不便ですが、この際目をつぶることにします。

また見栄えを良くするためにBootstrapを使っていますが、スマートフォンからESP8266に接続時はインターネットに接続できなくなるので、BootstrapのファイルをESP8266の内部フラッシュメモリにSPIFFSファイルシステムを使って書き込んでおきます。

Arduinoに書き込むスケッチ esp8266-release.ino は以下の通りです。
ソースコード全体はkat-kai/ESP8266-RemoteReleaseから、ご覧ください。

/*!
 * ESP8266-RemoteRelease v0.1
 * Copyright 2017 kat-kai
 * Licensed under the MIT license
 */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <Ticker.h>

#define SHUTTER_PIN 16
#define FOCUS_PIN 14

ESP8266WebServer server(80);
Ticker ticker, subticker;

void connectWiFi() {
  WiFi.disconnect();
  delay(10);
  
  WiFi.mode(WIFI_STA);
  WiFi.softAP("esp-release", "password"); //SSID:esp-release, パスワード: password。必要に応じて変更してください

  Serial.println();
  Serial.print("softAP IP address: ");
  Serial.println(WiFi.softAPIP()); //Default ESP8266's IP: 192.168.4.1
}

void getLocalFile(String filename, String dataType) {
  SPIFFS.begin();
  File data = SPIFFS.open(filename, "r");
  server.streamFile(data, dataType);
  data.close();
}

void releaseButton(int pin, int msec){
  digitalWrite(pin, HIGH);
  delay(msec);
  digitalWrite(pin, LOW);
}

void setup(void){
  Serial.begin(115200);

  pinMode(SHUTTER_PIN, OUTPUT);
  pinMode(FOCUS_PIN, OUTPUT);

  connectWiFi();
  
  server.on("/", [](){ getLocalFile("/index.html", "text/html"); });
  server.on("/bootstrap.min.js", [](){ getLocalFile("/bootstrap.min.js", "text/javascript"); });
  server.on("/bootstrap.min.css", [](){ getLocalFile("/bootstrap.min.css", "text/css"); });

  server.on("/on/", [](){ Serial.println("on"); digitalWrite(SHUTTER_PIN, HIGH); server.send(200, "text/html", ""); });
  server.on("/off/", [](){ Serial.println("off"); ticker.detach(); digitalWrite(SHUTTER_PIN, LOW); server.send(200, "text/html", ""); });

  server.on("/shutter/", [](){ Serial.println("shutter"); releaseButton(SHUTTER_PIN, 1000); server.send(200, "text/html", ""); }); 
  server.on("/focus/", [](){ Serial.println("focus"); releaseButton(FOCUS_PIN, 1000); server.send(200, "text/html", ""); });

  server.on("/interval/", [](){
    Serial.print("interval: ");
    Serial.println(server.arg("t"));
    
    int wait_ms = server.arg("t").toInt() * 1000;
    ticker.attach_ms(wait_ms, [](){
      Serial.println("interval");
      digitalWrite(SHUTTER_PIN, HIGH);
      subticker.once_ms(1000, [](){ digitalWrite(SHUTTER_PIN, LOW); });
      });
    server.send(200, "text/html", "");
  });

  server.on("/self/", [](){
    Serial.print("self: ");
    Serial.println(server.arg("t"));
    
    int wait_ms = server.arg("t").toInt() * 1000;
    ticker.once_ms(wait_ms, [](){
      Serial.println("self");
      digitalWrite(SHUTTER_PIN, HIGH);
      subticker.once_ms(1000, [](){ digitalWrite(SHUTTER_PIN, LOW); });
      });
    server.send(200, "text/html", "");
  });


  server.onNotFound([](){ server.send(404, "text/plain", "File Not Found"); });

  server.begin();
  Serial.println("httpd: Started.");

}

void loop(void){
  server.handleClient();
}

connectWiFi()で、ESP8266をsoftAPとして使う設定をします。
デフォルトではSSID:esp-release、パスワード:passwordで接続出来ます。こちらは必要に応じて変更して下さい。
ESP8266のアクセスポイントに接続し、192.168.4.1にアクセスすると下のような画面になります。

ss2

  • インターバル撮影 (繰り返し)
  • バルブ撮影開始・終了
  • シャッター(全押し)・オートフォーカス(半押し)
  • セルフタイマー撮影 (一度限り)

の機能を搭載しています。

releaseButton()の呼び出し時、待機時間int msecを1000ミリ秒にしていますが、
待機時間が少し長いかもしれないので、適宜調整して下さい。

おわりに

Arduino ESP8266を使うことで、無線リモートレリーズを作ることができました。羨ましいことにEOS Kiss X7の後続機にはリモート撮影機能が標準搭載されているようです。私の持っているX7ではそうした機能はなかったので、インターバル撮影やバルブ撮影をリモートで出来るようにしたものを作ってみました。

今回は、趣味である「電子工作」と「写真撮影」を組み合わせた、ものづくりに取り組めてとても楽しかったです。

最近ではArduinoやESP8266/ESP32に関する情報も豊富になってきていますし、
自分自身が欲しいものを作れる、作りやすい環境が整ってきているというのは、とても嬉しいことですね!

これまで以上にArduino, ESP8266/ESP32が普及していけばいいなーって思います!それでは!

投稿をシェアする