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

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

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

プログラムの稼働の下準備と稼働…しかし自己責任にて!!

 Nikon SDK C# Wrapperはココからダウンロードしました。
 demo_continuouscaptureのソースを開き、私の書いたプログラムを貼り付けます。
 私の書いたプログラムはココからダウンロード可能です。
 うまくコンパイル出来たら、ニコンZ6のSDKからNkdPTP.dll, Type0024.md3をEXEファイルと同じフォルダに入れます。
 Windows アクセサリのメモ帳等で第二接触・食の最大・第三接触の時刻を書き込んだ"TimeTable.txt"を作成し、EXEファイルと同じフォルダに入れます。時刻の記載方法は1時刻1行ずつ、12時12分12秒=121212のように、3行で書きます。

 例えば、
  C2:13時41分02秒
  食最大:13時41分32秒
  C3:13時42分02秒
 ならば、
  
 の様なテキストファイルになります。

 フォルダ内はこんな感じになります。
 後は.EXEをダブルクリックするのみです。
  

 カメラの設定でシャッター速度とISO感度の設定を1/2EVステップに設定します。
 後は.exeファイルをダブルクリックするだけ。
 起動するとコンソールが開き、通信が確立したときに4コマ撮影、のち上述の撮影シーケンスに沿って撮影をして行きます。
 問題が発生するとプログラムは終了し、コンソールが閉じます。

 ちなみに私はどうやら手にしたZ6に不良でもあったらしく、そこをSDKが直撃したか、スイッチオフでもバッテリが2日程でなくなるという不具合に見舞われました。幸い保証期間中だったのでメイン基板交換が無料でした。
 そんな訳で、このプログラム・Wrapper・SDKでカメラを壊し、或いは多大な損失を被っても当局は感知しない。健闘を祈る
 ココではZ6用のプログラムと設定を提示しています。本番ではZ6IIを使用する予定であり、その時このプログラムはそのまま使えると思いますが、.md3ファイルの型番が違ってきます。
   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:  // This demo shows how to perform continuous capture and store the images to disk
  21:  //
  22:   
  23:  namespace demo_continuouscapture
  24:  {
  25:  class DemoContinuousCapture
  26:      {
  27:  int _captureCount = 0;
  28:   
  29:          NikonDevice _device;
  30:          AutoResetEvent _waitForDevice = new AutoResetEvent(false);
  31:          AutoResetEvent _waitForCaptureComplete = new AutoResetEvent(false);
  32:   
  33:  publicvoid Run()
  34:          {
  35:   
  36:  string C2str = "", C3str = "", Cmaxstr = "";
  37:  string line = "";
  38:  int i;
  39:  
  40:  //日食の諸元を"TimeTable.txt"から取り入れる
  41:  using (StreamReader sr = newStreamReader(
  42:  "TimeTable.txt", Encoding.GetEncoding("UTF-8")))
  43:              {
  44:                  i = 1;
  45:  while ((line = sr.ReadLine()) != null)
  46:                  {
  47:  if (i == 1)
  48:                      {
  49:                          C2str = line;
  50:                      }
  51:  elseif (i == 2)
  52:                      {
  53:                          Cmaxstr = line;
  54:                      }
  55:  elseif (i == 3)
  56:                      {
  57:                          C3str = line;
  58:                      }
  59:                      i++;
  60:                  }
  61:              }
  62:   
  63:  //6桁(hhmmss形式)で示した時刻を分解する
  64:  int C2h = int.Parse(C2str.Substring(0, 2));
  65:  int C2m = int.Parse(C2str.Substring(2, 2));
  66:  int C2s = int.Parse(C2str.Substring(4, 2));
  67:  int Cmaxh = int.Parse(Cmaxstr.Substring(0, 2));
  68:  int Cmaxm = int.Parse(Cmaxstr.Substring(2, 2));
  69:  int Cmaxs = int.Parse(Cmaxstr.Substring(4, 2));
  70:  int C3h = int.Parse(C3str.Substring(0, 2));
  71:  int C3m = int.Parse(C3str.Substring(2, 2));
  72:  int C3s = int.Parse(C3str.Substring(4, 2));
  73:   
  74:  //秒に変換する
  75:  int C2 = C2h * 3600 + C2m * 60 + C2s;
  76:  int Cmax = Cmaxh * 3600 + Cmaxm * 60 + Cmaxs;
  77:  int C3 = C3h * 3600 + C3m * 60 + C3s;
  78:  
  79:  try
  80:              {
  81:  // Create manager object - make sure you have the correct MD3 file for your Nikon DSLR
  82:  //Type00##.md3の##が機種によって違う
  83:                  NikonManager manager = new NikonManager("Type0024.md3");
  84:  // Listen for the 'DeviceAdded' event
  85:                  manager.DeviceAdded += manager_DeviceAdded;
  86:  // Wait for a device to arrive
  87:                  _waitForDevice.WaitOne();
  88:  // 接続確認
  89:  _ = Interval_Capture(); 
  90:   
  91:  while (true)
  92:                  {
  93:  //現時刻(秒変換済み)を得る
  94:  int NowTime = Now();
  95:   
  96:  //時刻によりする動作を割りふる
  97:  //食最大の120秒より前で食最大の-120×n秒前の時
  98:  if (NowTime < Cmax - 121 && (Cmax - NowTime) % 120 == 0)
  99:                      {
 100:  //1.5EV間隔4段ブラケティング撮像
 101:                          _ = Interval_Capture();
 102:                      }
 103:  //食最大の120秒以内でC2の10秒前の時
 104:  elseif (NowTime > Cmax - 120 && NowTime == C2 - 10)
 105:                      {
 106:  //連写指示のビープ音&連写終了待ち
 107:  Console.Beep(500, 300);
 108:                          System.Threading.Thread.Sleep(19000);
 109:                      }
 110:  //C2とC3の間の時
 111:  elseif (NowTime > C2 && NowTime < C3)
 112:                      {
 113:  //多段階AEブラケティング
 114:                          _ = AEBlacket_Capture( C3 );
 115:   
 116:  //連写指示のビープ音&連写終了待ち
 117:  Console.Beep(500, 300);
 118:                          System.Threading.Thread.Sleep(19000);
 119:                      }
 120:  //C3の後の時
 121:  elseif (NowTime > C3 && (NowTime - Cmax) % 120 == 0)
 122:                      {
 123:  //1.5EV間隔4段ブラケティング撮像
 124:                          _ = Interval_Capture();
 125:                      }
 126:   
 127:                      System.Threading.Thread.Sleep(250);
 128:   
 129:                  }
 130:   
 131:  // Shutdown
 132:                  manager.Shutdown();
 133:              }
 134:  catch (NikonException ex)
 135:              {
 136:  Console.WriteLine(ex.Message);
 137:              }
 138:          }
 139:  staticint Now()
 140:          {
 141:  //現時刻を得て秒に直して送り返す
 142:  DateTime dt = DateTime.Now;
 143:  int hour = dt.Hour;
 144:  int minute = dt.Minute;
 145:  int second = dt.Second;
 146:  int x = hour * 3600 + minute * 60 + second;
 147:  return x;
 148:          }
 149:   
 150:  //2分毎の1.5EV step 4段階撮像
 151:  publicint Interval_Capture()
 152:          {
 153:  //Set Sensitivity 400
 154:              NikonEnum ISOSens = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity);
 155:              ISOSens.Index = 6;
 156:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 157:   
 158:              NikonEnum SpeedMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
 159:   
 160:  //1/3000-1/125sec 1.5EV間隔4段AEブラケティング撮影
 161:  int i = 0;
 162:  for (i = 36; i >= 27; i = i - 3)
 163:              {
 164:  //シャッター速度を指定
 165:                  SpeedMode.Index = i;
 166:                  _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 167:   
 168:  // Set number of continuous captures - in this case we want 1
 169:                  _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 170:   
 171:  // Hook up capture events
 172:                  _device.ImageReady += _device_ImageReady;
 173:                  _device.CaptureComplete += _device_CaptureComplete;
 174:   
 175:  // Capture
 176:                  _device.Capture();
 177:   
 178:  // Wait for the capture to complete
 179:                  _waitForCaptureComplete.WaitOne();
 180:   
 181:  // 時間調整
 182:                  System.Threading.Thread.Sleep(250);
 183:              }
 184:   
 185:  //set SS 1/500
 186:              SpeedMode.Index = 31;
 187:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 188:  
 189:  // Set shooting mode to 'continuous, highspeed'
 190:              NikonEnum shootingMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode);
 191:              shootingMode.Index = (int)eNkMAIDShootingMode.kNkMAIDShootingMode_CH;
 192:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode, shootingMode);
 193:   
 194:  return 0;
 195:          }
 196:   
 197:  //多段階AEブラケティング撮像
 198:  publicint AEBlacket_Capture( int C3 )
 199:          {
 200:  // Set shooting mode to 'continuous, highspeed'
 201:              NikonEnum shootingMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode);
 202:              shootingMode.Index = (int)eNkMAIDShootingMode.kNkMAIDShootingMode_CH;
 203:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShootingMode, shootingMode);
 204:   
 205:  //Set Sesitivity 1600
 206:              NikonEnum ISOSens = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity);
 207:              ISOSens.Index = 10;
 208:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 209:   
 210:  int i = 0;
 211:   
 212:              NikonEnum SpeedMode = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);
 213:   
 214:  // SS1/2秒で地球照を撮像
 215:              SpeedMode.Index = 15;
 216:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 217:              _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 218:              _device.ImageReady += _device_ImageReady;
 219:              _device.CaptureComplete += _device_CaptureComplete;
 220:              _device.Capture();
 221:              _waitForCaptureComplete.WaitOne();
 222:              System.Threading.Thread.Sleep(250);
 223:   
 224:  //Set Sesitivity 400
 225:              ISOSens.Index = 6;
 226:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 227:   
 228:   
 229:  while (true)
 230:              {
 231:  // SS 1/3000 - 1/2sec, 1.5EV step, 8段で多段階撮像する
 232:  for (i = 36; i >= 15; i = i - 3)
 233:                  {
 234:                      SpeedMode.Index = i;
 235:                      _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 236:   
 237:  // Set number of continuous captures - in this case we want 1
 238:                      _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 239:   
 240:  // Hook up capture events
 241:                      _device.ImageReady += _device_ImageReady;
 242:                      _device.CaptureComplete += _device_CaptureComplete;
 243:   
 244:  // Capture
 245:                      _device.Capture();
 246:   
 247:  // Wait for the capture to complete
 248:                      _waitForCaptureComplete.WaitOne();
 249:   
 250:  // 時間調整
 251:                      System.Threading.Thread.Sleep(250);
 252:                  }
 253:  // 時刻をピックアップして次の連写に行けるかを判断、16秒以内ならC3用連写
 254:  int NowTime = Now();
 255:  if (NowTime > C3 - 10)
 256:                  {
 257:  break;
 258:                  }
 259:              }
 260:   
 261:  // SS1/2秒で地球照を撮像
 262:   
 263:   
 264:  //Set Sesitivity 1600
 265:              ISOSens.Index = 10;
 266:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 267:   
 268:              SpeedMode.Index = 15;
 269:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 270:              _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);
 271:              _device.ImageReady += _device_ImageReady;
 272:              _device.CaptureComplete += _device_CaptureComplete;
 273:              _device.Capture();
 274:              _waitForCaptureComplete.WaitOne();
 275:              System.Threading.Thread.Sleep(250);
 276:   
 277:  //ダイヤモンドリング撮像の下準備
 278:  //set SS 1/500
 279:              SpeedMode.Index = 31;
 280:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, SpeedMode);
 281:   
 282:  //Set Sensitivity 100
 283:              ISOSens.Index = 2;
 284:              _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_Sensitivity, ISOSens);
 285:   
 286:  return 0;
 287:          }
 288:   
 289:   
 290:  void _device_ImageReady(NikonDevice sender, NikonImage image)
 291:          {
 292:  // Save captured image to disk
 293:  string filename = "image" + _captureCount.ToString() + ((image.Type == NikonImageType.Jpeg) ? ".jpg" : ".nef");
 294:              _captureCount++;
 295:   
 296:  using (FileStream s = newFileStream(filename, FileMode.Create, FileAccess.Write))
 297:              {
 298:                  s.Write(image.Buffer, 0, image.Buffer.Length);
 299:              }
 300:          }
 301:   
 302:  void _device_CaptureComplete(NikonDevice sender, int data)
 303:          {
 304:  // Signal the the capture completed
 305:              _waitForCaptureComplete.Set();
 306:          }
 307:   
 308:  void manager_DeviceAdded(NikonManager sender, NikonDevice device)
 309:          {
 310:  if (_device == null)
 311:              {
 312:  // Save device
 313:                  _device = device;
 314:   
 315:  // Signal that we got a device
 316:                  _waitForDevice.Set();
 317:              }
 318:          }
 319:      }
 320:   
 321:  class Program
 322:      {
 323:  staticvoid Main(string[] args)
 324:          {
 325:              DemoContinuousCapture demo = new DemoContinuousCapture();
 326:              demo.Run();
 327:          }
 328:      }
 329:  }
inserted by FC2 system