8.と9.で作ったソフト(「入力フォーム&テキストファイル掃出しソフト」と「テキストファイルからシーケンス制御するソフト」)を統合しました。これらによるNikon謹製SDKでのD600の制御だけでは無く、C2前の連写開始の時にD7200のシーケンサの起動信号音も同時に出せるようにしました。 Visual Studioでの作成時には、マイソリューションにSolution ExploreからWindowsBase、System.Windows, nikoncswrapperを参照するようにして、出力のアーキテクチャはX86にします。プロパティはAllow Drop TrueをFalseにするという事もしました。本当はフォームに前回入れた内容を再表示するようにしたかったのですが、上手くゆかず…その関係のコードも入っていたりします。フォームから撮像開始も出来ますが、一応シーケンス制御のソフト部分に関しても起動用のショートカットを作っておいた方が良いかと思ったりします。誤動作を防いだりするために。現時刻をラベルに表示しようかと考えていましたが、どうも上手くないので止め。フールプルーフ等も作って入ませんし、取り敢えず出来るよ、ってところでしょうか。 2台のデジイチ、はD600の制御はほぼ考えた通りに動いてくれていますし、音入力でのD7200のシーケンス制御も上手く行っています。とはいえ本当に上手く行くか・・・をデジイチとWin Tabを組み合わせてやってみる事、マウンティングに組んで配線すること、全システムの機材の電源を入れて、1時間半置いて自動撮像をさせてみるストレステストなど、制御ではなくシステムに慣れて使えるよう慣熟していくことかな、という事になります。機材の制御に一応のゴールが見えてきたので、時間管理のためにAndroidタブで時間管理するソフトを作ろうかとも考えています。テンパるなか、取るもの取り敢えず・・・ではなく、操作をサクッと事を済ませられるようにすることが必要です。 |
フォームから情報の入ったテキストを作成するフォームの裏にあるソフトウェア
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Data;
5: using System.Drawing;
6: using System.Linq;
7: using System.Text;
8: using System.Threading.Tasks;
9: using System.Windows.Forms;
10:
11:
12: namespace Eclips_Captor
13: {
14: public partial class Form1 : Form
15: {
16:
17: public ComboBox comboBox1_SelectedIndex_1;
18: public ComboBox comboBox1_SelectedIndex;
19: public ComboBox comboBox5_SelectedIndex;
20: public ComboBox comboBox4_SelectedIndex;
21: public ComboBox comboBox3_SelectedIndex;
22: public ComboBox comboBox2_SelectedIndex;
23: public ComboBox comboBox6_SelectedIndex;
24:
25: public string ContS;
26: public char KeyChar;
27: public string C2Hr;
28: public string C2Min;
29: public string C2Sec;
30: public string C2Total;
31: public string C3Hr;
32: public string C3Min;
33: public string C3Sec;
34: public string C3Total;
35: public string C2Before;
36: public string C2After;
37: public string C3Before;
38: public string C3After;
39: public string LapsTime;
40:
41: //public string Cont_SS;
42: //public string Step;
43: public int index;
44: public string IntSS;
45: public string Max_speed;
46: public string EV_Step;
47: public string Capture_Step;
48:
49: //public string IntSS { get; private set; }
50: public string IntSec; //{ get; private set; }
51: public string C2Time; //{ get; private set; }
52: public string C3Time; //{ get; private set; }
53:
54: //public object textBox1;
55:
56: //public readonly object comboBox1;
57:
58: public Form1()
59: {
60: InitializeComponent();
61: }
62:
63: //コンボボックスからのインプット
64: public void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
65: {
66: int Int_SS = comboBox2.SelectedIndex;
67: IntSS = Int_SS.ToString();
68: }
69:
70: public void ContSS_SelectedIndexChanged(object sender, EventArgs e)
71: {
72: int Cont_SS = ContSS.SelectedIndex;
73: ContS = Cont_SS.ToString();
74: }
75:
76: public void Max_SS_SelectedIndexChanged(object sender, EventArgs e)
77: {
78: int MaxSS = Max_SS.SelectedIndex;
79: Max_speed = MaxSS.ToString();
80: }
81:
82: public void EVStep_SelectedIndexChanged(object sender, EventArgs e)
83: {
84: int EV = EVStep.SelectedIndex;
85: EV_Step = EV.ToString();
86: }
87:
88: public void CaptureSteps_SelectedIndexChanged(object sender, EventArgs e)
89: {
90: int Capture = CaptureSteps.SelectedIndex;
91: Capture_Step = Capture.ToString();
92: }
93:
94: //各種数値のインプット
95: public void Interval_TextChanged(object sender, EventArgs e)
96: {
97: IntSec = Interval.Text;
98: }
99: public void textBox1_TextChanged(object sender, EventArgs e)
100: {
101: C2Hr = textBox1.Text;
102: }
103: public void textBox3_TextChanged(object sender, EventArgs e)
104: {
105: C2Min = textBox3.Text;
106: }
107: public void textBox4_TextChanged(object sender, EventArgs e)
108: {
109: C2Sec = textBox4.Text;
110: }
111: public void C2Time_TextChanged(object sender, EventArgs e)
112: {
113: C2Time = C2Hr + ":" + C2Min + ":" + C2Sec;
114: }
115:
116: public void textBox8_TextChanged(object sender, EventArgs e)
117: {
118: C2Before = textBox8.Text;
119: }
120: public void textBox9_TextChanged(object sender, EventArgs e)
121: {
122: C2After = textBox9.Text;
123: }
124:
125: public void textBox5_TextChanged(object sender, EventArgs e)
126: {
127: C3Hr = textBox5.Text;
128: }
129: public void textBox6_TextChanged(object sender, EventArgs e)
130: {
131: C3Min = textBox6.Text;
132: }
133: public void textBox7_TextChanged(object sender, EventArgs e)
134: {
135: C3Sec = textBox7.Text;
136: }
137: public void C3Time_TextChanged(object sender, EventArgs e)
138: {
139: C3Time = C3Hr + ":" + C3Min + ":" + C3Sec;
140: }
141:
142: public void textBox10_TextChanged(object sender, EventArgs e)
143: {
144: C3Before = textBox10.Text;
145: }
146: public void textBox11_TextChanged(object sender, EventArgs e)
147: {
148: C3After = textBox11.Text;
149: }
150:
151: /*public void label24_Click(object sender, EventArgs e)
152: {
153: label24.Text = C3Time + C2Time;
154: }*/
155:
156: //データのセーブ
157: public void button2_Click(object sender, EventArgs e)
158: {
159: string strData;
160: strData = "";
161: strData = IntSS + "," +ContS + "," + Max_speed + "," + EV_Step + "," + Capture_Step + "," + IntSec + "," + C2Hr + "," + C2Min + "," + C2Sec + "," + C2Before + "," + C2After + "," + C3Hr + "," + C3Min +"," +C3Sec + "," + C3Before + "," + C3After;
162:
163: string path = "D600CaptureSetting.txt";
164:
165: System.IO.StreamWriter sw = new System.IO.StreamWriter(
166: path,
167: false,
168: System.Text.Encoding.Default);
169: sw.WriteLine(strData);
170: sw.Close();
171: }
172:
173: //撮像プログラム稼働開始
174: public void button1_Click(object sender, EventArgs e)
175: {
176: Process.Start("Caputor_Main2.exe");
177: }
178:
179:
180: }
181: }
先のフォームの書きだした テキストファイルを元にシーケンス制御するプログラム
1: //
2: // This work is licensed under a Creative Commons Attribution 3.0 Unported License.
3: //Thomas Dideriksen (thomas@dideriksen.com)
4: //
5: // Modification is done by The M_shi for imaging automatic Total Solar Eclips
6: //
7:
8: using System;
9: using System.Collections.Generic;
10: using System.Linq;
11: using System.Text;
12: using System.Threading.Tasks;
13: using System.Threading;
14: using System.IO;
15: using Nikon;
16:
17: namespace demo_capture
18: {
19: class DemoCapture
20: {
21: NikonDevice _device;
22: AutoResetEvent _waitForDevice = new AutoResetEvent(false);
23: AutoResetEvent _waitForCaptureComplete = new AutoResetEvent(false);
24: //NikonImage image;
25: //NikonDevice sender;
26: //NikonDevice device;
27: public int Speed { get; private set; }
28: public int MaxSpeed { get; private set; }
29: public int EVStep { get; private set; }
30: public int DownStep { get; private set; }
31: public int LapsSS { get; private set; }
32: public int Present_time { get; private set; }
33: public int n { get; private set; }
34: public string[] cols = new string[17];
35:
36: // Create manager object - make sure you have the correct MD3 file for your Nikon DSLR
37: //(see https://sdk.nikonimaging.com/apply/)
38:
39: NikonManager manager = new NikonManager("Type0008.md3");
40: public int Hour;
41: public int Minute;
42: public int Second;
43: //private Stream arg;
44: private object test;
45: private string stResult;
46: private object row2;
47: private int ContSS;
48:
49: public void Run()
50: {
51: //ファイルの読み出しルーチン
52: System.IO.StreamReader cReader = (new System.IO.StreamReader("D600CaptureSetting.txt", System.Text.Encoding.Default));
53: while (cReader.Peek() >= 0)
54: {
55: // ファイルを 1 行ずつ読み込む
56: string stBuffer = cReader.ReadLine();
57: // 読み込んだものを追加で格納する
58: stResult += stBuffer + System.Environment.NewLine;
59: }
60: // cReader を閉じる
61: cReader.Close();
62: Console.WriteLine(stResult);
63:
64: // カンマ区切りで個々の要素の文字列に分離する
65: char delimiter = ',';
66: for (int i = 0; i <= 16; i++)
67: {
68: cols = stResult.Split(delimiter);
69: }
70:
71: // 分離した個々の要素を整数に変換・変数に導入する
72: int index_LapsSS = Convert.ToInt32(cols[0]);
73: int index_Speed = Convert.ToInt32(cols[1]);
74: int index_Maxspeed = Convert.ToInt32(cols[2]);
75: int index_EVStep = Convert.ToInt32(cols[3]);
76: int index_DownStep = Convert.ToInt32(cols[4]);
77: int Interval = Convert.ToInt32(cols[5]);
78: int C2_hour = Convert.ToInt32(cols[6]);
79: int C2_min = Convert.ToInt32(cols[7]);
80: int C2_sec = Convert.ToInt32(cols[8]);
81: int C2_before = Convert.ToInt32(cols[9]);
82: int C2_after = Convert.ToInt32(cols[10]);
83: int C3_hour = Convert.ToInt32(cols[11]);
84: int C3_min = Convert.ToInt32(cols[12]);
85: int C3_sec = Convert.ToInt32(cols[13]);
86: int C3_before = Convert.ToInt32(cols[14]);
87: int C3_after = Convert.ToInt32(cols[15]);
88:
89: // 時刻を秒単位に変換しておく
90: int C2time = C2_hour * 3600 + C2_min * 60 + C2_sec;
91: int C2Before = C2time - C2_before;
92: int C2After = C2time + C2_after;
93: int C3time = C3_hour * 3600 + C3_min * 60 + C3_sec;
94: int C3Before = C3time - C3_before;
95: int C3After = C3time + C3_after;
96:
97: System.IO.StreamWriter index_LapsSS2 = new System.IO.StreamWriter(Console.OpenStandardOutput());
98:
99: // 規定値から入力した値の数値化
100: switch (index_LapsSS) //タイムラプス時のシャッター速度
101: {
102: case 0:
103: LapsSS = 36;
104: break;
105: case 1:
106: LapsSS = 34;
107: break;
108: case 2:
109: LapsSS = 32;
110: break;
111: }
112:
113: switch (index_Speed) //ダイヤモンドリング撮像時のシャッター速
114: {
115: case 0:
116: ContSS = 36;
117: break;
118: case 1:
119: ContSS = 34;
120: break;
121: case 2:
122: ContSS = 32;
123: break;
124: }
125:
126: switch (index_Maxspeed) //多段階撮像時のシャッター速度
127: {
128: case 0:
129: MaxSpeed = 36;
130: break;
131: case 1:
132: MaxSpeed = 34;
133: break;
134: case 2:
135: MaxSpeed = 32;
136: break;
137: }
138:
139: switch (Convert.ToInt32(index_EVStep)) //EVの間隔
140: {
141: case 0:
142: EVStep = 6;
143: break;
144: case 1:
145: EVStep = 5;
146: break;
147: case 2:
148: EVStep = 4;
149: break;
150: case 3:
151: EVStep = 3;
152: break;
153: case 4:
154: EVStep = 2;
155: break;
156: case 5:
157: EVStep = 1;
158: break;
159: }
160:
161: switch (Convert.ToInt32(index_DownStep)) //EV間隔ごとに何回撮像するか
162: {
163: case 0:
164: DownStep = 11;
165: break;
166: case 1:
167: DownStep = 10;
168: break;
169: case 2:
170: DownStep = 9;
171: break;
172: case 3:
173: DownStep = 8;
174: break;
175: case 4:
176: DownStep = 7;
177: break;
178: case 5:
179: DownStep = 6;
180: break;
181: case 6:
182: DownStep = 5;
183: break;
184: case 7:
185: DownStep = 4;
186: break;
187: case 8:
188: DownStep = 3;
189: break;
190: case 9:
191: DownStep = 2;
192: break;
193: case 10:
194: DownStep = 1;
195: break;
196: }
197:
198: try
199: {
200: // Listen for the 'DeviceAdded' event
201: manager.DeviceAdded += manager_DeviceAdded;
202:
203: // Wait for a device to arrive
204: _waitForDevice.WaitOne();
205:
206: // Hook up capture events
207: _device.ImageReady += _device_ImageReady;
208: _device.CaptureComplete += _device_CaptureComplete;
209:
210: //C2までのタイムラプス撮像ルーチン
211: DateTime dtNow = DateTime.Now;
212: int iHour = dtNow.Hour;
213: int iMinute = dtNow.Minute;
214: int iSecond = dtNow.Second;
215: int iPresent_time = iHour * 3600 + iMinute * 60 + iSecond;
216: //C2前ダイヤモンドリング撮像までのタイムラプス撮像
217: while (C2Before - Interval >= iPresent_time)
218: {
219: Speed = LapsSS;
220: Captor(Speed);
221:
222: dtNow = DateTime.Now;
223: iHour = dtNow.Hour;
224: iMinute = dtNow.Minute;
225: iSecond = dtNow.Second;
226: iPresent_time = iHour * 3600 + iMinute * 60 + iSecond;
227: System.Threading.Thread.Sleep((Interval - 4) * 1000); //カメラ側の関係で4秒位時間を食うのでその調整
228: }
229:
230: var
231: //非同期で警報音を鳴らす
232: player = new System.Media.SoundPlayer("wb04.wav");
233: //非同期再生する
234: player.Play();
235:
236: //C2ダイヤモンドリング撮像のための連写ルーチン
237: uint Count = ((uint)C2_before + (uint)C2_after) * 2; //枚数はC2前後撮像する秒数の合計の2倍です
238: Speed = ContSS;
239: ContinuousCapture(Speed, Count); //サブルーチンに飛びます
240:
241: //多段階撮像ルーチン//
242: //最低速度を計算します。
243: int MinSpeed = MaxSpeed - EVStep * DownStep;
244: Speed = MaxSpeed;
245:
246: //多段階にSSを減速させつつ撮像するルーチン
247: //1ループごとにC3前連写時刻と現時刻を比較しつつ回す必要がありますが、それは後に。
248:
249: while (iPresent_time + 4 <= C3Before) //C3連写前の多段階撮像の肝
250: {
251: Captor(Speed);
252:
253: dtNow = DateTime.Now;
254: iHour = dtNow.Hour;
255: iMinute = dtNow.Minute;
256: iSecond = dtNow.Second;
257: iPresent_time = iHour * 3600 + iMinute * 60 + iSecond;
258:
259: //if (iPresent_time - 5 >= C3Before)
260: //{
261: // break;
262: //}
263:
264: if (Speed - EVStep > MinSpeed)
265: {
266: Speed = Speed - EVStep;
267: }
268: else
269: {
270: Speed = MaxSpeed;
271: }
272: }
273:
274: //C3ダイヤモンドリング撮像のための連写ルーチン
275: Count = ((uint)C3_before + (uint)C3_after) * 2; //撮像コマ数の指定
276: Speed = LapsSS; //シャッター速度の指定
277: ContinuousCapture(Speed, Count); //SSとコマ数を持って撮像サブルーチンに飛びます
278:
279: //C3ダイヤモンドリング撮像後のタイムラプス撮像の指定(ここでは300秒としている)
280: DateTime dt = DateTime.Now;
281: iHour = dtNow.Hour;
282: iMinute = dtNow.Minute;
283: iSecond = dtNow.Second;
284: iPresent_time = iHour * 3600 + iMinute * 60 + iSecond;
285: int Ending_time = iPresent_time + 300; //5分間5秒間隔で連写を続ける
286:
287: while (iPresent_time <= Ending_time)
288: {
289: dtNow = DateTime.Now;
290: iHour = dtNow.Hour;
291: iMinute = dtNow.Minute;
292: iSecond = dtNow.Second;
293: iPresent_time = iHour * 3600 + iMinute * 60 + iSecond;
294:
295: Captor(Speed);
296: System.Threading.Thread.Sleep((Interval - 3) * 1000); //カメラ側の関係で3秒位時間を食うのでその調整
297: }
298:
299: // Shutdown
300: manager.Shutdown();
301: }
302: catch (NikonException ex)
303: {
304: Console.WriteLine();
305: }
306: }
307:
308:
309:
310: // C2,C3前後の連写のためのサブルーチン
311: private void ContinuousCapture(int Speed, uint Count)
312: {
313: NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
314: shutterSpeed.Index = Speed;
315: _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);
316:
317: // Set number of continuous captures - in this case I set Count
318: _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, Count);
319:
320: // Capture
321: _device.Capture();
322:
323: // Wait for the capture to complete
324: _waitForCaptureComplete.WaitOne();
325:
326: return;
327: }
328:
329: // タイムラプス・多段階露光時の単写のためのサブルーチン
330: private void Captor(int Speed)
331: {
332: //C2前の連写枚数になっているので、これをリセット
333: _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
334:
335: //シャッター速度を変えるコード
336: NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
337: shutterSpeed.Index = Speed;
338: _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);
339:
340: //シャッター速度が1/30以下ならミラーアップ
341: /* if (Speed <= 22)
342: {
343: //uint mirrorUp;
344: NikonEnum mirrorUp = _device.GetEnum(eNkMAIDMirrorUpReleaseShootingCount.kNkMAIDMirrorUpReleaseShootingCount_0);
345: mirrorUp.Index = 0;
346: _device.SetEnum(eNkMAIDMirrorUpReleaseShootingCount.kNkMAIDShootingMode_MirrorUp, mirrorUp);
347: }
348: /* else
349: {
350: NikonEnum e = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode);
351: e.Index = 0;
352: _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode, e);
353: } */
354:
355: // Capture
356: _device.Capture();
357:
358: // Wait for the capture to complete
359: _waitForCaptureComplete.WaitOne();
360: return;
361: }
362:
363: void _device_ImageReady(NikonDevice sender, NikonImage image)
364: {
365: // Save captured image to disk
366: string filename = "image" + ((image.Type == NikonImageType.Raw) ? ".jpg" : ".nef");
367:
368: using (FileStream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
369: {
370: s.Write(image.Buffer, 0, image.Buffer.Length);
371: }
372: }
373:
374: void _device_CaptureComplete(NikonDevice sender, int data)
375: {
376: // Signal the the capture completed
377: _waitForCaptureComplete.Set();
378: }
379:
380: void manager_DeviceAdded(NikonManager sender, NikonDevice device)
381: {
382: if (_device == null)
383: {
384: // Save device
385: this._device = device;
386: device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_SaveMedia, (uint)eNkMAIDSaveMedia.kNkMAIDSaveMedia_Card);
387:
388: // Signal that we got a device
389: _waitForDevice.Set();
390: }
391: }
392: }
393:
394:
395: class Program
396: {
397: static void Main(string[] args)
398: {
399: DemoCapture demo = new DemoCapture();
400: demo.Run();
401: }
402: }
403: }