
問題の声明
自動光学エリプソメーターで実験の準備と実施を管理するためのソフトウェアを開発する。
ソフトウェアは機会を提供する必要があります
- 初期設定と実験パラメータの設定。
- サンプルの光学特性の測定を行う。
- プライマリデータセット[データセットI(α)の固定波長λおよびI(α)の固定(一定)値の特定の波長範囲λmin≤λ≤λmax(αはアナライザの方位角)またはI(λ)配列アナライザーの固定方位角α1、α2、α3、...αn];
- 配列I(α)またはI(λ)を処理して光学定数を計算する。
- 定常状態の信号レベルを測定するための、スペクトルの特定のポイントでの測定前の露出時間またはアナライザーの方位の制御、および信号を「累積」するためのスペクトルの特定のポイントでの「持続」時間(方位)。
- 測定データの視覚化。
- データをファイルに保存します。
実験
測定プロセス中、プログラムは2次元スキャンを実行してステッパードライブを制御する必要があります。 最小スキャン手順は、インストールオプションによって異なります。 範囲ごとのポイント数は、範囲のサイズとスキャンステップによって決まります。
実験パラメータ(測定範囲、スキャンステップ)は、測定中に変化しません。 スキャンは段階的に個別に行われます。
測定は、ドライブが停止しているときにのみ実行されます。 測定が実行された後、次のステップに移動コマンドが与えられ、搬送移動が実行されます。 PMTの電圧は PWMを使用して調整されます。
ソフトウェア
プログラミング言語として、C#を選択しました。これは、USB、COMポート、Microsoft Officeのネイティブサポートなどを操作するための多くの便利な機能を備えているためです。
したがって、データを受信し、マイクロコントローラーにコマンドを送信するには、仮想COMポートを使用します。
コード
// Open ADC Com private void buttonADC_Click(object sender, EventArgs e) { String s = ""; if (comboBox1.Text != "") { s += comboBox1.Text; } try { hPort = PACNET.UART.Open(s + ",9600,N,8,1"); Log.Items.Add(" "); buttonADC.Enabled = false; comboBox1.Enabled = false; } catch { MessageBox.Show(" " + serialPort1.PortName + " !", "!", MessageBoxButtons.OK, MessageBoxIcon.Warning); Log.Item.add(" !"); } }
アナログ信号を変換するために、 ICP Dasの 16ビットADCを使用しました。公式WebサイトにはSDKがあるため、ADCからのデータの読み取りは簡単です。
コード
float readSequenceADC(int iChannel, int iterations) { float result = 0; for (int i = 0; i < iterations; i++) { result += readADC(iChannel); Thread.Sleep(150); } result /= iterations; return result; }
光学定数を計算する少しの数学:
コード
public void count(float a, float b, float c) { double x = a; double y = b; double z = c; double ksi = Math.Atan(Math.Sqrt(x / z)); double delta = Math.Acos((x + z - 2 * y) / (2 * Math.Sqrt(x * z))); double denominator = Math.Pow((1 - Math.Sin(2 * ksi) * Math.Cos(delta)), 2); double numerator = Math.Pow(Math.Sin(phi), 2) * Math.Pow(Math.Tan(phi), 2) * Math.Sin(2 * ksi) * Math.Cos(2 * ksi) * Math.Sin(delta); double nk = numerator / denominator; double numerator1 = Math.Pow(Math.Cos(2 * ksi), 2) - Math.Pow(Math.Sin(2 * ksi), 2) * Math.Pow(Math.Sin(delta), 2); double nk2 = Math.Pow(Math.Sin(phi), 2) + (Math.Pow(Math.Sin(phi), 2) * Math.Pow(Math.Tan(phi), 2) * (numerator1 / denominator)); double x1 = 0; double x2 = 0; double D = nk2 * nk2 - 4 * ((-1) * nk * nk); if (D < 0) { x1 = 0; x2 = 0; } else if (D == 0) { x1 = -nk2 / 2; x2 = -nk2 / 2; } else if (D > 0) { x1 = (-nk2 + Math.Sqrt(D)) / 2; x2 = (-nk2 - Math.Sqrt(D)) / 2; } if (x1 < 0 && x2 < 0) { // "X1, x2 < 0" } else if (x1 > 0) { k = Math.Sqrt(x1); } else if (x2 > 0) { k = Math.Sqrt(x2); } n = Math.Sqrt(nk2 + k * k); }
「ゼロ」信号のドリフトを決定する機能:
コード
// Intensity Drifting Check private void Worker3() { while (isWorking == true) { try { for (int i = 0; i < 1000; i++) { Thread.Sleep(200); I = readADC(3); Intensity.Add(I); this.Invoke((MethodInvoker)(() => Log.Items.Add("I = " + I))); DrawGraph(i, I, 0); } PrintExel.ExportText(Intensity); ClearGraph(); isWorking = false; } catch (Exception e) { MessageBox.Show("Error:\n" + e.Message); } } }
光電子増倍管は非常に非線形であるため、スペクトルのさまざまな部分で感度が異なり、一定の信号を設定された制限内に維持する必要があります(測定では、これは300から850 mVの範囲で、最適な信号対雑音比です):

コード
private void maxControl() { double val = 1; while (val > 0.85) { this.radRadialGauge1.Value -= 7; serialPort1.Write("decrease"); val = Convert.ToInt32(Math.Abs(readADC(3))); Thread.Sleep(1000); } } private void minControl() { double val = 0; while (val < 0.4) // val < 300 { this.radRadialGauge1.Value += 7; serialPort1.Write("increase"); val = Convert.ToInt32(Math.Abs(readADC(3))); Thread.Sleep(1000); } }
データの可視化
測定結果をリアルタイムで表示することは、プロセスと実験の正確さを制御できるため、非常に重要なポイントです。 Habrの記事「.NETの グラフ作成 ツール」を分析して、ZedGraph を選択しました 。 無料、高速、シンプルでかなり機能的なライブラリ。

チャート機能
private void DrawGraph(int x, double n, double k) { GraphPane pane = zedGraphControl1.GraphPane; PointPairList listN = new PointPairList(); PointPairList listK = new PointPairList(); LineItem myCurve; listN.Add(x, n); listK.Add(x, k); myCurve = pane.AddCurve("", listN, Color.Blue, SymbolType.Default); myCurve = pane.AddCurve("", listK, Color.Red, SymbolType.Default); zedGraphControl1.AxisChange(); zedGraphControl1.Invalidate(); }
最後に、ファイルに保存します。
コード
public static void ExportToExcelIntensity(ArrayList arrLamda, ArrayList arrI0, ArrayList arrI45, ArrayList arrI90) { try { Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application(); excelApp.Visible = true; excelApp.Workbooks.Add(); Microsoft.Office.Interop.Excel.Worksheet workSheet = excelApp.ActiveSheet; workSheet.Cells[1, "A"] = "WaveLength"; workSheet.Cells[1, "B"] = "I0"; workSheet.Cells[1, "C"] = "I45"; workSheet.Cells[1, "D"] = "I90"; int row = 1; for (int i = 0; i < arrLamda.Count; i++) { row++; workSheet.Cells[row, "A"] = arrLamda[i]; workSheet.Cells[row, "B"] = arrI0[i]; workSheet.Cells[row, "C"] = arrI45[i]; workSheet.Cells[row, "D"] = arrI90[i]; } workSheet.Range["A1"].AutoFormat(Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2); excelApp.DisplayAlerts = false; workSheet.SaveAs(string.Format(@"{0}\OpticalIntensities.xlsx", Environment.CurrentDirectory)); excelApp.Quit(); } catch (Exception ex) { MessageBox.Show("Error:\n" + ex.Message); } }
まとめ
WinFormsに基づいて実験室測定を自動化するために設計されたハードウェアとソフトウェアの複合体が開発されました。 科学計算用にこの特定のPLを選択することのパフォーマンスと関連性を犠牲にして、 記事を参照してください 。
PSこれは制御ハードウェアの一部の外観です。これについては、次の記事で説明する予定です。
写真撮影
