Lab. of Voynich Code
2023年オーストラリア・インドネシア    金環皆既日食のたくらみ
光球面とコロナの明るさの比用システム
Windowsタブレットを使った制御:要素3
2022.02.28: Open : 2022.03.04 Update

Nikon SDK C# Wrapperを使ったメインのコンソールアプリの改造版

 プログラムのシーケンス
  • テキストファイルから第二接触(C2)・食の最大・第三接触(C3)の時刻を読み込む
  • 読み込んだ時刻と現時刻を比較し
    1. 起動時に太陽面の明るさ測定用1.5EV間隔で3段の撮影
    2. Cmaxの120秒前かつCmaxと現時刻の差が60秒であるとき、 1.5EV間隔で3段の撮影
    3. C2の10秒前に音信号発信・コントローラーで18秒連写
    4. 19秒待って地球照撮影
    5. 1.5EV間隔で8段のAEB撮影を行いつつ、現時刻がC3の9秒前になるまで撮影
    6. C3の前9秒になったら5.を終了し、地球照撮影
    7. 6.が終了し次第、音信号発信・コントローラーで18秒連写
    8. C3の後、 Cmaxと現時刻の差がn×60秒の時、1.5EV間隔で3段の撮影
    を選んで実行する

プログラムの設定方法…しかし自己責任にて!!

  • Nikon SDK C# Wrapperはココからダウンロードしました。
  • demo_continuouscaptureのソースを開き、私の書いたプログラムを置き換える形で貼り付けます。
  • コンパイル出来たら、ニコンZ6のSDKからNkdPTP.dll, Type0024.md3をコンパイルしたEXEファイルと同じフォルダに入れます。
  • カメラのシャッター速度・ISO感度は1/2EVステップに設定します。
  • 後はNikon Z6をPCとUSB接続して.exeファイルをダブルクリックで動くかどうかをチェックします。

更新記録

  • 2022.03.04
     稼働試験で、C3前に多段階露光を抜けてから音信号発信まで(地球照を撮影しダイヤモンドリング撮影の準備をす間)に5秒くらいかかっているので、多段階露光を抜ける時刻をC3の9秒前から14秒前に設定を変更しました。
    ・このために249行を while (NowTime <= C3 - 9) ⇒ while (NowTime <= C3 - 14) に変更しました。
   1:  //
   2:  // This work is licensed under a Creative Commons Attribution 3.0 Unported License.
   3:  // Thomas Dideriksen (thomas@dideriksen.com)
   4:  //
   5:  // Modified by M_shi@Lab. of Eclips Manuscript
   6:  // http://horukeu.web.fc2.com/Exp/2023Trial/Index.html
   7:  //
   8:  //
   9:  //
  10:   
  11:  using System;
  12:  using System.Collections.Generic;
  13:  using System.Linq;
  14:  using System.Text;
  15:  using System.Threading;
  16:  using System.IO;
  17:  using Nikon;
  18:   
  19:   
  20:   
  21:  namespace demo_continuouscapture
  22:  {
  23:      class DemoContinuousCapture
  24:      {
  25:          int _captureCount = 0;
  26:   
  27:          NikonDevice _device;
  28:          AutoResetEvent _waitForDevice = new AutoResetEvent(false);
  29:          AutoResetEvent _waitForCaptureComplete = new AutoResetEvent(false);
  30:   
  31:          public void Run()
  32:          {
  33:   
  34:              string C2str = "", C3str = "", Cmaxstr = "";
  35:              string line = "";
  36:              int i;
  37:   
  38:              //日食の諸元を"TimeTable.txt"から取り入れる
  39:              using (StreamReader sr = new StreamReader(
  40:                  "TimeTable.txt", Encoding.GetEncoding("UTF-8")))
  41:              {
  42:                  i = 1;
  43:                  while ((line = sr.ReadLine()) != null)
  44:                  {
  45:                      if (i == 1)
  46:                      {
  47:                          C2str = line;
  48:                      }
  49:                      else if (i == 2)
  50:                      {
  51:                          Cmaxstr = line;
  52:                      }
  53:                      else if (i == 3)
  54:                      {
  55:                          C3str = line;
  56:                      }
  57:                      i++;
  58:                  }
  59:              }
  60:   
  61:              //6桁(hhmmss形式)で示した時刻を分解する
  62:              int C2h = int.Parse(C2str.Substring(0, 2));
  63:              int C2m = int.Parse(C2str.Substring(2, 2));
  64:              int C2s = int.Parse(C2str.Substring(4, 2));
  65:              int Cmaxh = int.Parse(Cmaxstr.Substring(0, 2));
  66:              int Cmaxm = int.Parse(Cmaxstr.Substring(2, 2));
  67:              int Cmaxs = int.Parse(Cmaxstr.Substring(4, 2));
  68:              int C3h = int.Parse(C3str.Substring(0, 2));
  69:              int C3m = int.Parse(C3str.Substring(2, 2));
  70:              int C3s = int.Parse(C3str.Substring(4, 2));
  71:   
  72:              //秒に変換する
  73:              int C2 = C2h * 3600 + C2m * 60 + C2s;
  74:              int Cmax = Cmaxh * 3600 + Cmaxm * 60 + Cmaxs;
  75:              int C3 = C3h * 3600 + C3m * 60 + C3s;
  76:   
  77:              try
  78:              {
  79:                  // Create manager object - make sure you have the correct MD3 file for your Nikon DSLR
  80:                  //Type00##.md3の##が機種によって違う
  81:                  NikonManager manager = new NikonManager("Type0024.md3");
  82:   
  83:                  // Listen for the 'DeviceAdded' event
  84:                  manager.DeviceAdded += manager_DeviceAdded;
  85:   
  86:                  // Wait for a device to arrive
  87:                  _waitForDevice.WaitOne();
  88:   
  89:                  // 接続確認
  90:                  _ = Interval_Capture();
  91:   
  92:                  while (true)
  93:                  {
  94:                      //現時刻(秒変換済み)を得る
  95:                      int NowTime = Now();
  96:   
  97:                      //時刻によりする動作を割りふる
  98:                      //食最大の120秒より前で食最大の-60×n秒前の時
  99:                      if (NowTime <= Cmax - 120 && (Cmax - NowTime) % 60 == 0)
 100:                      {
 101:                          //1.5EV間隔4段ブラケティング撮像
 102:                          Console.WriteLine(DateTime.Now + " 毎分多段撮像");
 103:                          _ = Interval_Capture();
 104:                      }
 105:                      //食最大の120秒以内でC2の10秒前の時
 106:                      else if (NowTime > Cmax - 120 && NowTime == C2 - 10)
 107:                      {
 108:                          //連写指示のビープ音&連写終了待ち
 109:                          Console.WriteLine(DateTime.Now + " C2 連写開始");
 110:                          Console.Beep(2000, 500);
 111:                          System.Threading.Thread.Sleep(18500);
 112:                          Console.WriteLine(DateTime.Now + " C2 連写終了");
 113:                      }
 114:                      //C2とC3の間の時
 115:                      else if (NowTime > C2 && NowTime < C3)
 116:                      {
 117:                          //多段階AEブラケティング
 118:                          Console.WriteLine(DateTime.Now + " 多段撮像開始");
 119:                          Console.WriteLine(NowTime);
 120:                          _ = AEBlacket_Capture(C3);
 121:                          Console.WriteLine(DateTime.Now + " 多段撮像終了");
 122:                          Console.WriteLine(NowTime);
 123:                          //連写指示のビープ音&連写終了待ち
 124:                          Console.WriteLine(DateTime.Now + " C3 連写開始");
 125:                          Console.WriteLine(NowTime);
 126:                          Console.Beep(2000, 500);
 127:                          System.Threading.Thread.Sleep(18500);
 128:                          Console.WriteLine(DateTime.Now + " C3 連写終了");
 129:                          Console.WriteLine(NowTime);
 130:                      }
 131:                      //C3の後の時
 132:                      else if (NowTime > C3 && (NowTime - Cmax) % 60 == 0)
 133:                      {
 134:                          //1.5EV間隔4段ブラケティング撮像
 135:                          Console.WriteLine(DateTime.Now + " 毎分多段撮像");
 136:                          _ = Interval_Capture();
 137:                      }
 138:   
 139:                      System.Threading.Thread.Sleep(100);
 140:   
 141:                  }
 142:   
 143:                  // Shutdown
 144:                  manager.Shutdown();
 145:              }
 146:              catch (NikonException ex)
 147:              {
 148:                  Console.WriteLine(ex.Message);
 149:              }
 150:          }
 151:          static int Now()
 152:          {
 153:              //現時刻を得て秒に直して送り返す
 154:              DateTime dt = DateTime.Now;
 155:              int hour = dt.Hour;
 156:              int minute = dt.Minute;
 157:              int second = dt.Second;
 158:              int x = hour * 3600 + minute * 60 + second;
 159:              return x;
 160:          }
 161:   
 162:          //太陽面1分毎:1.5EVステップ・3段
 163:          public int Interval_Capture()
 164:          {
 165:              //Set Sensitivity 400
 166:              NikonEnum ISOSens = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity);
 167:              ISOSens.Index = 6;
 168:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 169:   
 170:              NikonEnum SpeedMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
 171:   
 172:              //1/3000-1/125sec 1.5EV間隔4段AEブラケティング撮影
 173:              int i = 0;
 174:              for (i = 36; i >= 30; i = i - 3)
 175:              {
 176:                  //シャッター速度を指定
 177:                  SpeedMode.Index = i;
 178:                  _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 179:   
 180:                  // Set number of continuous captures - in this case we want 1
 181:                  _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 182:   
 183:                  // Hook up capture events
 184:                  _device.ImageReady += _device_ImageReady;
 185:                  _device.CaptureComplete += _device_CaptureComplete;
 186:   
 187:                  // Capture
 188:                  _device.Capture();
 189:   
 190:                  // Wait for the capture to complete
 191:                  _waitForCaptureComplete.WaitOne();
 192:   
 193:                  // 時間調整
 194:                  System.Threading.Thread.Sleep(200);
 195:              }
 196:   
 197:              //set SS 1/500
 198:              SpeedMode.Index = 31;
 199:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 200:   
 201:              //Set Sensitivity 100
 202:              ISOSens.Index = 2;
 203:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 204:   
 205:              // Set shooting mode to 'continuous, highspeed'
 206:              NikonEnum shootingMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode);
 207:              shootingMode.Index = (int)eNkMAIDShootingMode.kNkMAIDShootingMode_CH;
 208:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode, shootingMode);
 209:   
 210:              return 0;
 211:          }
 212:   
 213:          //皆既中のコロナの多段階AEブラケティング撮像:1.5EVステップ・8段
 214:          public int AEBlacket_Capture(int C3)
 215:          {
 216:              int NowTime;
 217:   
 218:              // Set shooting mode to 'continuous, highspeed'
 219:              NikonEnum shootingMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode);
 220:              shootingMode.Index = (int)eNkMAIDShootingMode.kNkMAIDShootingMode_CH;
 221:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode, shootingMode);
 222:   
 223:              //Set Sesitivity ISO1600
 224:              NikonEnum ISOSens = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity);
 225:              ISOSens.Index = 10;
 226:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 227:   
 228:              int i;
 229:              //Set shutter speed 1/2sec
 230:              NikonEnum SpeedMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
 231:   
 232:              // SS1/2秒で地球照を撮像
 233:              SpeedMode.Index = 15;
 234:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 235:              _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 236:              _device.ImageReady += _device_ImageReady;
 237:              _device.CaptureComplete += _device_CaptureComplete;
 238:              _device.Capture();
 239:              _waitForCaptureComplete.WaitOne();
 240:              System.Threading.Thread.Sleep(200);
 241:   
 242:              //Set Sesitivity 400
 243:              ISOSens.Index = 6;
 244:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 245:   
 246:              NowTime = Now();
 247:   
 248:              i = 0;
 249:              while (NowTime <= C3 - 14)
 250:              {
 251:                  if (i <= 14)
 252:                  {
 253:                      i = 36;
 254:                  }
 255:                  Console.WriteLine(DateTime.Now);
 256:                  SpeedMode.Index = i;
 257:                  _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 258:   
 259:                  // Set number of continuous captures - in this case we want 1
 260:                  _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 261:   
 262:                  // Hook up capture events
 263:                  _device.ImageReady += _device_ImageReady;
 264:                  _device.CaptureComplete += _device_CaptureComplete;
 265:   
 266:                  // Capture
 267:                  _device.Capture();
 268:   
 269:                  // Wait for the capture to complete
 270:                  _waitForCaptureComplete.WaitOne();
 271:   
 272:                  // 時間調整
 273:                  System.Threading.Thread.Sleep(200);
 274:   
 275:                  i = i - 3;
 276:                  
 277:                  NowTime = Now();
 278:              }
 279:   
 280:              // SS1/2秒で地球照を撮像
 281:   
 282:              //Set Sesitivity ISO1600
 283:              ISOSens.Index = 10;
 284:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 285:              //Set ShutterSpeed 1/2sec
 286:              SpeedMode.Index = 15;
 287:              //Capture
 288:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 289:              _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 290:              _device.ImageReady += _device_ImageReady;
 291:              _device.CaptureComplete += _device_CaptureComplete;
 292:              _device.Capture();
 293:              _waitForCaptureComplete.WaitOne();
 294:              System.Threading.Thread.Sleep(200);
 295:   
 296:              //ダイヤモンドリング撮像の下準備
 297:              //set SS 1/500
 298:              SpeedMode.Index = 31;
 299:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 300:   
 301:              //Set Sensitivity 100
 302:              ISOSens.Index = 2;
 303:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 304:   
 305:              return 0;
 306:          }
 307:   
 308:   
 309:          void _device_ImageReady(NikonDevice sender, NikonImage image)
 310:          {
 311:              // Save captured image to disk
 312:              string filename = "image" + _captureCount.ToString() + ((image.Type == NikonImageType.Jpeg) ? ".jpg" : ".nef");
 313:              _captureCount++;
 314:   
 315:              using (FileStream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
 316:              {
 317:                  s.Write(image.Buffer, 0, image.Buffer.Length);
 318:              }
 319:          }
 320:   
 321:          void _device_CaptureComplete(NikonDevice sender, int data)
 322:          {
 323:              // Signal the the capture completed
 324:              _waitForCaptureComplete.Set();
 325:          }
 326:   
 327:          void manager_DeviceAdded(NikonManager sender, NikonDevice device)
 328:          {
 329:              if (_device == null)
 330:              {
 331:                  // Save device
 332:                  _device = device;
 333:   
 334:                  // Signal that we got a device
 335:                  _waitForDevice.Set();
 336:              }
 337:          }
 338:      }
 339:   
 340:      class Program
 341:      {
 342:          static void Main(string[] args)
 343:          {
 344:              DemoContinuousCapture demo = new DemoContinuousCapture();
 345:              demo.Run();
 346:          }
 347:      }
 348:  }
inserted by FC2 system