本软件设计由B站up主'全糖奶茶屋'提供, 可以直接联系我们的客服. 我们收到信息后会将问题在这里汇总. 大家也可以添加我们的人工客服微信: quantangnaichawu (如遇暂时加满了, 无法添加, 请后面再尝试).
可调谐激光器光谱分析与控制系统 V1.0 是一款专为激光器调谐与光谱分析设计的专业软件工具,致力于为科研实验、实验室研究及工业生产应用,提供高效精准的激光器控制与光谱数据处理能力。系统以模块化设计为核心,涵盖用户登录、参数设置、激光器扫描、光谱结果展示及报告导出等关键功能,支持灵活配置与高效数据处理,可全面满足不同场景下的激光器光谱分析需求。
一、用户登录与注册模块
登录验证:为系统安全提供核心保障,用户需通过有效用户名和密码完成身份验证,方可访问核心功能。该设计确保了系统使用的安全性,便于实验室、科研机构等场景下的用户权限管理,防止未授权操作。
用户注册:支持新用户创建专属账户,流程简便高效,可快速完成用户数据库的扩充与管理。用户通过注册模块建立账户后,即可随时开展激光器参数调控与光谱数据分析工作,满足多用户协作场景需求。
二、参数设置模块
用户可根据实际应用需求,对激光器运行参数与光谱分析参数进行精准配置,为后续扫描与数据采集奠定基础:
激光器参数:可设置目标波长、扫描速度、输出功率及功率阈值等关键参数,直接影响激光器的调谐精度与运行稳定性,适配不同实验对激光输出的个性化要求。
光谱分析参数:支持配置光谱分辨率、积分时间等参数,这些设置直接决定光谱数据的采集精度、信号稳定性,确保扫描结果符合实验预期标准。
三、激光器扫描模块
该模块依据用户预设参数,启动激光器开展光谱扫描工作:
通过精准的硬件控制逻辑,驱动激光器按设定目标波长逐步调整并发射激光束;
联动硬件感应器实时收集光谱数据,实现激光器控制与数据采集的同步进行,为后续分析提供真实、可靠的原始数据支撑;
支持与实际硬件设备无缝对接,确保扫描过程的实时性与准确性。
四、光谱结果展示与报告导出模块
结果分析与展示:对扫描采集的原始数据进行专业分析,计算并呈现带宽、信噪比等核心光谱特性指标,以直观的形式呈现数据结果,方便用户快速掌握光谱性能。
报告导出:支持将完整的分析结果导出为 TXT 格式报告,报告包含详细光谱数据与关键分析指标,便于用户保存归档、学术分享或进一步科研分析使用。
五、系统优势与适用场景
系统优势:采用模块化设计,各功能模块通过清晰的接口与逻辑调用协同工作,结构规整、扩展性强,便于后续功能升级与维护;操作流程简洁直观,兼顾专业性与易用性。
适用场景:广泛适配科研实验、实验室分析、工业生产检测等多种激光器调谐与光谱分析场景,为科研人员、工程师提供高效、精确的光谱分析与控制解决方案,是激光应用研究领域的得力工具。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NationalInstruments.Tdms;
using NationalInstruments.Analysis;
using NationalInstruments.Analysis.Conversion;
using NationalInstruments.Analysis.Dsp;
using NationalInstruments.Analysis.Dsp.Filters;
using NationalInstruments.Analysis.Math;
using NationalInstruments.Analysis.Monitoring;
using NationalInstruments.Analysis.SignalGeneration;
using NationalInstruments.Analysis.SpectralMeasurements;
using NationalInstruments;
using NationalInstruments.UI;
using NationalInstruments.UI.WindowsForms;
using System.IO.Ports;
using System.Threading;
namespace WindowsFormsApplication1
{
// 登录模块
public class LoginModule
{
private Dictionary usersDatabase;
public LoginModule()
{
usersDatabase = new Dictionary{
{ 'admin', 'password123' }
};
}
public bool ValidateLogin(string username, string password)
{
if (usersDatabase.ContainsKey(username) && usersDatabase[username] == password)
{
return true;
}
return false;
}
}
// 注册模块
public class RegisterModule
{
private Dictionary usersDatabase;
public RegisterModule()
{
usersDatabase = new Dictionary();
}
public bool Register(string username, string password)
{
if (!usersDatabase.ContainsKey(username))
{
usersDatabase.Add(username, password);
return true;
}
return false;
}
}
// 参数设置类
public class ParameterSettings
{
public double TargetWavelength { get; set; }
public double ScanSpeed { get; set; }
public double OutputPower { get; set; }
public double PowerThreshold { get; set; }
public double SpectrumResolution { get; set; }
public double IntegrationTime { get; set; }
public void SetLaserParameters(double wavelength, double speed, double power, double threshold)
{
TargetWavelength = wavelength;
ScanSpeed = speed;
OutputPower = power;
PowerThreshold = threshold;
}
public void SetSpectrumParameters(double resolution, double integrationTime)
{
SpectrumResolution = resolution;
IntegrationTime = integrationTime;
}
}
// 激光扫描类
public class LaserScanner
{
public void StartScan(ParameterSettings settings)
{
Console.WriteLine($'Starting scan at wavelength: {settings.TargetWavelength} nm, speed: {settings.ScanSpeed} nm/s');
System.Threading.Thread.Sleep(2000);
Console.WriteLine('Scan complete.');
}
}
// 光谱结果类
public class SpectrumResult
{
public double Bandwidth { get; set; }
public double SignalToNoiseRatio { get; set; }
public void DisplayResults()
{
Console.WriteLine($'Bandwidth: {Bandwidth} nm');
Console.WriteLine($'Signal-to-Noise Ratio: {SignalToNoiseRatio} dB');
}
public void ExportReport(string filePath)
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath))
{
sw.WriteLine($'Bandwidth: {Bandwidth} nm');
sw.WriteLine($'Signal-to-Noise Ratio: {SignalToNoiseRatio} dB');
}
}
}
// 光谱处理类
public class Spectral_processing
{
public double numericEdit1 { get; set; }
public double numericEdit2 { get; set; }
public double[] Sig1 { get; set; }
public double[] Sig2 { get; set; }
public double[] Sig3 { get; set; }
public double[] Sig4 { get; set; }
public void ReadTdmsFile()
{
// 需根据实际需求实现TDMS文件读取逻辑
}
public void ProcessData(out double[] x, out double[] y)
{
// 光谱数据处理逻辑,此处为占位实现
x = new double[] { };
y = new double[] { };
}
}
// AD卡操作相关类(文档中未完整实现,保留占位)
public class Art1
{
public IntPtr taskHandle = IntPtr.Zero;
public bool ConfigDone { get; set; }
public bool InitOK { get; set; }
public int ART_SPChanCount { get; set; }
public double ART_SPFrequency { get; set; }
public UInt32 ART_SPNumPerCH { get; set; }
public int ART_SPDelay { get; set; }
public int ART_FreqDivision { get; set; }
public int CH1_AC_DC { get; set; }
public int CH2_AC_DC { get; set; }
public int CH3_AC_DC { get; set; }
public int CH4_AC_DC { get; set; }
public int CH1_Range { get; set; }
public int CH2_Range { get; set; }
public int CH3_Range { get; set; }
public int CH4_Range { get; set; }
public int ART_TriggerDir { get; set; }
public string ART_TrigSrcSel { get; set; }
public float ART_TriggerLevel { get; set; }
public int ART_TriggerSens { get; set; }
public double[] Chan1 { get; set; }
public double[] Chan2 { get; set; }
public double[] Chan3 { get; set; }
public double[] Chan4 { get; set; }
public void ReleaseAD() { }
public void ReleaseAD(int param) { }
public void InitADCard(ref IntPtr handle) { }
public void ConfigParmIntClkSoftTrig() { }
public void ConfigParmIntClkVolTrig() { }
public void ConfigParmExtClkSoftTrig() { }
public void ConfigParmExtClkVolTrig() { }
public void ConfigART() { }
public void IntTask() { }
public int FinSample() { return 0; }
public void StopAcquisition() { }
}
// 全局变量类
public static class GlobalVariables
{
public static string output = '';
public static byte[] VersionArray = new byte[4] { 00, 00, 00, 00 };
public static int combinedValue2 = 0;
public static int lastcombinedValue2 = 0;
public static int lastselectindex = 0;
}
// 主窗口类
public partial class Form1 : Form
{
private VScrollBar vScrollBar;
private Panel contentPanel;
private BackgroundWorker backgroundWorker;
private SerialPort serialPort1 = new SerialPort();
private bool TimerOpen = false;
private bool _receivedC1 = false;
private bool isReadPressed = false;
private Art1 Art1 = new Art1();
private string FileName = '';
// 界面控件(文档中未显式定义,按代码引用补充)
private ComboBox ClockSel, TrigSrc, TrigDir, Range1, Range2, Range3, Range4, SetParameters, Speed;
private NumericUpDown SPAmount, TrigVal, SPrate, numericEdit1, numericEdit2;
private TextBox ScanStart1, ScanEnd1, Fixed1, ScanStart2, ScanEnd2, Fixed2, SerialNumber, VersionNumber, Box, StepSize, XPOS, YPOS;
private Button OpenSerialPort, CloseSerialPort, Read, ScanSetting, SpeedSetting, SingleScan, ContinueScan, StopScan, FrequencySetting, Clean, XY_Auto, CurMode, ZoomMode, MoveMode, ConfigDAQ, SamplingOnce, SaveDAQ, Repeat, SaveFileTDMS, getTDMSdata, SpectralProcessing;
private CheckBox CH1Couple, CH2Couple, CH3Couple, CH4Couple, checkBox1, checkBox2, checkBox3, checkBox4;
private WaveformGraph waveformGraph1;
private ScatterGraph scatterGraph1;
private WaveformPlot waveformPlot1, waveformPlot2, waveformPlot3, waveformPlot4;
private ScatterPlot scatterPlot1;
private XYCursor xyCursor1;
private Timer timer1 = new Timer();
public Form1()
{
InitializeComponent();
ClockSel.SelectedIndex = 0;
TrigSrc.SelectedIndex = 0;
TrigDir.SelectedIndex = 0;
Range1.SelectedIndex = 0;
Range2.SelectedIndex = 0;
Range3.SelectedIndex = 0;
Range4.SelectedIndex = 0;
SPAmount.Value = 40 * 1000 * 1000;
TrigVal.Value = 1.5m;
SPrate.Value = 40 * 1000 * 1000;
TimerOpen = false;
numericEdit1.Value = Math.Round(double.Parse(ScanStart2.Text), 1);
numericEdit2.Value = Math.Round(double.Parse(ScanEnd2.Text), 1);
Control.CheckForIllegalCrossThreadCalls = false;
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
this.AutoScroll = true;
scatterGraph1.XAxes[0].Range = new Range(numericEdit1.Value, numericEdit2.Value);
vScrollBar = new VScrollBar
{
Location = new System.Drawing.Point(10, 10),
Size = new System.Drawing.Size(20, this.ClientSize.Height - 20),
Minimum = 0,
Maximum = 100,
Value = 0,
LargeChange = 10,
SmallChange = 1
};
vScrollBar.Scroll += VScrollBar_Scroll;
contentPanel = new Panel
{
Location = new System.Drawing.Point(40, 10),
Size = new System.Drawing.Size(this.ClientSize.Width - 50, this.ClientSize.Height - 20),
AutoScroll = true
};
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = false;
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
ScanStart2.ReadOnly = true;
ScanEnd2.ReadOnly = true;
Fixed2.ReadOnly = true;
SerialNumber.ReadOnly = true;
VersionNumber.ReadOnly = true;
}
private void VScrollBar_Scroll(object sender, ScrollEventArgs e)
{
contentPanel.VerticalScroll.Value = vScrollBar.Value;
}
private void OpenSerialPort_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = SelectSerialPort.Text;
serialPort1.BaudRate = Convert.ToInt32(SelectBaudRate.Text, 10);
serialPort1.Open();
OpenSerialPort.Enabled = false;
CloseSerialPort.Enabled = true;
Read.Enabled = true;
ScanSetting.Enabled = true;
SpeedSetting.Enabled = true;
SingleScan.Enabled = true;
ContinueScan.Enabled = true;
StopScan.Enabled = true;
FrequencySetting.Enabled = true;
SerialNumber.Enabled = true;
VersionNumber.Enabled = true;
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 串口打开成功!' + Environment.NewLine + Box.Text;
}
catch
{
MessageBox.Show('端口错误,请检查串口', '错误');
}
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
while (serialPort1.BytesToRead > 0)
{
byte[] buffer = new byte[serialPort1.BytesToRead];
int bytesRead = serialPort1.Read(buffer, 0, buffer.Length);
List validBytes = new List();
foreach (byte b in buffer)
{
if (b != 0x20)
{
validBytes.Add(b);
}
}
if (validBytes.Count > 4)
{
validBytes = validBytes.GetRange(0, 4);
}
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
string output1 = formattedTime + ' 接收';
foreach (byte b in validBytes)
{
string hexString = Convert.ToString(b, 16).ToLower().PadLeft(2, '0');
GlobalVariables.output += hexString + ' ';
}
while (validBytes.Count
{
output1 = output1 + GlobalVariables.output;
Box.Text = output1 + Environment.NewLine + Box.Text;
}));
}
else
{
Box.Text = output1 + Environment.NewLine + Box.Text;
}
byte[] byteArray = GlobalVariables.output.Trim().Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
try
{
if (isReadPressed)
{
if (byteArray[1] == 0xc3)
{
int combinedValue1 = (byteArray[2] <
{
VersionNumber.Text = 'V' + roundedValue.ToString('F1');
}));
}
else
{
VersionNumber.Text = 'V' + roundedValue.ToString('F1');
}
}
if (byteArray[1] == 0xC1)
{
_receivedC1 = true;
GlobalVariables.VersionArray[0] = byteArray[2];
GlobalVariables.VersionArray[1] = byteArray[3];
GlobalVariables.combinedValue2 = GlobalVariables.lastcombinedValue2;
}
else if (byteArray[1] == 0xC2)
{
GlobalVariables.VersionArray[2] = byteArray[2];
GlobalVariables.VersionArray[3] = byteArray[3];
if (_receivedC1)
{
GlobalVariables.combinedValue2 = (GlobalVariables.VersionArray[0] << 24) |
(GlobalVariables.VersionArray[1] << 16) |
(GlobalVariables.VersionArray[2] << 8) |
GlobalVariables.VersionArray[3];
_receivedC1 = false;
}
else
{
GlobalVariables.VersionArray[0] = 00;
GlobalVariables.VersionArray[1] = 00;
GlobalVariables.combinedValue2 = (GlobalVariables.VersionArray[0] << 24) |
(GlobalVariables.VersionArray[1] << 16) |
(GlobalVariables.VersionArray[2] <
{
SerialNumber.Text = GlobalVariables.combinedValue2.ToString();
}));
}
else
{
SerialNumber.Text = GlobalVariables.combinedValue2.ToString();
}
}
}
catch
{
GlobalVariables.output = '';
}
}
}
catch (TimeoutException)
{
Box.AppendText('Timeout occurred while reading data.\n');
}
}
private void CloseSerialPort_Click(object sender, EventArgs e)
{
try
{
serialPort1.Close();
OpenSerialPort.Enabled = true;
CloseSerialPort.Enabled = false;
Read.Enabled = false;
ScanSetting.Enabled = false;
SpeedSetting.Enabled = false;
SingleScan.Enabled = false;
ContinueScan.Enabled = false;
StopScan.Enabled = false;
FrequencySetting.Enabled = false;
SerialNumber.Enabled = false;
VersionNumber.Enabled = false;
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 串口关闭!' + Environment.NewLine + Box.Text;
}
catch
{
}
}
private void Read_Click(object sender, EventArgs e)
{
isReadPressed = true;
if (!backgroundWorker.IsBusy)
{
backgroundWorker.RunWorkerAsync('Read');
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
string operation = e.Argument.ToString();
if (operation == 'Read')
{
PerformReadOperation();
}
else if (operation == 'Scan')
{
PerformScanOperation();
}
else if (operation == 'Frequency')
{
PerformFrequencyOperation();
}
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show('发生错误:' + e.Error.Message);
}
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Box.Text = e.UserState.ToString() + Environment.NewLine + Box.Text;
}
private void PerformReadOperation()
{
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
string hexString1 = 'd0 c1 00 00';
string hexString2 = 'e0 c2 00 00';
string hexString3 = 'c0 c3 00 01';
Box.Text = formattedTime + ' 发出→' + hexString1 + Environment.NewLine + Box.Text;
SendHexStringArray(hexString1);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + hexString2 + Environment.NewLine + Box.Text;
SendHexStringArray(hexString2);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + hexString3 + Environment.NewLine + Box.Text;
SendHexStringArray(hexString3);
System.Threading.Thread.Sleep(1000);
}
private void PerformScanOperation()
{
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
string StartFrequency = '';
string EndFrequency = '';
int step = int.Parse(StepSize.Text);
string Step = FormatWithSpaces(step);
if (SetParameters.SelectedIndex == 0)
{
int Frequncy1 = int.Parse(ScanStart1.Text);
Frequncy1 = 196251 - Frequncy1;
StartFrequency = FormatWithSpaces(Frequncy1);
int Frequncy2 = int.Parse(ScanEnd1.Text);
Frequncy2 = 196251 - Frequncy2;
EndFrequency = FormatWithSpaces(Frequncy2);
}
else
{
int Frequncy1 = int.Parse(ScanStart2.Text);
Frequncy1 = 196251 - Frequncy1;
StartFrequency = FormatWithSpaces(Frequncy1);
int Frequncy2 = int.Parse(ScanEnd2.Text);
Frequncy2 = 196251 - Frequncy2;
EndFrequency = FormatWithSpaces(Frequncy2);
}
string StartFrequncyString = '01 93 ' + StartFrequency;
StartFrequncyString = CalcBIP4(StartFrequncyString).ToLower();
string StepSizeString = '01 94 ' + Step;
StepSizeString = CalcBIP4(StepSizeString).ToLower();
string EndFrequncyString = '01 95 ' + EndFrequency;
EndFrequncyString = CalcBIP4(EndFrequncyString).ToLower();
Box.Text = formattedTime + ' 发出→' + StartFrequncyString + Environment.NewLine + Box.Text;
SendHexStringArray(StartFrequncyString);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + StepSizeString + Environment.NewLine + Box.Text;
SendHexStringArray(StepSizeString);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + EndFrequncyString + Environment.NewLine + Box.Text;
SendHexStringArray(EndFrequncyString);
System.Threading.Thread.Sleep(1000);
}
private void PerformFrequencyOperation()
{
string formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
string FixedFrequence = '';
if (SetParameters.SelectedIndex == 0)
{
int frequencyGhz = int.Parse(Fixed1.Text);
frequencyGhz = 196250 - frequencyGhz;
FixedFrequence = FormatWithSpaces(frequencyGhz);
}
else if (SetParameters.SelectedIndex == 1)
{
int frequencyGhz = int.Parse(Fixed2.Text);
frequencyGhz = 196250 - frequencyGhz;
FixedFrequence = FormatWithSpaces(frequencyGhz);
}
string FixedFrequenceString1 = '01 93 ' + FixedFrequence;
FixedFrequenceString1 = CalcBIP4(FixedFrequenceString1).ToLower();
string FixedFrequenceString2 = '01 95 ' + FixedFrequence;
FixedFrequenceString2 = CalcBIP4(FixedFrequenceString2).ToLower();
string FixedFrequenceString3 = '01 a4 00 02';
FixedFrequenceString3 = CalcBIP4(FixedFrequenceString3).ToLower();
Box.Text = formattedTime + ' 发出→' + FixedFrequenceString1 + Environment.NewLine + Box.Text;
SendHexStringArray(FixedFrequenceString1);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + FixedFrequenceString2 + Environment.NewLine + Box.Text;
SendHexStringArray(FixedFrequenceString2);
System.Threading.Thread.Sleep(1000);
formattedTime = DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
Box.Text = formattedTime + ' 发出→' + FixedFrequenceString3 + Environment.NewLine + Box.Text;
SendHexStringArray(FixedFrequenceString3);
System.Threading.Thread.Sleep(1000);
}
private void SendHexStringArray(string hexString)
{
byte[] commandBytes = hexString.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
serialPort1.Write(commandBytes, 0, commandBytes.Length);
}
private void Clean_Click(object sender, EventArgs e)
{
Box.Text = string.Empty;
}
private void SetParameters_SelectedIndexChanged(object sender, EventArgs e)
{
if (SetParameters.SelectedIndex == 0)
{
Unit1.Text = 'GHz';
Unit2.Text = 'GHz';
Unit3.Text = 'nm';
Unit4.Text = 'nm';
Unit5.Text = 'GHz';
Unit6.Text = 'nm';
if (SetParameters.SelectedIndex != GlobalVariables.lastselectindex)
{
NumChange1(SetParameters.SelectedIndex);
}
}
else if (SetParameters.SelectedIndex == 1)
{
Unit1.Text = 'nm';
Unit2.Text = 'nm';
Unit3.Text = 'GHz';
Unit4.Text = 'GHz';
Unit5.Text = 'nm';
Unit6.Text = 'GHz';
if (SetParameters.SelectedIndex != GlobalVariables.lastselectindex)
{
NumChange1(SetParameters.SelectedIndex);
}
}
GlobalVariables.lastselectindex = SetParameters.SelectedIndex;
}
private void ScanStart1_TextChanged(object sender, EventArgs e)
{
NumChange2(ScanStart1.Text, 1, SetParameters.SelectedIndex);
if (SetParameters.SelectedIndex == 0)
{
double start = double.Parse(ScanStart2.Text);
numericEdit1.Value = Math.Round(start, 1);
}
else
{
double start = double.Parse(ScanStart1.Text);
numericEdit1.Value = Math.Round(start, 1);
}
}
private void ScanEnd1_TextChanged(object sender, EventArgs e)
{
NumChange2(ScanEnd1.Text, 2, SetParameters.SelectedIndex);
if (SetParameters.SelectedIndex == 0)
{
double end = double.Parse(ScanEnd2.Text);
numericEdit2.Value = Math.Round(end, 1);
}
else
{
double end = double.Parse(ScanEnd1.Text);
numericEdit2.Value = Math.Round(end, 1);
}
}
private void Fixed1_TextChanged(object sender, EventArgs e)
{
NumChange2(Fixed1.Text, 3, SetParameters.SelectedIndex);
}
private void NumChange1(int i)
{
double ScanStart1_Num;
double ScanEnd1_Num;
double Fixed1_Num;
double ScanStart2_Num;
double ScanEnd2_Num;
double Fixed2_Num;
ScanStart1.Text = ScanStart2.Text;
ScanStart1_Num = double.Parse(ScanStart1.Text);
ScanStart2_Num = 3e8 / ScanStart1_Num;
ScanEnd1.Text = ScanEnd2.Text;
ScanEnd1_Num = double.Parse(ScanEnd1.Text);
ScanEnd2_Num = 3e8 / ScanEnd1_Num;
Fixed1.Text = Fixed2.Text;
Fixed1_Num = double.Parse(Fixed1.Text);
Fixed2_Num = 3e8 / Fixed1_Num;
if (i == 0)
{
ScanStart2.Text = ScanStart2_Num.ToString('F3');
ScanEnd2.Text = ScanEnd2_Num.ToString('F3');
Fixed2.Text = Fixed2_Num.ToString('F3');
}
if (i == 1)
{
ScanStart2.Text = ScanStart2_Num.ToString('F0');
ScanEnd2.Text = ScanEnd2_Num.ToString('F0');
Fixed2.Text = Fixed2_Num.ToString('F0');
}
}
private void NumChange2(string text, int location, int index)
{
double Num1;
double Num2;
Num1 = double.Parse(text);
Num2 = 3e8 / Num1;
if (index == 0)
{
switch (location)
{
case 1:
ScanStart2.Text = Num2.ToString('F3');
break;
case 2:
ScanEnd2.Text = Num2.ToString('F3');
break;
case 3:
Fixed2.Text = Num2.ToString('F3');
break;
}
}
else
{
switch (location)
{
case 1:
ScanStart2.Text = Num2.ToString('F0');
break;
case 2:
ScanEnd2.Text = Num2.ToString('F0');
break;
case 3:
Fixed2.Text = Num2.ToString('F0');
break;
}
}
}
private void ScanSetting_Click(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
{
backgroundWorker.RunWorkerAsync('Scan');
}
}
private string FormatWithSpaces(int number)
{
string numberStr = number.ToString('X4');
string formattedStr = '';
for (int i = 0; i < numberStr.Length; i += 2)
{
formattedStr += numberStr.Substring(i, Math.Min(2, numberStr.Length - i));
if (i + 2 Convert.ToInt32(part, 16)).ToArray();
int bip8 = intArray[0] ^ intArray[1] ^ intArray[2] ^ intArray[3];
int bip4 = ((bip8 & 0xF0) >> 4) ^ (bip8 & 0x0F);
intArray[0] += bip4 * 16;
string[] hexArray = intArray.Select(i => i.ToString('X2')).ToArray();
string result = string.Join(' ', hexArray);
return result;
}
private void XY_Auto_Click(object sender, EventArgs e)
{
waveformGraph1.InteractionModeDefault = GraphDefaultInteractionMode.None;
waveformGraph1.ResetZoomPan();
}
private void CurMode_Click(object sender, EventArgs e)
{
xyCursor1.SnapMode = NationalInstruments.UI.CursorSnapMode.NearestPoint;
waveformGraph1.InteractionModeDefault = GraphDefaultInteractionMode.None;
waveformGraph1.InteractionMode = GraphInteractionModes.DragCursor;
}
private void ZoomMode_Click(object sender, EventArgs e)
{
waveformGraph1.InteractionModeDefault = GraphDefaultInteractionMode.ZoomXY;
}
private void MoveMode_Click(object sender, EventArgs e)
{
waveformGraph1.InteractionModeDefault = GraphDefaultInteractionMode.PanXY;
}
private void OnCursorMove(object sender, NationalInstruments.UI.AfterMoveXYCursorEventArgs e)
{
string DispCur = e.XPosition.ToString('f3');
XPOS.Text = DispCur;
DispCur = e.YPosition.ToString('f4');
YPOS.Text = DispCur;
}
private void ConfigDAQ_Click(object sender, EventArgs e)
{
Art1.ReleaseAD();
Art1.ART_SPChanCount = 4;
Art1.ART_SPFrequency = SPrate.Value;
Art1.ART_SPNumPerCH = (UInt32)SPAmount.Value;
Art1.ART_SPDelay = 0;
Art1.ART_FreqDivision = 1;
Art1.CH1_AC_DC = 1;
Art1.CH2_AC_DC = 1;
Art1.CH3_AC_DC = 1;
Art1.CH4_AC_DC = 1;
if (CH1Couple.Checked) { Art1.CH1_AC_DC = 0; }
if (CH2Couple.Checked) { Art1.CH2_AC_DC = 0; }
if (CH3Couple.Checked) { Art1.CH3_AC_DC = 0; }
if (CH4Couple.Checked) { Art1.CH4_AC_DC = 0; }
Art1.CH1_Range = 1;
Art1.CH2_Range = 1;
Art1.CH3_Range = 1;
Art1.CH4_Range = 1;
if (Range1.SelectedIndex == 1) { Art1.CH1_Range = 2; }
if (Range2.SelectedIndex == 1) { Art1.CH2_Range = 2; }
if (Range3.SelectedIndex == 1) { Art1.CH3_Range = 2; }
if (Range4.SelectedIndex == 1) { Art1.CH4_Range = 2; }
switch (TrigDir.SelectedIndex)
{
case 0: Art1.ART_TriggerDir = 1; break;
case 1: Art1.ART_TriggerDir = 0; break;
}
switch (TrigSrc.SelectedIndex)
{
case 0: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_SW'; break;
case 1: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_CH0'; break;
case 2: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_CH1'; break;
case 3: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_CH2'; break;
case 4: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_CH3'; break;
case 5: Art1.ART_TrigSrcSel = 'VAL_TRIGGER_DTR'; break;
}
switch (ClockSel.SelectedIndex)
{
case 0:
if (TrigSrc.SelectedIndex == 0)
{
Art1.ConfigParmIntClkSoftTrig();
}
else
{
Art1.ConfigParmIntClkVolTrig();
Art1.ART_TriggerLevel = (float)TrigVal.Value * 1000;
Art1.ART_TriggerSens = 0;
}
break;
case 1:
if (TrigSrc.SelectedIndex == 0)
{
Art1.ConfigParmExtClkSoftTrig();
}
else
{
Art1.ConfigParmExtClkVolTrig();
Art1.ART_TriggerLevel = (float)TrigVal.Value * 1000;
Art1.ART_TriggerSens = 0;
}
break;
}
Art1.ConfigART();
Art1.IntTask();
}
private void SamplingOnce_Click(object sender, EventArgs e)
{
if (Art1.ConfigDone && Art1.InitOK)
{
if (Art1.FinSample() == 0)
{
Art1.StopAcquisition();
}
}
else
{
Art1.StopAcquisition();
Art1.ReleaseAD(0);
}
waveformPlot1.ClearData();
waveformPlot2.ClearData();
waveformPlot3.ClearData();
waveformPlot4.ClearData();
if (checkBox1.Checked)
{
waveformPlot1.PlotY(Art1.Chan1);
}
if (checkBox2.Checked)
{
waveformPlot2.PlotY(Art1.Chan2);
}
if (checkBox3.Checked)
{
waveformPlot3.PlotY(Art1.Chan3);
}
if (checkBox4.Checked)
{
waveformPlot4.PlotY(Art1.Chan4);
}
}
private void SaveDAQ_Click(object sender, EventArgs e)
{
string FileName = DateTime.Now.ToString('yyyyMMddHHmmss') + '.txt';
using (System.IO.StreamWriter file = new System.IO.StreamWriter(FileName, false))
{
string WriteData;
if (Art1.Chan1.Length == 0)
{
file.WriteLine();
}
else
{
for (Int32 loop = 0; loop 0)
{
FileName = DateTime.Now.ToString('yyyyMMddHHmmss') + '.tdms';
file = new TdmsFile(FileName, new TdmsFileOptions());
file.AutoSave = true;
TdmsChannelGroup channelGroup = new TdmsChannelGroup('Main Group');
TdmsChannelGroupCollection channelGroups = file.GetChannelGroups();
channelGroups.Add(channelGroup);
TdmsChannelCollection tdmsChannels = channelGroup.GetChannels();
TdmsChannel[] waveformChannels = new TdmsChannel[4];
waveformChannels[0] = new TdmsChannel('Channel 1', TdmsDataType.Double);
tdmsChannels.Add(waveformChannels[0]);
waveformChannels[1] = new TdmsChannel('Channel 2', TdmsDataType.Double);
tdmsChannels.Add(waveformChannels[1]);
waveformChannels[2] = new TdmsChannel('Channel 3', TdmsDataType.Double);
tdmsChannels.Add(waveformChannels[2]);
waveformChannels[3] = new TdmsChannel('Channel 4', TdmsDataType.Double);
tdmsChannels.Add(waveformChannels[3]);
AnalogWaveform[] generatedData = new AnalogWaveform[4];
generatedData[0] = AnalogWaveform.FromArray1D(Art1.Chan1);
Art1.Chan1 = null;
generatedData[1] = AnalogWaveform.FromArray1D(Art1.Chan2);
Art1.Chan2 = null;
generatedData[2] = AnalogWaveform.FromArray1D(Art1.Chan3);
Art1.Chan3 = null;
generatedData[3] = AnalogWaveform.FromArray1D(Art1.Chan4);
Art1.Chan4 = null;
channelGroup.AppendAnalogWaveforms(waveformChannels, generatedData);
file.Close();
channelGroup = null;
waveformChannels = null;
channelGroups = null;
tdmsChannels = null;
GC.Collect();
}
else
{
MessageBox.Show('存储数据空', '错误提示');
}
}
catch
{
MessageBox.Show('存储数据出错', '错误提示');
}
finally
{
try { file?.Close(); }
catch { }
}
}
private void getTDMSdata_Click(object sender, EventArgs e)
{
Spectral_processing s = new Spectral_processing();
s.ReadTdmsFile();
double[] x;
double[] y;
s.ProcessData(out x, out y);
scatterPlot1.ClearData();
scatterPlot1.PlotXY(x, y);
}
private double[] wavelength;
private double[] opticalpower;
private void SpectralProcessing_Click(object sender, EventArgs e)
{
SamplingOnce_Click(null, null);
Spectral_processing s = new Spectral_processing();
s.numericEdit1 = numericEdit1.Value;
s.numericEdit2 = numericEdit2.Value;
s.Sig1 = Art1.Chan1;
s.Sig2 = Art1.Chan2;
s.Sig3 = Art1.Chan3;
s.Sig4 = Art1.Chan4;
s.ProcessData(out wavelength, out opticalpower);
scatterPlot1.ClearData();
scatterPlot1.PlotXY(wavelength, opticalpower);
}
// 文档中缺失的界面控件初始化方法(占位)
private void InitializeComponent()
{
// 需根据实际UI设计补充控件初始化逻辑
this.ClockSel = new ComboBox();
this.TrigSrc = new ComboBox();
this.TrigDir = new ComboBox();
this.Range1 = new ComboBox();
this.Range2 = new ComboBox();
this.Range3 = new ComboBox();
this.Range4 = new ComboBox();
this.SetParameters = new ComboBox();
this.Speed = new ComboBox();
this.SPAmount = new NumericUpDown();
this.TrigVal = new NumericUpDown();
this.SPrate = new NumericUpDown();
this.numericEdit1 = new NumericUpDown();
this.numericEdit2 = new NumericUpDown();
this.ScanStart1 = new TextBox();
this.ScanEnd1 = new TextBox();
this.Fixed1 = new TextBox();
this.ScanStart2 = new TextBox();
this.ScanEnd2 = new TextBox();
this.Fixed2 = new TextBox();
this.SerialNumber = new TextBox();
this.VersionNumber = new TextBox();
this.Box = new TextBox();
this.StepSize = new TextBox();
this.XPOS = new TextBox();
this.YPOS = new TextBox();
this.OpenSerialPort = new Button();
this.CloseSerialPort = new Button();
this.Read = new Button();
this.ScanSetting = new Button();
this.SpeedSetting = new Button();
this.SingleScan = new Button();
this.ContinueScan = new Button();
this.StopScan = new Button();
this.FrequencySetting = new Button();
this.Clean = new Button();
this.XY_Auto = new Button();
this.CurMode = new Button();
this.ZoomMode = new Button();
this.MoveMode = new Button();
this.ConfigDAQ = new Button();
this.SamplingOnce = new Button();
this.SaveDAQ = new Button();
this.Repeat = new Button();
this.SaveFileTDMS = new Button();
this.getTDMSdata = new Button();
this.SpectralProcessing = new Button();
this.CH1Couple = new CheckBox();
this.CH2Couple = new CheckBox();
this.CH3Couple = new CheckBox();
this.CH4Couple = new CheckBox();
this.checkBox1 = new CheckBox();
this.checkBox2 = new CheckBox();
this.checkBox3 = new CheckBox();
this.checkBox4 = new CheckBox();
this.waveformGraph1 = new WaveformGraph();
this.scatterGraph1 = new ScatterGraph();
this.waveformPlot1 = new WaveformPlot();
this.waveformPlot2 = new WaveformPlot();
this.waveformPlot3 = new WaveformPlot();
this.waveformPlot4 = new WaveformPlot();
this.scatterPlot1 = new ScatterPlot();
this.xyCursor1 = new XYCursor();
this.SelectSerialPort = new ComboBox();
this.SelectBaudRate = new ComboBox();
this.Unit1 = new Label();
this.Unit2 = new Label();
this.Unit3 = new Label();
this.Unit4 = new Label();
this.Unit5 = new Label();
this.Unit6 = new Label();
((System.ComponentModel.ISupportInitialize)(this.SPAmount)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.TrigVal)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.SPrate)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericEdit1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericEdit2)).BeginInit();
this.SuspendLayout();
// 控件位置、大小等属性初始化(略)
((System.ComponentModel.ISupportInitialize)(this.SPAmount)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.TrigVal)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.SPrate)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericEdit1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericEdit2)).EndInit();
this.ResumeLayout(false);
}
// 补充缺失的控件声明
private ComboBox SelectSerialPort;
private ComboBox SelectBaudRate;
private Label Unit1, Unit2, Unit3, Unit4, Unit5, Unit6;
}
// 程序入口类
class Program
{
static void Main(string[] args)
{
Console.WriteLine('Welcome to the Laser Spectrum Analysis System');
Console.Write('Username: ');
string username = Console.ReadLine();
Console.Write('Password: ');
string password = Console.ReadLine();
LoginModule login = new LoginModule();
if (login.ValidateLogin(username, password))
{
Console.WriteLine('Login successful!');
ParameterSettings paramSettings = new ParameterSettings();
paramSettings.SetLaserParameters(1550, 1.0, 10.0, 5.0);
paramSettings.SetSpectrumParameters(0.1, 0.5);
Console.WriteLine('Laser and spectrum parameters are set.');
LaserScanner laserScanner = new LaserScanner();
laserScanner.StartScan(paramSettings);
SpectrumResult spectrumResult = new SpectrumResult
{
Bandwidth = 10.5,
SignalToNoiseRatio = 35.0
};
spectrumResult.DisplayResults();
Console.Write('Enter file path to save report: ');
string filePath = Console.ReadLine();
spectrumResult.ExportReport(filePath);
Console.WriteLine('Report exported.');
}
else
{
Console.WriteLine('Invalid login credentials.');
}
// 启动Windows窗体应用
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}软件的使用步骤以下是我的软件的使用步骤:
1.打开软件:将软件在本地安装好后双击运行exe文件,进入软件的注册页面,如图1。

图 1 注册页面
2.注册账号:没有账号的话需要进行注册或者直接利用初始账号密码123456 进行登录,点击注册按钮进入注册页面,输入账号密码注册成功后点击返回登录 界面按钮,如果输入账号已存在或者两次输入密码不一致会有提示,如图2。

图 2 登录页面可调谐激光器光谱分析与控制系统 V1.0
3.登录可调谐激光器光谱分析与控制系统:输入初始账号密码123456或者输入自己注册的账号密码进行登录,登录成功后会进入软件,如果输入密码错误或 者账号不存在会有提示,如图3。

图 3 可调谐激光器光谱分析与控制系统界面
4. 参数设置。首先需要设置激光器的参数,包括目标波长,扫描速度,输 出功率和功率阈值,接下去设置光谱分析的参数包括光谱分辨率和积分时间,这 些参数设置为激光器的采样提供了基础,如图4。

图 4 参数设置界面可调谐激光器光谱分析与控制系统 V1.0
5. 激光扫描。点击开始扫描,激光器开始收集光谱并分析,当信号灯为绿 色时候表示结束,如图5。

图 5 扫描界面
6. 结果输出。最后输出光谱的结果,包括带宽和信噪比,还能将分析报告 导出txt格式到本地,如图6。

图 6 结果导出界面