Nikon SDKのC#Wrapper自体は、D600を動かすには充分な能力があります。しかし問題はVisual StudioのC#を使ったフォームでプログラミングする際には”_waitForDevice.WaitOne();”が引っ掛かって、どうやっても動かない。という事で、フォームからのD600の稼働を諦め、フォームでは各種データを入力するだけにして、これを撮像スケジュールファイルとしてファイルに書きだしておき、スタートボタンを押したら、別にC#で書いて実行ファイル形式にした撮像シーケンスソフトウェアで撮像スケジュールを読み込んで、これに従って撮像シーケンスを進めていく形にしました。ここでD7100は、D600がC2前の連写開始時間が始まったときにビープ音を出して、これを感知したら撮像を開始する・・・と言う形にしたいと考えています。 ここには、コマンドラインで動かす連写~多段階露光~連写を行うルーチンを提示しました。各種データはフォームから入力しセーブした撮像スケジュールを読み込んでこれを変数に代入して従って動くようにしたり、タイムラプスのループからダイヤモンドリングのための連写、多段階撮像を時刻で切ってダイヤモンドリグのための連写に移行することなど、色々関門はあります。 フォームもきちんと考えないとですね。 弱点は単写速度が遅いので皆既中の多段階撮像は今回の日食では6セット程度しか撮れない事です。まあこの辺はD7100に依存することになります。 下部にあるプログラムはコマンドプロンプトで動く「連写~多段階の露光~連写」を設定した数値で実行するプログラムです。Wrapperにもありますが、ソースコードのプロパティには、nikonwrapperを導入し、コンパイルして実行ファイルが入るところにはnikoncswrapper.dll、nikoncswrapper.pdb、NkdPTP.dll、Type0008.md3がある必要があります。 設定した数値はフォームから入力し、データはtextファイルで取って起き、コマンドプロンプトで動くこのプログラムに読み込む様に作って行く予定です。 |
//
// This work is licensed under a Creative Commons Attribution 3.0 Unported License.
//Thomas Dideriksen (thomas@dideriksen.com)
//
// Modification is done by M_shi_Lab for imaging automatic Total Solar Eclips
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using Nikon;
namespace demo_capture
{
class DemoCapture
{
NikonDevice _device;
AutoResetEvent _waitForDevice = new AutoResetEvent(false);
AutoResetEvent _waitForCaptureComplete = new AutoResetEvent(false);
public int Speed { get; private set; }
public int MaxSpeed { get; private set; }
public int EVStep { get; private set; }
public int DownStep { get; private set; }
// Create manager object - make sure you have the correct MD3 file for your Nikon DSLR
//(see https://sdk.nikonimaging.com/apply/)
NikonManager manager = new NikonManager("Type0008.md3");
public void Run()
{
try
{
// Listen for the 'DeviceAdded' event
manager.DeviceAdded += manager_DeviceAdded;
// Wait for a device to arrive
_waitForDevice.WaitOne();
// Hook up capture events
_device.ImageReady += _device_ImageReady;
_device.CaptureComplete += _device_CaptureComplete;
//C2ダイヤモンドリング撮像のための連写ルーチン
Speed = 34; //SSはフォームから読み取ります
uint Count = 5; //ここでは5コマですが、コマ数はC2前後撮像する秒数の合計の2倍です
ContinuousCapture(Speed, Count); //サブルーチンに飛びます
//多段階撮像ルーチン
//↓では動作確認上規定値としていますが、本当は表に出るフォームの入力値を
//セーブしたファイルから読み込みます。
MaxSpeed = 36; //最高速度を規定します。デモ上は1/4000secになります
EVStep = 2*2; //EVステップ×2が減速となります
DownStep = 5; //何段階撮像するかを規定します
//最低速度を計算します。デモ上では1/4secになります
int MinSpeed = MaxSpeed - EVStep * DownStep;
//多段階にSSを減速させつつ撮像するルーチン
//1ループごとにC3前連写時刻と現時刻を比較しつつ回す必要がありますが、それは後に。
for (Speed = MaxSpeed; Speed >= MinSpeed; Speed = Speed - EVStep)
{
Captor(Speed);
}
//C3ダイヤモンドリング撮像のための連写ルーチン
Speed = 34; //SSはフォームから読み取ります
Count = 5; //ここでは5コマですが、コマ数はC2前後撮像する秒数の合計の2倍です
ContinuousCapture(Speed, Count); //サブルーチンに飛びます
// Shutdown
manager.Shutdown();
}
catch (NikonException ex)
{
Console.WriteLine(ex.Message);
}
}
private void ContinuousCapture(int Speed, uint Count) //C2,3のダイヤモンドリングを連写するサブルーチン
{
NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
shutterSpeed.Index = Speed;
_device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);
// Set number of continuous captures - in this case we want 5
_device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, Count);
// Capture
_device.Capture();
// Wait for the capture to complete
_waitForCaptureComplete.WaitOne();
}
private void Captor(int Speed) //任意のシャッター速度で単写するサブルーチン
{
_device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
//ShutterSpeed シャッター速度を変えるコード
NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
shutterSpeed.Index = Speed;
_device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);
// Capture
_device.Capture();
// Wait for the capture to complete
_waitForCaptureComplete.WaitOne();
}
void _device_ImageReady(NikonDevice sender, NikonImage image)
{
// Save captured image to disk
string filename = "image" + ((image.Type == NikonImageType.Raw) ? ".jpg" : ".nef");
using (FileStream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
s.Write(image.Buffer, 0, image.Buffer.Length);
}
}
void _device_CaptureComplete(NikonDevice sender, int data)
{
// Signal the the capture completed
_waitForCaptureComplete.Set();
}
void manager_DeviceAdded(NikonManager sender, NikonDevice device)
{
if (_device == null)
{
// Save device
this._device = device;
device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_SaveMedia, (uint)eNkMAIDSaveMedia.kNkMAIDSaveMedia_Card);
// Signal that we got a device
_waitForDevice.Set();
}
}
}
class Program
{
static void Main(string[] args)
{
DemoCapture demo = new DemoCapture();
demo.Run();
}
}
}