実験装置の動作に合わせてデジタルカメラで自動的に撮影させるため、通過センサーとArduinoでカメラと装置とを同期させた。
センサーは2つあり、写真奥がシャッター半押し用、手前がリリース用。順に反応したときにだけシャッターが切れる(往復動作の機器のときに復路でシャッターが切れないようにするため)。金具を介して、実験装置に固定する。アルミのプレートは特製。黒い鉄製の金具は市販品。実験装置の動作部に遮光板を取り付け、センサーのスリットの間を通過するようにする。このセンサーは遮光時にONの信号がでる。

Arduinoを使って、センサーからの信号をシャッターの制御に変換する。
- プッシュスイッチ(赤)・LED(赤):制御オン・オフ
- プッシュスイッチ(黒・中央)・LED(青):シャッター半押し状態を持続(カメラの半押しまでの動作を省くとき)
- LED(黄):半押しの位置のセンサーが反応、カメラを半押し状態に
- LED(緑):リリースの位置のセンサーが反応、シャッターを切る
- プッシュスイッチ(黒・端):マニュアルシャッター
- DIPスイッチ1:センサーと反応対象物の明暗が逆の時にON(変更後はリセットスイッチを押す)
- DIPスイッチ2:センサーを逆方向に取り付けたときにON(変更後はリセットスイッチを押す)
- 半固定抵抗:センサーの感度調節(EE-SX460-P1の場合は中央の位置)


カメラとの接続には、カメラのリモコンを利用する。ニコンの場合は、端子を短絡させるだけのリモートケーブルがあるので、それを利用する。ただしニコン側に極性がある(RJ-45の端子3→リモートケーブルの黄;4+6→黒;5→青)。キヤノンも端子を短絡させるだけ。USBなどで接続するリモコンでは、リモコンのシャッタースイッチの端子から導線を引き出せば、同様に接続できる。


反射センサーの使用例
通過センサーの代わりに反射センサーを使うこともできる。

スケッチ
/*
Photosensor_shutter
This sketch is written to control the camera shutter by photosensors.
This work is licensed under a Creative Commons Attribution 4.0 International License.
<http://creativecommons.org/licenses/by/4.0/>
(c) 2016, Tohru Murakami, Gunma University.
*/
// Hardware constants. Adjust these values per installations.
const int latentcy = 100; // msec
const float baselineVoltage = 2.5; // threshold voltage of the photosensor; 0 – 5.0
// Pin assignments
// DIPSW Switch inputs
const int DIPSW_sensorTypeMismatch = 12;
const int DIPSW_sensorDirection = 13;
// Switch inputs
const int SWPin_autoControl = 3; // the auto-control switch
const int SWPin_contHalfPush = 4; // the continuous-half-push switch
const int SWPin_manualRelease = 5; // the manual-shutter-release switch
// Switch indicator outputs
const int ledPin_autoControl = 7; // the auto-control indicator
const int ledPin_contHalfPush = 6; // the continuous-half-push indicator
// Shutter indicator outputs
const int ledPin_halfPush = 8; // the half-push indicator
const int ledPin_release = 9; // the shutter-release indicator
// Shutter outputs
const int optoPin_halfPush = 11; // the half-push optocoupler
const int optoPin_release = 10; // the shutter-release optocoupler
// Sensor inputs (for default installation)
int sensorPin_halfPush = A1; // the half-push photosensor
int sensorPin_release = A0; // the shutter-release photosensor
// Serial communication rate
const int serialSpeed = 9600;
// Shutter status aliases
const int interval = 0;
const int standby = 1;
// DIPSW switch values (0 for default installation)
int sensorTypeMismatch = 0;
int sensorDirection = 0;
// Variables
int releaseCounter = 0; // count shutter release
int shutterStatus = interval;
int autoControl = 0;
int contHalfPush = 0;
int manualRelease = 0;
int sensorVal_halfPush; // 10 bit unsigned integer
int sensorVal_release; // 10 bit unsigned integer
float voltage_halfPush; // 0.0–5.0
float voltage_release; // 0.0–5.0
void setup() {
int temp;
// Assign output pins
pinMode(optoPin_halfPush, OUTPUT);
pinMode(optoPin_release, OUTPUT);
pinMode(ledPin_autoControl, OUTPUT);
pinMode(ledPin_contHalfPush, OUTPUT);
pinMode(ledPin_halfPush, OUTPUT);
pinMode(ledPin_release, OUTPUT);
// Assign switche pins
pinMode(DIPSW_sensorTypeMismatch, INPUT);
// HIGH = light-ON sensor for dark signal or dark-ON for light signal; LOW = matched
pinMode(DIPSW_sensorDirection, INPUT); //HIGH reverse; LOW default
pinMode(SWPin_autoControl, INPUT); //HIGH automatic; LOW no shutter control
pinMode(SWPin_contHalfPush, INPUT); //HIGH continuous half push; LOW sensor-controled half push
pinMode(SWPin_manualRelease, INPUT); //HIGH shutter release
// initialize output pins
digitalWrite(ledPin_autoControl, LOW);
digitalWrite(ledPin_contHalfPush, LOW);
digitalWrite(optoPin_halfPush, LOW);
digitalWrite(ledPin_halfPush, LOW);
digitalWrite(optoPin_release, LOW);
digitalWrite(ledPin_release, LOW);
// read the DIP switches
sensorTypeMismatch = digitalRead(DIPSW_sensorTypeMismatch); // LOW = default, HIGH = mismatch
sensorDirection = digitalRead(DIPSW_sensorDirection); // LOW = default, HIGH = reverse
// adjust the sensor direction
if (sensorDirection == HIGH) {
temp = sensorPin_halfPush; // Swap the sensor pin assignments
sensorPin_halfPush = sensorPin_release;
sensorPin_release = temp;
}
// initialize serial communication
Serial.begin(serialSpeed);
// print message when done.
Serial.println("Photosensor-driven shutter controler ready!");
}
void loop() {
// read the switches
manualRelease = digitalRead(SWPin_manualRelease);
autoControl = digitalRead(SWPin_autoControl);
contHalfPush = digitalRead(SWPin_contHalfPush);
if (manualRelease == HIGH) { // releaes the shutter when the manual shutter release switch is pressed.
Serial.print("Manual ");
release();
} else if (autoControl == HIGH) {
digitalWrite(ledPin_autoControl, HIGH);
if (contHalfPush == HIGH) { // leave the half-push HIGH when the continuous-half-push switch is ON
digitalWrite(ledPin_contHalfPush, HIGH);
digitalWrite(optoPin_halfPush, HIGH);
} else if (shutterStatus == interval) {
digitalWrite(ledPin_contHalfPush, LOW);
digitalWrite(optoPin_halfPush, LOW);
};
// read the sensor values and convert them to voltage levels
sensorVal_halfPush = analogRead(sensorPin_halfPush);
sensorVal_release = analogRead(sensorPin_release);
voltage_halfPush = (sensorVal_halfPush / 1024.0) * 5.0;
voltage_release = (sensorVal_release / 1024.0) * 5.0;
// print the voltage levels on the serial port
// Serial.print("half push sensor: ");
// Serial.print(voltage_halfPush);
// Serial.print(", release sensor: ");
// Serial.println(voltage_release);
if (sensorTypeMismatch == HIGH) { // invert the sensor voltages when sensorTypeMismatch is bright ON
voltage_halfPush = 5.0 - voltage_halfPush;
voltage_release = 5.0 - voltage_release;
};
if (voltage_halfPush > baselineVoltage && voltage_release <= baselineVoltage && shutterStatus == interval) {
// turn half-push HIGH when the half-push sensor detects something.
digitalWrite(optoPin_halfPush, HIGH);
digitalWrite(ledPin_halfPush, HIGH);
shutterStatus = standby;
};
if (voltage_release > baselineVoltage && shutterStatus == standby) {
// release the shutter when the release sensor detects something.
release();
shutterStatus = interval;
};
} else { // make everything zero when autoControl SW is off.
Serial.println("OFF");
digitalWrite(ledPin_autoControl, LOW);
digitalWrite(ledPin_contHalfPush, LOW);
digitalWrite(optoPin_halfPush, LOW);
digitalWrite(ledPin_halfPush, LOW);
digitalWrite(optoPin_release, LOW);
digitalWrite(ledPin_release, LOW);
shutterStatus = interval;
};
}
void release() {
digitalWrite(optoPin_halfPush, HIGH);
digitalWrite(ledPin_halfPush, HIGH);
delay(latentcy); // give the optocoupler a moment to activate
digitalWrite(optoPin_release, HIGH);
digitalWrite(ledPin_release, HIGH);
delay(latentcy); // give the optocoupler a moment to activate
digitalWrite(optoPin_release, LOW);
digitalWrite(ledPin_release, LOW);
digitalWrite(ledPin_halfPush, LOW);
if (contHalfPush != HIGH) {
digitalWrite(optoPin_halfPush, LOW);
};
Serial.print("# ");
Serial.println(releaseCounter++);
}