所有しているSony NEX-5でタイムラプス動画の撮影をしたい。
でも本体にはその機能がなくプログラマブルタイマもオプションとして存在しない。
なければ作りましょう。というわけで作成しました。
カメラ本体は赤外線リモコンでシャッターが切れる仕様。
シャッター信号を赤外線LEDで一定間隔で送信するのが必要な機能。追加の機能としてシャッター間隔を変更できると活用の幅が広がる。せっかくのでESP32のAPモードでスマホから撮影間隔を変更できるようにしてみた。
構成部品
5mm赤外線LED 940nm OSI5LA5113A
MOSFET 2N7000
PchパワーMOSFET(55V11A) IRFU9024NPBF
ESP32
無印良品 小物ケース・SS (ESP32にちょうどいい)
https://www.muji.com/jp/ja/store/cmdty/detail/4550182202922
接続概念図
完成形
ケースにLEDとUSB電源用の穴をあけ組み込み。固定はグルーガン。最終的に星の写真を撮りたかったのでオフにできない電源LEDも黒のグルーガンで埋めてしまう。
以下のコードをESP32に書きこむ。
電源が入ると1秒間隔でシャッター用赤外線信号を発生する。スマホで近くのWifi
を探すと設定したSSIDが見えるので参加しブラウザでhttp://192.168.20.2にアクセス。バーストモードとの切り替えボタンが表示されるのでオフにすると30秒間隔でシャッターと切るモードに変更可能。
タイムラプス用リモコン
#include <WiFi.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <Ticker.h>
String header;
WiFiServer server(80);
const uint16_t kIrLed = 14; // LED接続用PIN番号
IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
int irLED = 14;
String LEDoutpinState = "on";
const char ssid[] = "CameraRemote70"; // APモード用SSID
const char pass[] = "cameraremote70"; // APモード用password
const IPAddress ip(192, 168, 20, 2); // IPアドレス
const IPAddress subnet(255, 255, 255, 0); // サブネットマスク
void sonyshoot(void) {
Serial.println("Sony");
irsend.sendSony(0xB4B8F, 20); // 12 bits & 2 repeats 0xB4B8F inmiddiatry ,0xECB8F 2sec timer
}
Ticker toggler;
void sonyshoot(void) {
Serial.println("shoot");
for (int i = 0; i < 18; i++)
{
digitalWrite(irLED, HIGH);
delayMicroseconds(9);
digitalWrite(irLED, LOW);
delayMicroseconds(20);
}
delayMicroseconds(7330);
for (int i = 0; i < 18; i++)
{
digitalWrite(irLED, HIGH);
delayMicroseconds(9);
digitalWrite(irLED, LOW);
delayMicroseconds(20);
}
}
const int defaultperiod = 30;//通常モードでは30秒間隔で撮影
const int LEDoutpin = 14;
void setup() {
pinMode(LEDoutpin, OUTPUT);
digitalWrite(LEDoutpin, LOW);
sonyshoot();
toggler.attach(1, sonyshoot);
Serial.begin(115200);
WiFi.softAP(ssid, pass); // SSIDとパスの設定
delay(100); // 追記:このdelayを入れないと失敗する場合がある
WiFi.softAPConfig(ip, ip, subnet); // IPアドレス、ゲートウェイ、サブネットマスクの設定
IPAddress myIP = WiFi.softAPIP(); // WiFi.softAPIP()でWiFi起動
server.begin(); // サーバーを起動(htmlを表示させるため)
/* 各種情報を表示 */
Serial.print("SSID: ");
Serial.println(ssid);
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.println("Server start!");
}
void loop() {
WiFiClient client = server.available(); //クライアント(スマホやPCなど)がつながっているかどうかをclientに出力
if (client) { // クライアントが来たとき
Serial.println("New Client.");
String currentLine = ""; // クライアントからくるデータを格納する変数
while (client.connected()) { // クライアントがつながっている間、以下をループ
if (client.available()) { // クライアントからデータが来ているとき
char c = client.read(); // データを読み込み
Serial.write(c); // 届いたデータをシリアルモニタに出力
header += c;
if (c == '\n') { // 届いたデータが改行コードだった時
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// リクエストに従ってモードの切り替え
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
LEDoutpinState = "on";
toggler.detach();
toggler.attach(1, sonyshoot);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
LEDoutpinState = "off";
toggler.detach();
toggler.attach(defaultperiod, sonyshoot);
}
// htmlを表示
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// ON/OFFボタンのためのCSS
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");
// ページ本体(bodyタグ内)
client.println("<body><h1>Remote Shutter</h1>");
// 現在のモードと、オンオフ用のボタンを出力
client.println("<p>Burst Mode State " + LEDoutpinState + "</p>");
// LEDoutpinStateがオフなら、ONにするボタンを表示
if (LEDoutpinState == "off") {
client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// HTTPレスポンスの最後は改行で終了
client.println();
// whileループの終了
break;
} else { // 改行コードを取得したら、currentLineをリセット
currentLine = "";
}
} else if (c != '\r') { // 改行以外の何かしらのコードが来ているとき
currentLine += c; // currentLineに追加
}
}
}
// ヘッダーをリセット
header = "";
// 接続をリセット
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
投稿者の人気記事
-
Koji
さんが
2021/02/27
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する