任天堂NDSL掌上型遊戲機+Arduino微電腦=縮時影片拍攝控制器
文∕趙英傑
大約三年前,HDR Labs採用任天堂NDSL遊戲機充當人機介面,加上一個自製的Arduino微電腦板,製作出一款開放式相機控制器(Open Camera Controller,簡稱OCC)。它可以控制照相機的快門,拍攝縮時攝影、星軌以及HDR高動態範圍相片。因為我使用的Sony NEX-5相機無法接快門線,所以我替它加入紅外線遙控功能(哦,NEX-5R和NEX-6有支援APP下載功能,相機本身即可拍攝縮時影像,我想我大概會等到Sony推出Android版的NEX系列,或者NEX-Xperia才會更換相機吧~)
有興趣的人士可以在HDR Labs網站的OCC網頁下載相關程式(含原始碼)和硬體。

(照片取自HDR Labs)
實際連接照相機的是Arduino微電腦板,它被製作成Game Boy遊戲卡匣形式,插接在NDSL主機前方的Game Boy遊戲卡插槽。因此,本文使用的Nintendo DS遊戲機,必須是具備Game Boy遊戲插槽的初代機種,NDSi, NDSLL和3DS等新機種都不行。

(照片取自HDR Labs)
為了讓NDSL執行自製軟體,還必須額外購買R4卡和micro SD記憶卡。
底下是HDR Labs設計的印刷電路板,讀者可以照著OCC硬體介紹網頁的說明自行蝕刻一片:

(照片取自HDR Labs)
電路板前方的兩個小IC,是隔離微電腦與相機快門線的電氣訊號的光耦合元件。這個電路跟照相機的廠牌型號無關,可以控制Canon, Nikon, Olympus, Sony, Panasonic, Casio…等廠牌的相機。
然而,不同廠牌與型號的相機快門線設計都不太一樣,這個電路輸出到快門線之間的轉換電路你要自己搞定。像Canon EOS D500單眼相機的快門線只是一個「加上兩個開關的2.5 mm立體耳機線」,所以不用外加任何電路即可使用,但Panasonic的快門線就得加上幾個電阻(請自行Google電路)。
使用《轉轉壞俐歐工坊》遊戲卡匣來包裝Arduino微電腦板
HDR Labs選用《轉轉壞俐歐工坊》(まわる メイドインワリオ)這一款遊戲的卡匣外殼來包裝。因為《轉轉壞俐歐工坊》內建一個陀螺儀感測器(Gyro Sensor),卡匣後面凸出一塊,適合放置轉接線頭:

這是陀螺儀感測器正面的模樣:

《轉轉壞俐歐工坊》裡面包含200個以上逗趣的休閒小遊戲,遊戲不使用十字鈕操作,完全透過陀螺儀偵測主機傾斜或旋轉的方向來遊玩。這遊戲實在太有趣(看看YouTube上的這個遊戲內容介紹吧),將它拆掉很可惜。如果你不介意電路板裸露在外的話,就不必使用這個卡匣。
改造Game Boy遊戲卡匣
我用不到快門線,而且蝕刻電路板有點麻煩,所以用萬用PCB板(也稱為「洞洞板」)來組裝、焊接元件。但是,萬用PCB板並沒有像遊戲卡匣前面的條紋接點,所以我把一塊不用的Game Boy(簡稱GB)遊戲卡鋸下來。
Game Boy Advanced(簡稱GBA)的遊戲卡匣和GB卡的接點設計是一樣的,下圖左邊是GBA卡,右邊是GB卡:

底下是把鋸下來的GB卡與自製的Arduino微電腦板焊接在一起的樣子,最前方的透明LED是紅外線發射二極體:

HDR Labs選用的微處理器是ATmega168,實際上,選用ATmega8型號即可,當然,用ATmega328也行,它們之間的差別主要在於記憶體容量的大小。我在ATmega8微處理器的第15腳(也就是Arduino微電腦板的數位第9腳)焊接一個100Ω電阻和紅外線發射LED。
控制相機快門線的Arduino程式碼
底下是HDR Labs的硬體介紹網頁所刊載的Arduino程式碼,應該是打字錯誤,其中三行有誤:
int FullPressPin = 13;
int HalfPressPin = 12;
int ShutterState=LOW; // 應該要刪除這一行
int IsShooting=0;
int x = 0;
int HeartbeatPin = 4;
volatile int state = LOW;
/*
上面一行應該改寫成:
volatile int ShutterState = LOW;
*/
void setup()
{
pinMode(HalfPressPin, OUTPUT);
pinMode(FullPressPin, OUTPUT);
pinMode(HeartbeatPin, OUTPUT);
attachInterrupt(0, ProcessDSSignalRising, RISING);
attachInterrupt(1, ProcessDSSignalFalling, FALLING);
ShutterState=LOW; // de-depress shutter button if it is an unknown state
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HalfPressPin, ShutterState);
//May 2010 Heartbeat code variation
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
delay(500);
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
delay(500);
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
}
void loop()
{
if (IsShooting = 0){ // 應該寫成:if (IsShooting == 0){
ShutterState=LOW;
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HalfPressPin, ShutterState);
}
}
void ProcessDSSignalRising()
{
ShutterState=LOW;
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HeartbeatPin, LOW);
digitalWrite(HalfPressPin, ShutterState);
IsShooting=0;
}
void ProcessDSSignalFalling()
{
ShutterState=HIGH;
// add a delay here to make HalfPress a tad longer
for (x=0;x< 5; x++){
digitalWrite(HalfPressPin, ShutterState);
}
digitalWrite(HeartbeatPin, HIGH);
digitalWrite(FullPressPin, ShutterState);
IsShooting=1;
}
上面的Arduino程式會接收從任天堂NDSL遊戲機發出的中斷訊號,在中斷訊號的下降階段(FALLING),Arduino將控制快門線的半按以及全按動作;在中斷訊號的上昇階段(RISING),Arduino將釋放快門。
透過Arduino微電腦使用紅外線遙控數位相機
Sebastian Setz開發了一個Arduino數位相機紅外線遙控程式庫”multiCameraIrControl“,能遙控Canon, Nikon, Olympus, Pentax, Sony或Minolta等相機的紅外線程式庫。
Sony NEX-5相機無法外接快門線,所以我透過這個紅外線遙控程式庫,改寫上面的程式,讓Arduino在中斷訊號的上昇階段發射紅外線來控制數位相機,改寫後的程式碼如下:
#include <multiCameraIrControl.h>
const byte FullPressPin = 13;
const byte HalfPressPin = 12;
boolean IsShooting=false;
byte HeartbeatPin = 4;
volatile boolean ShutterState=LOW;
volatile boolean IRState = false;
const byte cameraPin = 9; // 紅外線遙控LED接在第9腳
Sony NEX(cameraPin); // 初始化紅外線遙控程式庫
void setup()
{
pinMode(HalfPressPin, OUTPUT);
pinMode(FullPressPin, OUTPUT);
pinMode(HeartbeatPin, OUTPUT);
pinMode(cameraPin, OUTPUT);
attachInterrupt(0, ProcessDSSignalRising, RISING);
attachInterrupt(1, ProcessDSSignalFalling, FALLING);
ShutterState=LOW;
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HalfPressPin, ShutterState);
//May 2010 Heartbeat code variation
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
delay(500);
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
delay(500);
digitalWrite(HeartbeatPin, HIGH);
delay(1000);
digitalWrite(HeartbeatPin, LOW);
}
void loop()
{
if (IsShooting == false){
ShutterState=LOW;
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HalfPressPin, ShutterState);
digitalWrite(HeartbeatPin, ShutterState);
} else {
if (IRState) {
IRState = false;
NEX.shutterNow(); // 發射紅外線快門訊號
}
}
}
void ProcessDSSignalRising()
{
ShutterState=LOW;
digitalWrite(FullPressPin, ShutterState);
digitalWrite(HeartbeatPin, LOW);
digitalWrite(HalfPressPin, ShutterState);
IsShooting=false;
IRState = true; // 設定成「可發射紅外線」
}
void ProcessDSSignalFalling()
{
ShutterState=HIGH;
for (byte x=0;x< 5; x++){
digitalWrite(HalfPressPin, ShutterState);
}
digitalWrite(HeartbeatPin, HIGH);
digitalWrite(FullPressPin, ShutterState);
IsShooting=true;
}
編譯並上傳程式以上程式碼到ATmega8微處理器,就可以插入NDSL遊戲機使用了。
用NDSL遊戲機玩縮時攝影
每次操作快門時,電路板上的綠色LED也會跟著閃爍。此電路板安裝在任天堂NDSL遊戲機的模樣如下:

在任天堂NDSL遊戲機上執行HDR Labs自製的”Intervalometer”縮時攝影程式(可在HDR Labs的軟體網頁下載)的外觀如下,點選底下觸控螢幕Increment後面的數字,可調整拍攝的間隔時間。這個軟體還可讀取NDSL主機的時鐘,讓你設定從某個時間開始拍攝,或者直接按下L和R鍵開始控制相機:

附帶一提,底下的縮時影片,是一位名叫Robin Baumgarten的德國佬,使用筆者製作的Android紅外線快門與縮時攝影控制器免費軟體,加上自製的紅外線遙控發射器拍攝的(原文發表於dpreview.com論壇):
