using CommonDevHostApp.Devices; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Tps_LQ_Transmitter.com; using Tps_LQ_Transmitter.Common; using Tps_LQ_Transmitter.views; namespace Tps_LQ_Transmitter { public partial class FrmMain : Form { /// /// config目录下存在的测试配置文件信息 /// IList FileNodes; bool comFlag = false; /// /// 当前选择的测试配置文件信息 /// FileNode currFileNode; /// /// 停止测试标志 /// bool IsRuning = true; FrmMsg frmMsg; FrmDevice frmDevice; public FrmMain() { InitializeComponent(); frmMsg = new FrmMsg(); frmDevice = new FrmDevice(); } private void FrmMain_Load(object sender, EventArgs e) { //this.WindowState = System.Windows.Forms.FormWindowState.Maximized; FileNodes = new BindingList(); cbbProduct.ValueMember = "TestProject"; cbbProduct.DisplayMember = "DisplayName"; cbbProduct.DataSource = FileNodes; //加载配置文件信息 string folder = Path.Combine(Bundle.bundle.BundleDir, "config"); if(Directory.Exists(folder)) { //文件名示例:测试#常温测试#035变频模块.xlsx string[] files = Directory.GetFiles(folder, "测试#*.xlsx"); foreach (string file in files) { FileNode node = new FileNode(); node.FilePath = file; string fname = Path.GetFileNameWithoutExtension(file); fname = fname.Substring(fname.IndexOf('#') + 1); node.DisplayName = fname; node.TestProject = fname.Substring(0, fname.IndexOf('#')); node.ProductName = fname.Substring(fname.IndexOf('#') + 1); FileNodes.Add(node); } } cbbProduct.Refresh(); comFlag = true; superTabControl1.SelectedTabIndex = 0; } private void BtnLoadTpsConfig_Click(object sender, EventArgs e) { if (cbbProduct.SelectedIndex >= 0 && cbbProduct.SelectedItem != null) { //把试验项目显示到界面 FileNode fn = (FileNode)cbbProduct.SelectedItem; //加载内容 if (fn.Tps == null) { MainTps tps = new MainTps(); try { if (tps.LoadConfigFile(fn.FilePath)) { fn.Tps = tps; } else { ShowMessage(MsgType.Error, string.Format("加载配置文件失败,文件路径:{0}", fn.FilePath)); return; } } catch(Exception ee) { ShowMessage(MsgType.Error, string.Format("加载配置文件出现异常:{0},详细请查看日志文件。", ee.Message)); Bundle.log.WriteLog(AppLibs.Host.LogLevel.Error, "类:FrmMain,方法:BtnLoadTpsConfig_Click", ee.Message + ee.StackTrace); } } //初始化界面相关 ShowTps(fn); } } List tMsgs = new List(); void ShowMessage(MsgType msgType , string msg) { if (msgType == MsgType.Error) { errorCount++; this.Invoke(new Action(() => { BtnMessage.Text = "消息/错误:" + errorCount.ToString(); BtnMessage.ForeColor = Color.Red; })); } tMsgs.Add(new TestMessage() { type = msgType, message = msg }); frmMsg.ShowMsg(tMsgs); } /// /// 清空消息 /// void ClearMessage() { tMsgs.Clear(); frmMsg.ClearMsg(); } void ShowTps(FileNode fn) { if (currFileNode != null && currFileNode.Tps!= null ) { currFileNode.Tps.MessageEvent -= Tps_MessageEvent; currFileNode.Tps.ManualTableCellChanged -= Tps_ManualTableCellChanged; currFileNode.Tps.TestTableCellChanged -= Tps_TestTableCellChanged; currFileNode.Tps.AddTestTableCell -= Tps_TestTableAddCell; } currFileNode = fn; if(currFileNode.Tps != null) { currFileNode.Tps.MessageEvent += Tps_MessageEvent; currFileNode.Tps.ManualTableCellChanged += Tps_ManualTableCellChanged; currFileNode.Tps.TestTableCellChanged += Tps_TestTableCellChanged; currFileNode.Tps.AddTestTableCell += Tps_TestTableAddCell; } tbTestProject.Text = fn.TestProject; displayTree(true); //显示主界面 dgvTestData.DataSource = currFileNode.Tps.TestTable; //显示人工配置界面 dgvManualData.DataSource = currFileNode.Tps.ManualTable; //显示仪器列表,把当前TPS使用的仪器和仪器检查界面绑定 frmDevice.ShowDevices(currFileNode.Tps.Devices); } private void Tps_TestTableAddCell(string name, string lower, string upper, string testval, string result) { this.Invoke(new Action(() => { currFileNode.Tps.TestTable.Rows.Add(name, lower,upper,testval, result); if (result=="是") { dgvTestData.Rows[currFileNode.Tps.TestTable.Rows.Count-1].Cells[4].Style.BackColor = Color.Green; } else { dgvTestData.Rows[currFileNode.Tps.TestTable.Rows.Count-1].Cells[4].Style.BackColor = Color.Red; } })); } private void Tps_TestTableCellChanged(int row, int cell,bool ok, object value) { this.Invoke(new Action(() => { currFileNode.Tps.TestTable.Rows[row][cell] = value; if (ok) { dgvTestData.Rows[row].Cells[cell].Style.BackColor = Color.White; } else { dgvTestData.Rows[row].Cells[cell].Style.BackColor = Color.Red; } })); } private void Tps_ManualTableCellChanged(int row, int cell, bool ok, object value) { this.Invoke(new Action(() => { currFileNode.Tps.ManualTable.Rows[row][cell] = value; if (ok) { dgvTestData.Rows[row].Cells[cell].Style.BackColor = Color.White; } else { dgvTestData.Rows[row].Cells[cell].Style.BackColor = Color.Red; } })); } int errorCount = 0; private void Tps_MessageEvent(MsgType msgType, string msg) { ShowMessage(msgType, msg); } bool isOrderByChannel = true; Task task; private void BtnStart_Click(object sender, EventArgs e) { if (currFileNode == null) return; if (tbSerial.Text == "") { MessageBox.Show("温馨提示:请输入产品编号后再进行测试!"); return; } labRemainTime.Text = $"开始测试"; IsRuning = true; BtnLoadTpsConfig.Enabled = false; BtnStart.Enabled = false; currFileNode.Tps.Tester = tbTester.Text; currFileNode.Tps.Place = tbPlace.Text; currFileNode.Tps.Product = currFileNode.ProductName; currFileNode.Tps.Serial = tbSerial.Text; currFileNode.Tps.Temperature = tbTemp.Text; currFileNode.Tps.Humidity = tbRH.Text; currFileNode.Tps.TestProject = tbTestProject.Text; ClearMessage(); //检查仪器,如果OK则开始测试 if(currFileNode.Tps.CheckDevices()) { if(BtnDevice.ForeColor == Color.Red) { BtnDevice.ForeColor = Color.Black; } StartTest(); } else { //设备检查不通过,需要提醒用户确认 //BtnDevice.ForeColor = Color.Red; //显示仪器设置界面 //if(MessageBox.Show("设备参数异常,是否继续测试?","警告",MessageBoxButtons.YesNo) == DialogResult.Yes) //{ StartTest(); //} //else //{ // BtnLoadTpsConfig.Enabled = true; // BtnStart.Enabled = true; //} } } Thread SerialHandleThread1; private void WorkThretdHandleFunction(object num) { } void StartTest() { Stopwatch TimesCounter = new Stopwatch(); double testMin = 0; TimesCounter.Restart(); //开始测试的时候重置测试表格 currFileNode.Tps.ResetTestTable(); SerialHandleThread1 = new Thread(new ParameterizedThreadStart(WorkThretdHandleFunction)); SerialHandleThread1.Priority = ThreadPriority.Highest; MainTps tps = new MainTps(); SerialConfig scfg = new SerialConfig(); MatchComPara CfigComParas = scfg.LoadComWorkBook(); if (CfigComParas == null) { return; } byte FourthByte = 0x00; string ComPort = CfigComParas.GetComPort("1"); byte ThridByte = Convert.ToByte(CfigComParas.GetThirdByte("1"), 16); currFileNode.Tps.ThridByte = ThridByte; int FrequencyNumber; if (currFileNode.Tps.TestFreqSum >= CfigComParas.ComParameters.Count)//如果限定的测试频点数大于设置的频点数 { FrequencyNumber = CfigComParas.ComParameters.Count;//取设置的频点数 } else { FrequencyNumber = currFileNode.Tps.TestFreqSum;//取限定的测试频点数 } dgvTestData.DataSource = null; dgvTestData.DataSource = currFileNode.Tps.TestTable; // ConfigParameter SetVoltPara = new ConfigParameter(); CommonVisaResource DCPower = new CommonVisaResource(); try { DCPower.Open(currFileNode.Tps.DCPowerAddress); } catch (Exception ex) { MessageBox.Show("打开TDK电源失败,请检查电源是否上电!"); return; } DCPower.Write("INSTrument:NSELect 6\n"); DCPower.Query("*OPC?\n"); DCPower.Write("VOLTage:PROTection:LEVel 34 V\n"); DCPower.Query("*OPC?\n");//设置过压保护 DCPower.Write("VOLT:PROT:LOW 20 V\n"); DCPower.Query("*OPC?\n");//设置欠压保护 DCPower.Write("VOLT:PROT:LOW:STAT UVP\n"); DCPower.Query("*OPC?\n");//启动欠压保护 double volt = currFileNode.Tps.GloabConfigDict["电压"]; double Current = currFileNode.Tps.GloabConfigDict["电流"]; DCPower.Write($"VOLTage {volt} V\n"); DCPower.Query("*OPC?\n");//设置电压 DCPower.Write($"CURRent {Current} A\n"); DCPower.Query("*OPC?\n");//设置电流 DCPower.Write("GLOBal:OUTPut:STATe 1\n"); DCPower.Query("*OPC?\n"); ShowMessage(MsgType.Info, string.Format("打开TDK电源.")); TransmitterSerialPort SerialClient = new TransmitterSerialPort(); int ControlDelay = currFileNode.Tps.TestNodes[0].Parameters.GetParameter("控制延时"); currFileNode.Tps.ControlDelay = ControlDelay; task = new Task(new Action(() => { //执行测试过程 //currFileNode.Tps.Start(isOrderByChannel); SerialClient.SerialOpen(CfigComParas.GetComPort("1"));//需要取消注释 ShowMessage(MsgType.Info, string.Format("打开串口."));//需要取消注释 currFileNode.Tps.SerialClient = SerialClient; #region 根据频点来测指标 for (int point = 0; point < FrequencyNumber; point++)//频点总数 { FourthByte = Convert.ToByte(CfigComParas.GetFourthByte((point + 1).ToString()), 16); currFileNode.Tps.FourthByte = FourthByte; double CenterFreq = double.Parse(CfigComParas.Getfreqpoint((point + 1).ToString())); for (int i = 0; i < currFileNode.Tps.TestNodes.Count; i++) { currFileNode.Tps.TestNodes[i].PointIndex = point; currFileNode.Tps.TestNodes[i].CenterFreq = CenterFreq; //currFileNode.Tps.TestNodes[i].PointTotal = currFileNode.Tps.TestNodes.Count; currFileNode.Tps.TestNodes[i].PointTotal = FrequencyNumber; } if (IsRuning == false) { //控制断电 if (currFileNode.Tps.Product.Contains("YZH16A"))//针对YZH16A的产品 { SerialClient.DUT_Transmitter_Ctrol(0x00, 0x00, 0x55); } else { SerialClient.DUT_Transmitter_Ctrol1(0x00, 0x00); } SerialClient.SerialClose(); DCPower.Write("GLOBal:OUTPut:STATe 0\n"); DCPower.Query("*OPC?\n"); ShowMessage(MsgType.Info, string.Format("关闭6YYC信号源,关闭串口,关闭TDK电源.")); return; } //控制 if (currFileNode.Tps.Product.Contains("YZH16A"))//针对YZH16A的产品 { SerialClient.DUT_Transmitter_Ctrol(ThridByte, FourthByte, 0x55); } else { SerialClient.DUT_Transmitter_Ctrol1(ThridByte, FourthByte); } ShowMessage(MsgType.Info, string.Format("发送串口指令EB 90 {0} {1}.", ThridByte, FourthByte)); testMin = TimesCounter.ElapsedMilliseconds/1000f / 60f; Thread.Sleep(ControlDelay);//单位ms ShowMessage(MsgType.Info, string.Format("延时{0}ms.", ControlDelay)); this.BeginInvoke(new Action(() => { labRemainTime.Text = $"第{point + 1}个频点[{CenterFreq}]MHz测试,共{FrequencyNumber}个频点,耗时{Math.Round(testMin, 2)}Min。"; })); currFileNode.Tps.Start(isOrderByChannel); } TimesCounter.Stop(); testMin = TimesCounter.ElapsedMilliseconds / 1000f / 60f; this.BeginInvoke(new Action(() => { labRemainTime.Text = $"测试结束,共计耗时{Math.Round(testMin,2)}分钟"; })); #endregion //控制断电 if (currFileNode.Tps.Product.Contains("YZH16A"))//针对YZH16A的产品 { SerialClient.DUT_Transmitter_Ctrol(0x00, 0x00, 0x55); } else { SerialClient.DUT_Transmitter_Ctrol1(0x00, 0x00); } SerialClient.SerialClose();//需要取消注释 DCPower.Write("GLOBal:OUTPut:STATe 0\n"); DCPower.Query("*OPC?\n");//需要取消注释 ShowMessage(MsgType.Info, string.Format("关闭6YYC信号源,关闭串口,关闭TDK电源.")); this.Invoke(new Action(() => { BtnLoadTpsConfig.Enabled = true; BtnStart.Enabled = true; })); })); task.Start(); } public void DataTableFlush(DataTable data) { this.Invoke(new Action(() => { dgvTestData.DataSource = null; dgvTestData.DataSource = data; })); } private void BtnStop_Click(object sender, EventArgs e) { MainTps tps = new MainTps(); CommonVisaResource DCPower = new CommonVisaResource(); //获取仪器 //var DC = tps.GetDevice("程控电源"); currFileNode.Tps.Stop(); IsRuning = false; //if(task != null && task.IsCompleted == false) //{ // //等待任务退出 // task.Wait(); //} BtnStart.Enabled = true; BtnLoadTpsConfig.Enabled = true; labRemainTime.Text = $"已停止测试。"; //DC.Write("关闭电源"); } private void BtnDevice_Click(object sender, EventArgs e) { if (currFileNode != null) { //点开按钮前检查仪器状态,并根据状态来显示不同背景颜色 currFileNode.Tps.CheckDevices(); } frmDevice.ShowDialog(); } private void BtnMessage_Click(object sender, EventArgs e) { frmMsg.ShowDialog(); errorCount = 0; BtnMessage.ForeColor = Color.Black; BtnMessage.Text = "消息"; } private void advTree1_NodeDoubleClick(object sender, DevComponents.AdvTree.TreeNodeMouseEventArgs e) { //打开注释,则启用各测试指标的各自界面,否则只用公共界面 //if(e.Node.Tag != null) //{ // TestNode node = (TestNode)e.Node.Tag; // //没有界面的就只清除显示 // if (node.TestModel.UC == null) // panel1.Controls.Clear(); // //相同的界面不做处理 // if (panel1.Controls.Count > 0 && panel1.Controls[0] == node.TestModel.UC) // return; // panel1.Controls.Clear(); // panel1.Controls.Add(node.TestModel.UC); // node.TestModel.UC.Dock = DockStyle.Fill; // node.TestModel.UC.Visible = true; //} } //树形控件按通道分类 private void tsmChannel_Click(object sender, EventArgs e) { displayTree(true); } //树形控件按指标分类 private void tmsTestNode_Click(object sender, EventArgs e) { displayTree(false); } bool treeCanSelect = true; private void tsmSelectAll_Click(object sender, EventArgs e) { checkAllNode(true); } private void tsmUnSelecteAll_Click(object sender, EventArgs e) { checkAllNode(false); } //选或者反选所有节点 void checkAllNode(bool isChecked) { treeCanSelect = false; foreach (DevComponents.AdvTree.Node node in advTree1.Nodes) { node.Checked = isChecked; if (node.Nodes.Count > 0) { foreach (DevComponents.AdvTree.Node child in node.Nodes) { child.Checked = isChecked; } } } treeCanSelect = true; } /// /// 显示测试指标的树结构 /// /// 是否按通道来显示 void displayTree(bool isOrderByChannel) { this.isOrderByChannel = isOrderByChannel; advTree1.BeginUpdate(); treeCanSelect = false; advTree1.Nodes.Clear(); IEnumerable parents = null; if(isOrderByChannel) { parents = (from x in currFileNode.Tps.TestNodes select x.Channel).ToList().Distinct(); } else { parents = (from x in currFileNode.Tps.TestNodes select x.Name).ToList().Distinct(); } if (parents == null) return; List childs = null; foreach (string chName in parents) { DevComponents.AdvTree.Node parent = new DevComponents.AdvTree.Node(); parent.Text = chName; parent.CheckBoxVisible = true; parent.Tag = null; if (isOrderByChannel) { childs = currFileNode.Tps.TestNodes.Where(x => x.Channel == chName).ToList(); } else { childs = currFileNode.Tps.TestNodes.Where(x => x.Name == chName).ToList(); } foreach (TestNode node in childs) { DevComponents.AdvTree.Node treeNode = new DevComponents.AdvTree.Node(); if (isOrderByChannel) { treeNode.Text = node.Name; } else { treeNode.Text = node.Channel; } treeNode.CheckBoxVisible = true; if (node.IsSelected) { treeNode.Checked = true; parent.Checked = true; } treeNode.Tag = node; parent.Nodes.Add(treeNode); } advTree1.Nodes.Add(parent); } //如果父节点只有一个,即只有一个通道,则不显示通道 if(advTree1.Nodes.Count == 1) { DevComponents.AdvTree.Node root = advTree1.Nodes[0]; advTree1.Nodes.Clear(); if (root.Nodes.Count == 1) { advTree1.Nodes.Add(root.Nodes[0]); } else { foreach (DevComponents.AdvTree.Node item in root.Nodes) { advTree1.Nodes.Add(item); } } } treeCanSelect = true; advTree1.EndUpdate(); advTree1.Refresh(); advTree1.ExpandAll(); } /// /// 父节点全选或者反选,子节点采用一致的动作 /// /// /// private void advTree1_AfterCheck(object sender, DevComponents.AdvTree.AdvTreeCellEventArgs e) { if(treeCanSelect && e.Cell.Parent.Tag == null) { //表明选到了顶层,把子节点的选中状态和当前一致 foreach (DevComponents.AdvTree.Node node in e.Cell.Parent.Nodes) { node.Checked = e.Cell.Checked; } } else if(e.Cell.Parent.Tag != null) { TestNode node = (TestNode)e.Cell.Parent.Tag; node.IsSelected = e.Cell.Checked; } } public class ConfigParameter { /// /// 设置过压保护 /// public string SetOverVoltProtect { set; get; } /// /// 设置电压 /// public double SetVolt { set; get; } /// /// 设置电流 /// public double SetCurrent { set; get; } } private void dgvTestData_CellContentClick(object sender, DataGridViewCellEventArgs e) { } private void tbTester_TextChanged(object sender, EventArgs e) { } private void btnDebugging_Click(object sender, EventArgs e) { DebuggingForm debuggingForm = new DebuggingForm(); debuggingForm.Show(); } } }