using INIFILE; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO.Ports; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Management; using System.Text.RegularExpressions; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms.DataVisualization.Charting; using System.Data.OleDb; using System.Data.SqlClient; using Sunny.UI.Win32; using System.Web; using SortOrder = System.Windows.Forms.SortOrder; namespace SetTools { public partial class FormMain : Form { public String ConSql = @"Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Directory.GetCurrentDirectory() + "\\rqdata.mdb"; public String Ua = "1"; public String Ub = "1"; public String Uc = "1"; public int UOP_ID = 0;//操作时记录ID public bool reverice_flag = false; SerialPort sp1 = new SerialPort();//sp1.ReceivedBytesThreshold = 1;//只要有1个字符送达端口时便触发DataReceived事件 int visble = 0; byte[] bytes = new byte[100];//接收数据缓冲 private Stream lastPortBaseStream = null; public FormMain() { InitializeComponent(); } private void loadPram() { radioButton1.Checked = Convert.ToBoolean((Profile.txtPParm12));//显示格式 radioButton2.Checked = Convert.ToBoolean((Profile.txtPParm13));//显示格式 visble = Convert.ToInt16(Profile.txtPParm15); } private void Init_Chart1() { //设置坐标X轴标题 chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Size = 50;//x坐标显示的个数--控制这个数量的大小进行缩放 chart1.ChartAreas[0].AxisX.LabelStyle.Interval = 1;//设置X轴的值的间隔大小 chart1.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = false;//是否在轴末尾显示标记 chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;//设置X轴的值的间隔大小 chart1.ChartAreas[0].AxisX.Title = "磁条长度(mm)或角度(°)"; //chart1.ChartAreas[0].AxisX.TitleForeColor = System.Drawing.Color.Crimson; chart1.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal; chart1.ChartAreas[0].AxisX.IsStartedFromZero = false; chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;//将X轴始终展示 //设置坐标Y轴标题 chart1.ChartAreas[0].AxisY.Title = "电压值/mv"; chart1.ChartAreas[0].AxisY.TitleForeColor = System.Drawing.Color.Black ; chart1.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Rotated270;//.Horizontal chart1.ChartAreas[0].AxisY.IsStartedFromZero = false; chart1.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;//将Y轴始终展示 chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色 chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色 chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条,也可以不关闭,就可以滑动 chart1.Series[0].BorderWidth = 2;//线宽 //清除曲线内的数据 foreach (var series in chart1.Series) { series.Points.Clear(); } } private void Init_Chart2() { //设置坐标X轴标题 chart2.ChartAreas["ChartArea1"].AxisX.ScaleView.Size = 50; chart2.ChartAreas[0].AxisX.LabelStyle.Interval = 1; chart2.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = false;//是否在轴末尾显示标记 chart2.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;//设置X轴的值的间隔大小 chart2.ChartAreas[0].AxisX.Title = "磁条长度(mm)或角度(°)"; //chart1.ChartAreas[0].AxisX.TitleForeColor = System.Drawing.Color.Crimson; chart2.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal; chart2.ChartAreas[0].AxisX.IsStartedFromZero = false; chart2.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;//将X轴始终展示 //设置坐标Y轴标题 chart2.ChartAreas[0].AxisY.Title = "电压值/mv"; chart2.ChartAreas[0].AxisY.TitleForeColor = System.Drawing.Color.Black; chart2.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Rotated270; chart2.ChartAreas[0].AxisY.IsStartedFromZero = false; chart2.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;//将Y轴始终展示 chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色 chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色 chart2.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条,也可以不关闭,就可以滑动 chart2.Series[0].BorderWidth = 2;//线宽 //清除曲线内的数据 foreach (var series in chart2.Series) { series.Points.Clear(); } } private void Init_Chart3() { //设置X坐标轴标题 chart3.ChartAreas["ChartArea1"].AxisX.ScaleView.Size = 50; chart3.ChartAreas[0].AxisX.LabelStyle.Interval = 1; chart3.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = false;//是否在轴末尾显示标记 chart3.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;//设置X轴的值的间隔大小 chart3.ChartAreas[0].AxisX.Title = "磁条长度(mm)或角度(°)"; //chart1.ChartAreas[0].AxisX.TitleForeColor = System.Drawing.Color.Crimson; chart3.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal; chart3.ChartAreas[0].AxisX.IsStartedFromZero = false; chart3.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;//将X轴始终展示 //设置Y坐标轴标题 chart3.ChartAreas[0].AxisY.Title = "电压值/mv"; chart3.ChartAreas[0].AxisY.TitleForeColor = System.Drawing.Color.Black; chart3.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Rotated270; chart3.ChartAreas[0].AxisY.IsStartedFromZero = false; chart3.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;//将Y轴始终展示 chart3.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色 chart3.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色 chart3.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条,也可以不关闭,就可以滑动 chart3.ChartAreas[0].CursorX.IsUserEnabled = true; chart3.ChartAreas[0].CursorY.IsUserEnabled = true; //清除曲线内的数据 foreach (var series in chart3.Series) { series.Points.Clear(); } } // 定义两个全局变量 public bool isMouseDown = false; public int lastMove = 0; // 用于记录鼠标上次移动的点,用于判断是左移还是右移 // 初始化ScaleView,可根据首次出现在chart中的数据点数修改合适的值 private void chart3_MouseWheel(object sender, MouseEventArgs e) { // 实验发现鼠标滚轮滚动一圈时e.Delta = 120,正反转对应正负120 if (chart3.ChartAreas[0].AxisX.ScaleView.Size > 0) // 防止越过左边界 { chart3.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } else if (e.Delta > 0) { chart3.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } } private void chart2_MouseWheel(object sender, MouseEventArgs e) { // 实验发现鼠标滚轮滚动一圈时e.Delta = 120,正反转对应正负120 if (chart2.ChartAreas[0].AxisX.ScaleView.Size > 0) // 防止越过左边界 { chart2.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } else if (e.Delta > 0) { chart2.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } } private void chart1_MouseWheel(object sender, MouseEventArgs e) { // 实验发现鼠标滚轮滚动一圈时e.Delta = 120,正反转对应正负120 if (chart1.ChartAreas[0].AxisX.ScaleView.Size > 0) // 防止越过左边界 { chart1.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } else if (e.Delta > 0) { chart1.ChartAreas[0].AxisX.ScaleView.Size += (e.Delta / 120); // 每次缩放1 } } private void LoginForm_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Normal) { SetWindowRegion(); } else { this.Region = null; } } public void SetWindowRegion() { System.Drawing.Drawing2D.GraphicsPath FormPath; FormPath = new System.Drawing.Drawing2D.GraphicsPath(); Rectangle rect = new Rectangle(0, 0, this.Width, this.Height); FormPath = GetRoundedRectPath(rect, 10);//10代表圆角角度大小 this.Region = new Region(FormPath); } /// 窗体大小 /// 圆角大小 private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius) { int diameter = radius; Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); GraphicsPath path = new GraphicsPath(); path.AddArc(arcRect, 180, 90);//左上角 arcRect.X = rect.Right - diameter;//右上角 path.AddArc(arcRect, 270, 90); arcRect.Y = rect.Bottom - diameter;// 右下角 path.AddArc(arcRect, 0, 90); arcRect.X = rect.Left;// 左下角 path.AddArc(arcRect, 90, 90); path.CloseFigure(); return path; } /// /// 程序启动时 /// /// /// private void FormMain_Load(object sender, EventArgs e) { INIFILE.Profile.LoadProfile();//加载所有 loadPram(); SetControlValue(); comboBox1.SelectedIndex = 0; comboBox2.SelectedIndex = 0; comboBox3.SelectedIndex = 0; comboBox4.SelectedIndex = 0; this.chart1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseWheel); Init_Chart1(); this.chart2.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.chart2_MouseWheel); Init_Chart2(); chart3.ChartAreas[0].AxisX.ScaleView.Size = 5; // 设置不显示chart自带的滚动条 chart3.ChartAreas[0].AxisX.ScrollBar.Enabled = false; chart3.ChartAreas[0].AxisY.ScrollBar.Enabled = false; // 注意不要开启X轴游标,默认不开启,如下设置false或者不设置下列参数 chart3.ChartAreas[0].CursorX.IsUserEnabled = false; chart3.ChartAreas[0].CursorX.AutoScroll = false; chart3.ChartAreas[0].CursorX.IsUserSelectionEnabled = false; this.chart3.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.chart3_MouseWheel); Init_Chart3(); button1.Visible = false; label64.ForeColor = Color.Gray; } /// /// 初始化窗体 /// private void SetControlValue() { // 预置波特率 switch (Profile.G_BAUDRATE) { case "300": cbBaudRate.SelectedIndex = 0; break; case "600": cbBaudRate.SelectedIndex = 1; break; case "1200": cbBaudRate.SelectedIndex = 2; break; case "2400": cbBaudRate.SelectedIndex = 3; break; case "4800": cbBaudRate.SelectedIndex = 4; break; case "9600": cbBaudRate.SelectedIndex = 5; break; case "19200": cbBaudRate.SelectedIndex = 6; break; case "38400": cbBaudRate.SelectedIndex = 7; break; case "57600": cbBaudRate.SelectedIndex = 8; break; case "115200": cbBaudRate.SelectedIndex = 9; break; default: { MessageBox.Show("波特率预置参数错误!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } //预置数据位 switch (Profile.G_DATABITS) { case "5": cbDataBits.SelectedIndex = 0; break; case "6": cbDataBits.SelectedIndex = 1; break; case "7": cbDataBits.SelectedIndex = 2; break; case "8": cbDataBits.SelectedIndex = 3; break; default: { MessageBox.Show("数据位预置参数错误!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } //预置停止位 switch (Profile.G_STOP) { case "1": cbStop.SelectedIndex = 0; break; case "1.5": cbStop.SelectedIndex = 1; break; case "2": cbStop.SelectedIndex = 2; break; default: { MessageBox.Show("停止位预置参数错误!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } //预置校验位 switch (Profile.G_PARITY) { case "NONE": cbParity.SelectedIndex = 0; break; case "ODD": cbParity.SelectedIndex = 1; break; case "EVEN": cbParity.SelectedIndex = 2; break; default: { MessageBox.Show("校验位预置参数错误!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } // 初始化串口 serialPortInit(); } public int GetTextBoxLength(string textboxTextStr) { int nLength = 0; for (int i = 0; i < textboxTextStr.Length; i++) { if (textboxTextStr[i] >= 0x3000 && textboxTextStr[i] <= 0x9FFF) nLength += 2; else nLength++; } return nLength; } /// /// 初始化串口相关 /// public void serialPortInit() { //检查是否含有串口 string[] str = SerialPort.GetPortNames(); if (str == null) { MessageBox.Show("本机没有串口!", "Error"); return; } //添加串口项目 foreach (string s in System.IO.Ports.SerialPort.GetPortNames()) { cbSerial.Items.Add(s); } //串口设置默认选择项 if (cbSerial.Items.Count > 0) { cbSerial.SelectedIndex = 0; } sp1.BaudRate = 9600; Control.CheckForIllegalCrossThreadCalls = false; //这个类中我们不检查跨线程的调用是否合法(因为.net 2.0以后加强了安全机制,,不允许在winform中直接跨线程访问控件的属性) sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); sp1.ReadTimeout = 1000; sp1.Close(); } int Travle_Flag = 0; int Motor_Run = 0; int Run_Mode = 0; int getV1 = 0; double getgs = 0; int getV2 = 0; int getd1 = 0; int getS = 0; double actd1 = 0; string[] x = new string[] { "已转角度", "角度" }; double[] y = new double[] { 0, 360 }; //用于接收串口数据 const int Rec_MaxLen = 1024; public byte[] bytes2 = new byte[Rec_MaxLen];//1024 字节 public int Rec_Len = 0; public int flag = 0; //处理完成 清除标记+清除缓存 void ClrRecData() { Rec_Len = 0; flag = 0; bytes2 = new byte[Rec_MaxLen]; sp1.DiscardInBuffer();//清空串口的数据 } /// /// 串口接收入口 /// /// /// public void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e) { if (reverice_flag == false) return; try { //直接用Invoke,关闭窗口时可能和这里冲突,虽然用BeginInvoke不会阻塞当前线程,但是接收会不够及时 this.BeginInvoke((EventHandler)(delegate { if (!sp1.IsOpen) return; //接受的临时数据 int ilen = sp1.BytesToRead; byte[] bytes = new byte[ilen]; sp1.Read(bytes, 0, ilen); int i = 0; int num = 0; if(flag == 0) { for (i = 0; i < bytes.Length; i++) { if (bytes[i] == 0x05)//帧头 { num = i; flag = 1; break; } } } if (flag == 1) { //数据转移到空数组里面 for (i = 0; i < (bytes.Length - num); i++) { bytes2[Rec_Len] = bytes[i + num]; Rec_Len++;//已接收数据的长度 //接收数据不能超过定义的缓存 if (Rec_Len >= Rec_MaxLen) { Rec_Len = 0; } } //数据长度(需要接收数据的长度) int slen = 0; slen = Convert.ToInt16( bytes2[1] ); slen <<= 8; slen += Convert.ToInt16( bytes2[2] ); if( bytes2[slen] == 0x1b )//帧尾是否一样 { //界面显示 string receiveString = ListbyteToHexStr(bytes2, Rec_Len) + System.Environment.NewLine; txtReceive.AppendText("接收成功!" ); //是否是自己 if ((bytes2[5] == 0x00) && (bytes2[6] == 0xA1)) { //指令 命令字 //order int order = 0; order = Convert.ToInt16(bytes2[7]); order <<= 8; order += Convert.ToInt16(bytes2[8]); switch(order) { case 0xF001:// { Travle_Flag = Convert.ToInt16(bytes2[9]); //测量功能: 00 直行程 01 角行程 Motor_Run = Convert.ToInt16(bytes2[10]); //控制电机运行: 00 停止 01 运行 02-运动到起始点 03-运动到结束点 Run_Mode = Convert.ToInt16(bytes2[11]); //运行模式: 00 点动 01 连续 getS = Convert.ToInt16(bytes2[12]); //到位开关状态: 00 无状态 01 起始位 02 结束位 getV1 = Convert.ToInt16(bytes2[13]) * 0x100 + Convert.ToInt16(bytes2[14]); //采样电压: 00 00 (数值 0 - 4095) getV2 = Convert.ToInt16(bytes2[15]) * 0x100 + Convert.ToInt16(bytes2[16]); //激光电压: 00 00 (数值 0 - 4095) getd1 = Convert.ToInt16(bytes2[17]) * 0x100 + Convert.ToInt16(bytes2[18]); //磁条长度: 00 00 (数值 0 - 4095) //分析在界面上 if (Travle_Flag == 0) { label13.Text = "直行程"; } else { label13.Text = "角行程"; } if (Motor_Run == 0) label15.Text = "停止"; else if (Motor_Run == 1) label15.Text = "运行"; else if (Motor_Run == 2) label15.Text = "运动到起始点"; else if (Motor_Run == 3) label15.Text = "运动到结束点"; else label15.Text = "错误"; if (Run_Mode == 0) label17.Text = "点动"; else label17.Text = "连续"; switch (getS) { case 1: { label19.Text = "起始位"; label64.ForeColor = Color.Yellow; } break; case 2: { label19.Text = "结束位"; label64.ForeColor = Color.Red; } break; case 3: { label19.Text = "测量中"; label64.ForeColor = Color.Green; } break; default: { label19.Text = "无状态"; label64.ForeColor = Color.Gray; } break; } getV1 = Convert.ToUInt16((getV1 * 3300) / 4096);//转成实际电压 getgs = Convert.ToDouble(((getV1 - 1500) / 3.3)/ 2.2);//转成高斯值 getV2 = (Convert.ToUInt16((getV2 * 3300) / 4096)*1000) / 110;//转成实际电流 label21.Text = Convert.ToString(getV1); label23.Text = Convert.ToString(getV2);//激光电压 int qaz = Convert.ToUInt16(comboBox4.SelectedIndex); //体现在曲线图上 if (Travle_Flag == 0 || (Travle_Flag == 1 && checkBox1.Checked == false))//"直行程" { if(qaz == 5) actd1 = (Convert.ToDouble(getd1 )) / 10;//转成磁条实际长度 else actd1 = (Convert.ToDouble(getd1)) / 10;//转成磁条实际长度 label60.Text = Convert.ToString(actd1); int m = chart1.Series[0].Points.AddXY(Convert.ToString(actd1) , getV1); if (chart1.ChartAreas[0].AxisX.ScaleView.Size > 0) { chart1.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } chart1.Series[0].Points[m].MarkerStyle = MarkerStyle.Diamond; chart1.Series[0].Points[m].MarkerBorderWidth = 3; chart1.Series[0].Points[m].MarkerSize = 10; chart1.Series[0].Points[m].IsValueShownAsLabel = true; //设置Y坐标轴标题 chart1.ChartAreas[0].AxisY.Title = "电压值"; chart1.ChartAreas[0].AxisY.TitleForeColor = System.Drawing.Color.Crimson; chart1.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Horizontal; chart1.ChartAreas[0].AxisY.IsStartedFromZero = false; chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色 chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色 chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条,也可以不关闭,就可以滑动 chart1.Series[0].BorderWidth = 2;//线宽 } else { actd1 = (Convert.ToDouble(getd1)) / 10;//转成磁条实际长度 label60.Text = Convert.ToString(actd1); //计算角度 y[0] = actd1; if (y[0] >= 360) y[0] = 0; y[1] = 360 - y[0]; chart1.Series[0].Points.DataBindXY(x, y); chart1.Series[0].Points[0].Color = Color.Yellow; //绑定颜色 chart1.Series[0].Palette = ChartColorPalette.BrightPastel; } //接收的数据插入到数据库内 TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); string UU = string.Empty; UU = Convert.ToInt64(ts.TotalMilliseconds).ToString(); string UK = Convert.ToString(DateTime.Now.ToString("G"));//日期 string UL = Uc;//人员编码ID string UM = textBox1.Text;//磁条编号 string UN = Convert.ToString(comboBox4.SelectedIndex);//磁条规格 double UO = Convert.ToDouble(numericUpDown1.Value);//磁条步长 OleDbConnection conn;//数据库连接 conn = new OleDbConnection(ConSql); conn.Open(); //建立SQL语句 string sqlstr = ""; sqlstr = @"INSERT INTO 磁条数据记录([测量功能], [控制电机运行], [运行模式], [到位开关状态],[采样电压], [激光电压], [磁条长度],[接收时间值],[接收数据时间], [人员编码ID],[磁条编号],[磁条规格],[磁条步长],[测试编号ID])VALUES("; sqlstr += "'" + Travle_Flag + "', '" + Motor_Run + "', '" + Run_Mode + "', '" + getS + "', '" + getV1 + "', '" + getV2 + "', '" + actd1 + "', '" + UU + "','" + UK + "', '" + UL + "','" + UM + "', '" + UN + "', '" + UO + "', '" + UOP_ID + "')"; OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; cmd.ExecuteNonQuery(); conn.Close(); if(Travle_Flag == 0 && Run_Mode == 1) { if(comboBox4.SelectedIndex == 1 && actd1 >= 25) { go_begin(); } if (comboBox4.SelectedIndex == 2 && actd1 >= 50) { go_begin(); } if (comboBox4.SelectedIndex == 3 && actd1 >= 110) { go_begin(); } if (comboBox4.SelectedIndex == 4 && actd1 >= 210) { go_begin(); } } } break; default: break; } } //清除数据 ClrRecData(); } } })); } catch { } } /// /// 时间控件 /// /// /// private void TmSend_Tick(object sender, EventArgs e) { try { } catch { } //分析 } public T Clone(T RealObject) { using (Stream objectStream = new MemoryStream()) { //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制 IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, RealObject); objectStream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(objectStream); } } /// /// 刷新串口对象 /// private void refreshSerialDevice() { try { lastPortBaseStream?.Dispose(); } catch (Exception e) { Console.WriteLine($"portBaseStream?.Dispose error:{e.Message}"); } try { sp1.BaseStream.Dispose(); } catch (Exception e) { Console.WriteLine($"serial.BaseStream.Dispose error:{e.Message}"); } sp1.Dispose(); sp1 = new SerialPort(); sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); } /// /// 打开串口 /// /// /// private void BtnOpen_Click(object sender, EventArgs e) { if (cbSerial.Items.Count == 0) { MessageBox.Show("Error:没有检测到可用的串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (!sp1.IsOpen) { try { refreshSerialDevice(); //设置串口号 string serialName = cbSerial.SelectedItem.ToString(); sp1.PortName = serialName; //设置各“串口设置” string strBaudRate = cbBaudRate.Text; string strDateBits = cbDataBits.Text; string strStopBits = cbStop.Text; Int32 iBaudRate = Convert.ToInt32(strBaudRate); Int32 iDateBits = Convert.ToInt32(strDateBits); sp1.BaudRate = iBaudRate; //波特率 sp1.DataBits = iDateBits; //数据位 switch (cbStop.Text) //停止位 { case "1": sp1.StopBits = StopBits.One; break; case "1.5": sp1.StopBits = StopBits.OnePointFive; break; case "2": sp1.StopBits = StopBits.Two; break; default: MessageBox.Show("Error:参数不正确!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } switch (cbParity.Text) //校验位 { case "无": sp1.Parity = Parity.None; break; case "奇校验": sp1.Parity = Parity.Odd; break; case "偶校验": sp1.Parity = Parity.Even; break; default: MessageBox.Show("Error:参数不正确!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } if (sp1.IsOpen == true)//如果打开状态,则先关闭一下 { sp1.Close(); } //状态栏设置 tsSpNum.Text = "串口号:" + sp1.PortName + "|"; tsBaudRate.Text = "波特率:" + sp1.BaudRate + "|"; tsDataBits.Text = "数据位:" + sp1.DataBits + "|"; tsStopBits.Text = "停止位:" + sp1.StopBits + "|"; tsParity.Text = "校验位:" + sp1.Parity + "|"; //设置必要控件不可用 cbSerial.Enabled = false; cbBaudRate.Enabled = false; cbDataBits.Enabled = false; cbStop.Enabled = false; cbParity.Enabled = false; refreshSerial.Enabled = false; sp1.Open(); //打开串口 btnOpen.Text = "关闭串口"; } catch (System.Exception ex) { MessageBox.Show("Error:" + ex.Message, "Error"); //状态栏设置 tsSpNum.Text = "串口号:未指定|"; tsBaudRate.Text = "波特率:未指定|"; tsDataBits.Text = "数据位:未指定|"; tsStopBits.Text = "停止位:未指定|"; tsParity.Text = "校验位:未指定|"; //恢复控件功能 //设置必要控件不可用 cbSerial.Enabled = true; cbBaudRate.Enabled = true; cbDataBits.Enabled = true; cbStop.Enabled = true; refreshSerial.Enabled = true; tmSend.Enabled = false; tmSend.Stop(); return; } } else { //状态栏设置 tsSpNum.Text = "串口号:未指定|"; tsBaudRate.Text = "波特率:未指定|"; tsDataBits.Text = "数据位:未指定|"; tsStopBits.Text = "停止位:未指定|"; tsParity.Text = "校验位:未指定|"; //恢复控件功能 //设置必要控件不可用 cbSerial.Enabled = true; cbBaudRate.Enabled = true; cbDataBits.Enabled = true; cbStop.Enabled = true; cbParity.Enabled = true; refreshSerial.Enabled = true; sp1.Close(); //关闭串口 btnOpen.Text = "打开串口"; tmSend.Enabled = false; //关闭计时器 tmSend.Stop(); } } /// /// 存储数据,保存参数 /// private void saveparm() { Profile.G_BAUDRATE = cbBaudRate.Text;//cbSerial.Text; Profile.G_DATABITS = cbDataBits.Text; Profile.G_STOP = cbStop.Text; Profile.G_PARITY = cbParity.Text; Profile.txtPParm12 = Convert.ToString(radioButton1.Checked); Profile.txtPParm13 = Convert.ToString(radioButton2.Checked); //------------------------------------------------------------------ INIFILE.Profile.SaveProfile(); } /// /// 关闭窗体时 /// /// /// private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { try { //参数保存 saveparm(); //关闭串口 sp1.Close(); } catch { } } /// /// 检测串口 /// private void CheckPort() { //状态栏设置 tsSpNum.Text = "串口号:未指定|"; tsBaudRate.Text = "波特率:未指定|"; tsDataBits.Text = "数据位:未指定|"; tsStopBits.Text = "停止位:未指定|"; tsParity.Text = "校验位:未指定|"; //恢复控件功能 //设置必要控件不可用 cbSerial.Enabled = true; cbBaudRate.Enabled = true; cbDataBits.Enabled = true; cbStop.Enabled = true; cbParity.Enabled = true; refreshSerial.Enabled = true; sp1.Close(); //关闭串口 btnOpen.Text = "打开串口"; tmSend.Enabled = false; //关闭计时器 tmSend.Stop(); try { //设置串口号 string serialName = cbSerial.SelectedItem.ToString(); sp1.PortName = serialName; //设置各“串口设置” string strBaudRate = cbBaudRate.Text; string strDateBits = cbDataBits.Text; string strStopBits = cbStop.Text; Int32 iBaudRate = Convert.ToInt32(strBaudRate); Int32 iDateBits = Convert.ToInt32(strDateBits); sp1.BaudRate = iBaudRate; //波特率 sp1.DataBits = iDateBits; //数据位 switch (cbStop.Text) //停止位 { case "1": sp1.StopBits = StopBits.One; break; case "1.5": sp1.StopBits = StopBits.OnePointFive; break; case "2": sp1.StopBits = StopBits.Two; break; default: MessageBox.Show("Error:参数不正确!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } switch (cbParity.Text) //校验位 { case "无": sp1.Parity = Parity.None; break; case "奇校验": sp1.Parity = Parity.Odd; break; case "偶校验": sp1.Parity = Parity.Even; break; default: MessageBox.Show("Error:参数不正确!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } if (sp1.IsOpen == true)//如果打开状态,则先关闭一下 { sp1.Close(); } //状态栏设置 tsSpNum.Text = "串口号:" + sp1.PortName + "|"; tsBaudRate.Text = "波特率:" + sp1.BaudRate + "|"; tsDataBits.Text = "数据位:" + sp1.DataBits + "|"; tsStopBits.Text = "停止位:" + sp1.StopBits + "|"; tsParity.Text = "校验位:" + sp1.Parity + "|"; //设置必要控件不可用 cbSerial.Enabled = false; cbBaudRate.Enabled = false; cbDataBits.Enabled = false; cbStop.Enabled = false; cbParity.Enabled = false; refreshSerial.Enabled = false; sp1.Open(); //打开串口 btnOpen.Text = "关闭串口"; } catch (System.Exception ex) { MessageBox.Show("Error:" + ex.Message, "Error"); tmSend.Enabled = false; tmSend.Stop(); return; } } /// /// 延时不卡界面 /// /// public void Delay(int milliSecond) { int start = Environment.TickCount; while (Math.Abs(Environment.TickCount - start) < milliSecond) { Application.DoEvents(); } } /// /// 将标识字符的转义字符还原 /// /// /// private byte[] UnEscape(byte[] data) { List tmp = new List(); for (int i = 0; i < data.Length; i++) { if (data[i] == 0x7D) { if (data[i + 1] == 0x01) { tmp.Add(0x7D); i++; } else if (data[i + 1] == 0x02) { tmp.Add(0x7E); i++; } } else { tmp.Add(data[i]); } } return tmp.ToArray(); } /// /// 连接设备「按钮」 /// /// /// private void button3_Click(object sender, EventArgs e) { if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } txtReceive.Focus(); txtReceive.SelectionStart = txtReceive.TextLength; } /// /// 字符串转换为16进制字符 /// /// /// /// private string StringToHexString(string s, Encoding encode) { byte[] b = encode.GetBytes(s);//按照指定编码将string编程字节数组 string result = string.Empty; for (int i = 0; i < b.Length; i++)//逐字节变为16进制字符 { result += Convert.ToString(b[i], 16); } return result; } /// /// 字节数组转16进制字符串 /// /// /// public static string byteToHexStr(byte[] bytes) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("X2"); } } return returnStr; } /// /// 字节数组转16进制字符串 /// /// /// public static string ListbyteToHexStr(byte[] bytes,int len) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < len; i++) { returnStr += bytes[i].ToString("X2") + " "; } } return returnStr; } // /// 字符串转16进制字节数组 /// /// /// private static byte[] strToToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } /// /// 16进制字符转换为字符串 /// /// /// /// private string HexStringToString(string hs, Encoding encode) { string strTemp = ""; byte[] b = new byte[hs.Length / 2]; for (int i = 0; i < hs.Length / 2; i++) { strTemp = hs.Substring(i * 2, 2); b[i] = Convert.ToByte(strTemp, 16); } //按照指定编码将字节数组变为字符串 return encode.GetString(b); } /// /// 从汉字转换到16进制 /// /// /// 编码,如"utf-8","gb2312" /// 是否每字符用逗号分隔 /// public static string ToHex(string s, string charset, bool fenge) { if ((s.Length % 2) != 0) { s += " ";//空格 } System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset); byte[] bytes = chs.GetBytes(s); string str = ""; for (int i = 0; i < bytes.Length; i++) { str += string.Format("{0:X}", bytes[i]); if (fenge && (i != bytes.Length - 1)) { str += string.Format("{0}", ","); } } return str.ToLower(); } /// /// 从16进制转换成汉字 /// /// /// 编码,如"utf-8","gb2312" /// public static string UnHex(string hex, string charset) { if (hex == null) throw new ArgumentNullException("hex"); hex = hex.Replace(",", ""); hex = hex.Replace("\n", ""); hex = hex.Replace("\\", ""); hex = hex.Replace(" ", ""); if (hex.Length % 2 != 0) { hex += "20";//空格 } // 需要将 hex 转换成 byte 数组。 byte[] bytes = new byte[hex.Length / 2]; for (int i = 0; i < bytes.Length; i++) { try { // 每两个字符是一个 byte。 bytes[i] = byte.Parse(hex.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } catch { // Rethrow an exception with custom message. throw new ArgumentException("hex is not a valid hex number!", "hex"); } } System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset); return chs.GetString(bytes); } private bool refreshLock = false; /// /// 刷新设备列表 /// private void refreshPortList() { if (refreshLock) return; refreshLock = true; cbSerial.Items.Clear(); List strs = new List(); Task.Run(() => { while (true) { try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity"); Regex regExp = new Regex("\\(COM\\d+\\)"); foreach (ManagementObject queryObj in searcher.Get()) { if ((queryObj["Caption"] != null) && regExp.IsMatch(queryObj["Caption"].ToString())) { strs.Add(queryObj["Caption"].ToString()); } } break; } catch { System.Threading.Thread.Sleep(500); } } foreach (string p in SerialPort.GetPortNames())//加上缺少的com口 { bool notMatch = true; foreach (string n in strs) { if (n.Contains($"({p})"))//如果和选中项目匹配 { notMatch = false; break; } } if (notMatch) strs.Add($"Serial Port {p} ({p})");//如果列表中没有,就自己加上 } foreach (string i in strs) cbSerial.Items.Add(i); if (strs.Count >= 1) { btnOpen.Enabled = true; cbSerial.SelectedIndex = 0; } else { btnOpen.Enabled = false; } refreshLock = false; //选定上次的com口 foreach (string c in cbSerial.Items) { } }); } private void refreshSerial_Click(object sender, EventArgs e) { if (sp1.IsOpen) //串口已经打开就不用刷新了 return; cbSerial.Items.Clear(); //初始化串口 serialPortInit(); } private void clearButton_Click(object sender, EventArgs e) { txtReceive.Text = ""; } /// /// 将16进制的字符串转为byte[] /// /// /// public static byte[] StrToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } public static string ToHexString(string str) { var sb = new StringBuilder(); var bytes = Encoding.Unicode.GetBytes(str); foreach (var t in bytes) { sb.Append(t.ToString("X2")); } return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world" } public static string FromHexString(string hexString) { var bytes = new byte[hexString.Length / 2]; for (var i = 0; i < bytes.Length; i++) { bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } return Encoding.Unicode.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64" } //byte转小写字母 public static string byteToHexLetterStr(byte[] bytes) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("x2"); } } return returnStr; } /// /// 发送数据 /// /// private void Send_AtMsg(String st) { //发送数据 if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } byte[] bytes = new byte[100]; int len = 0; bytes = System.Text.Encoding.Default.GetBytes(st); len = st.Length; sp1.Write(bytes, 0, len); //写入数据 if (txtReceive.Text.Trim() == "") { txtReceive.Text = "发送成功!" + System.Environment.NewLine; } else { txtReceive.Text = txtReceive.Text + System.Environment.NewLine + "发送成功!" + st + System.Environment.NewLine; } txtReceive.Focus(); txtReceive.SelectionStart = txtReceive.TextLength; } /// /// 发送代码 /// /// 数据内容 /// 命令 /// 地址 /// 数据内容的长度 /// private static byte[] GetData(byte[] data, int order, int addr, int DLen) { byte[] rVal = new byte[100]; byte[] crcVal = new byte[2]; int len = 0; int i = 0; //标识位 1B rVal[len + 0] = 0x05; len = len + 1; //长度 2B int t = DLen; t += 11; rVal[len + 0] = (byte)(t >> 8); rVal[len + 1] = (byte)t; len = len + 2; //设备 OBJ 4B rVal[len + 0] = 0x00; rVal[len + 1] = 0xA1; rVal[len + 2] = Convert.ToByte((addr >> 8) & 0xff); rVal[len + 3] = Convert.ToByte(addr & 0xff); len = len + 4; //命令字 2B rVal[len] = (byte)((order >> 8) & 0xff); rVal[len + 1] = (byte)(order & 0xff); len = len + 2; //数据内容 NB for (i = 0; i < DLen; i++) { rVal[len + i] = data[i]; } len = len + DLen; crcVal = CRC16(rVal, t); //校验码 2B CRC校验 rVal[len + 0] = crcVal[0]; rVal[len + 1] = crcVal[1]; rVal[len + 2] = 0x1B; len = len + 3; return rVal; } /// /// CRC16 /// /// 要进行计算的数组 /// 计算后的数组 private static byte[] CRC16(byte[] data, int len) { byte[] returnVal = new byte[2]; byte CRC16Lo, CRC16Hi, CL, CH, SaveHi, SaveLo; int i, Flag; CRC16Lo = 0xFF; CRC16Hi = 0xFF; CL = 0x42; CH = 0x04; for (i = 1; i < len; i++) { CRC16Lo = (byte)(CRC16Lo ^ data[i]);//每一个数据与CRC寄存器进行异或 for (Flag = 0; Flag <= 7; Flag++) { SaveHi = CRC16Hi; SaveLo = CRC16Lo; CRC16Hi = (byte)(CRC16Hi >> 1);//高位右移一位 CRC16Lo = (byte)(CRC16Lo >> 1);//低位右移一位 if ((SaveHi & 0x01) == 0x01)//如果高位字节最后一位为 { CRC16Lo = (byte)(CRC16Lo | 0x80);//则低位字节右移后前面补 否则自动补0 } if ((SaveLo & 0x01) == 0x01) //如果LSB为1,则与多项式码进行异或 { CRC16Hi = (byte)(CRC16Hi ^ CH); CRC16Lo = (byte)(CRC16Lo ^ CL); } } } returnVal[0] = CRC16Hi;//CRC高位 returnVal[1] = CRC16Lo;//CRC低位 return returnVal; } /// /// 控制指令 /// /// /// private void button1_Click(object sender, EventArgs e) { //发送数据 if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //处理完成后需要清除 ClrRecData(); byte[] bytes = new byte[100]; byte[] dstr = new byte[100]; int len = 0; int i = 0; int addr = 0; //测量功能 选择 dstr[0] = Convert.ToByte(comboBox2.SelectedIndex); len += 1; //控制电机运行 dstr[1] = Convert.ToByte(comboBox1.SelectedIndex); len += 1; //运行模式 dstr[2] = Convert.ToByte(comboBox3.SelectedIndex); len += 1; //电机运行多少圈为一个步长 i = Convert.ToInt16((Convert.ToDouble( numericUpDown1.Value))*10); dstr[3] = (byte)(i >> 8); dstr[4] = (byte)(i); len += 2; //电机运行间隔时长 i = Convert.ToInt16(numericUpDown2.Value); dstr[5] = (byte)(i >> 8); dstr[6] = (byte)(i); len += 2; //到“结束点”后,停止时间 i = Convert.ToInt16(numericUpDown3.Value); dstr[7] = (byte)(i >> 8); dstr[8] = (byte)(i); len += 2; //目标地址 addr = 0x00; addr <<= 8; addr += 0xB1; //整理数据 bytes = GetData(dstr, 0xF001, addr, len); len = len + 0x0b + 1; String str2 = ListbyteToHexStr(bytes, len); sp1.Write(bytes, 0, len); //写入数据 if (txtReceive.Text.Trim() == "") { txtReceive.Text = "发送成功!" + System.Environment.NewLine; } else { txtReceive.Text = txtReceive.Text + System.Environment.NewLine + "发送成功!" + System.Environment.NewLine; } txtReceive.Focus(); txtReceive.SelectionStart = txtReceive.TextLength; //插入到数据库 int UE = comboBox2.SelectedIndex; //测量功能: 00 直行程 01 角行程 int UF = comboBox1.SelectedIndex; //控制电机运行: 00 停止 01 运行 02 - 运动到起始点 03 - 运动到结束点 int UG = comboBox3.SelectedIndex; //运行模式: 00 点动 01 连续 double UH = Convert.ToDouble( numericUpDown1.Value); //电机运行多少圈为一个步长; 00 00 (65535)毫米 int UI = Convert.ToInt16(numericUpDown2.Value); //电机运行间隔时长: 00 00 (65535)毫秒(数据反馈时间) int UJ = Convert.ToInt16(numericUpDown3.Value); //到“结束点”后,停止时间 00 00 (65535)毫秒 string UK = Convert.ToString(DateTime.Now.ToString("G"));//日期 string UL = Uc;//人员编码ID string UM = textBox1.Text;//磁条编号 OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open(); //建立SQL语句 string sqlstr = ""; sqlstr = @"INSERT INTO 发送数据记录([测量功能], [控制电机运行], [运行模式], [电机运行步长],[间隔时长], [停止时间], [发送时间], [人员编码ID],[磁条编号],[测试编号ID])VALUES("; sqlstr += "'" + UE + "', '" + UF + "', '" + UG + "', '" + UH + "', '" + UI + "', '" + UJ + "', '" + UK + "', '" + UL + "','" + UM + "', '" + UOP_ID + "' )"; OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; cmd.ExecuteNonQuery(); conn.Close(); } /// /// 开始测试 / 结束测试 /// /// /// private void button2_Click(object sender, EventArgs e) { if(button2.Text == "开始测试") { textBox1.ReadOnly= true; button1.Visible = true; button2.Text = "结束测试"; tmSend.Enabled = true; //插入到数据库 //定义字段 string UK = Convert.ToString(DateTime.Now.ToString("G"));//日期 string UL = Uc;//人员编码ID string UM = textBox1.Text;//磁条编号 string UN = comboBox4.Text;//磁条规格 //插入数据库 OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open(); //建立SQL语句 string sqlstr = ""; sqlstr = @"INSERT INTO 磁条测试记录([磁条编号], [开始时间], [结束时间], [磁条规格], [人员编码ID]) VALUES("; sqlstr += "'" + UM + "','" + UK + "','" + UK + "','" + UN + "','" + UL + "')"; OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; cmd.ExecuteNonQuery(); //获取当前插入数据的ID cmd.CommandText = "SELECT @@IDENTITY"; UOP_ID = (int)cmd.ExecuteScalar(); conn.Close(); reverice_flag = true; FormData fd = new FormData(); fd.UOP_ID = UOP_ID; fd.textBox13.Text = System.DateTime.Now.ToString("g"); fd.textBox2.Text = UM; fd.textBox5.Text = UN; fd.textBox14.Text = numericUpDown1.Text; fd.textBox15.Text = comboBox3.Text; fd.ShowDialog(); if (fd.DialogResult == DialogResult.OK) { textBox1.Text = fd.textBox2.Text; } //点击开始测试清除之前数据 foreach (var series in chart1.Series) { series.Points.Clear(); } } else { textBox1.ReadOnly = false; button2.Text = "开始测试"; tmSend.Enabled = false; button1.Visible = false; //更新数据库 //定义字段 string UK = Convert.ToString(DateTime.Now.ToString("G"));//日期 //插入数据库 OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open(); //建立SQL语句 string sqlstr = ""; sqlstr = @"UPDATE 磁条测试记录 set [结束时间] = '" + UK + "'"; sqlstr += " where [ID] = " + UOP_ID + ""; OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; cmd.ExecuteNonQuery(); conn.Close(); reverice_flag = false; } } int ss_flag = 0; private void button4_Click(object sender, EventArgs e) { ss_flag++; if (ss_flag >= 3) ss_flag = 0; switch (ss_flag) { case 1: { chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.False;//将X轴始终展示 } break; case 2: { chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.Auto;//将X轴始终展示 } break; default: { chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;//将X轴始终展示 } break; } } private void FormMain_FormClosed(object sender, FormClosedEventArgs e) { Application.Exit(); } public struct DP_Data { public int Travle_Flag; public int Motor_Run; public int Run_Mode; public int getS; public int getV1; public int getV2; public double actd1; public string getTimer; public int state;//磁条位置 public int MT_size; }; /// /// 根据查询条件,得出数据到图标 /// /// /// private void button3_Click_1(object sender, EventArgs e) { Init_Chart2(); string sdate = "";//dateTimePicker1.Value + " " + dateTimePicker3.Text; string edate = "";//dateTimePicker1.Value + " " + dateTimePicker2.Text; sdate = dateTimePicker1.Value.Year.ToString() + "/" + dateTimePicker1.Value.Month.ToString() + "/" + dateTimePicker1.Value.Day.ToString(); edate = sdate; sdate += " " + dateTimePicker3.Text; edate += " " + dateTimePicker2.Text; int j = 0; //建立SQL语句 string sqlstr = ""; sqlstr = @"select * from [磁条数据记录] where [磁条编号] = '" + textBox2.Text + "' and (接收数据时间 between #" + sdate + "# and #" + edate + "#) order by[接收时间值] asc"; OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open();//打开数据 OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; try { DP_Data[] array = new DP_Data[0]; //建立读取 OleDbDataReader odrReader; odrReader = cmd.ExecuteReader(); while (odrReader.Read()) { Array.Resize(ref array, array.Length + 1); array[array.Length - 1].Travle_Flag = Convert.ToInt16(odrReader[2]); array[array.Length - 1].Motor_Run = Convert.ToInt16(odrReader[3]); array[array.Length - 1].Run_Mode = Convert.ToInt16(odrReader[4]); array[array.Length - 1].getS = Convert.ToInt16(odrReader[5]); array[array.Length - 1].getV1 = Convert.ToUInt16((Convert.ToInt16(odrReader[6]) ));//转成实际电压 array[array.Length - 1].getV2 = Convert.ToUInt16((Convert.ToInt16(odrReader[7]) * 3300) / 4096);//转成实际电压 array[array.Length - 1].actd1 = Convert.ToDouble(Convert.ToDouble(odrReader[9]));//转成实际距离 array[array.Length - 1].getTimer = odrReader[10].ToString(); array[array.Length - 1].MT_size = Convert.ToInt16(odrReader[13]); j++; } //关闭连接 C#操作Access之读取mdb odrReader.Close(); conn.Close();//关闭数据库 if (j == 0) { MessageBox.Show("该时间段范围内无数据,请重新选择时间!"); } else { int dlen = 0; for (dlen = 0; dlen < j; dlen++) { //分析在界面上 if (array[dlen].Travle_Flag == 0) label56.Text = "直行程"; else label56.Text = "角行程"; if (array[dlen].Motor_Run == 0) label36.Text = "停止"; else if (Motor_Run == 1) label36.Text = "运行"; else if (Motor_Run == 2) label36.Text = "运动到起始点"; else if (Motor_Run == 3) label36.Text = "运动到结束点"; else label36.Text = "错误"; if (array[dlen].Run_Mode == 0) label35.Text = "点动"; else label35.Text = "连续"; switch (array[dlen].getS) { case 1: { label34.Text = "起始位"; } break; case 2: { label34.Text = "结束位"; } break; default: { label34.Text = "无状态"; } break; } switch (array[dlen].MT_size) { case 0: { label55.Text = "角行程"; } break; case 1: { label55.Text = "直行程#25"; } break; case 2: { label55.Text = "直行程#50"; } break; case 3: { label55.Text = "直行程#110"; } break; case 4: { label55.Text = "直行程#210"; } break; case 5: { label55.Text = "特殊"; } break; default: { label55.Text = "错误"; } break; } label33.Text = Convert.ToString(array[dlen].getV1); label62.Text = Convert.ToString(array[dlen].actd1); label57.Text = Convert.ToString(dlen);//总条数 int i = chart2.Series[0].Points.AddXY(Convert.ToString(array[dlen].actd1), Convert.ToString(array[dlen].getV1)); if (chart2.ChartAreas[0].AxisX.ScaleView.Size > 0) { chart2.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } chart2.Series[0].Points[i].MarkerStyle = MarkerStyle.Diamond; chart2.Series[0].Points[i].MarkerColor = Color.Red; chart2.Series[0].Points[i].MarkerBorderWidth = 3; chart2.Series[0].Points[i].MarkerSize = 10; chart2.Series[0].Points[i].Label = "#VAL"; if (dlen == j - 1) { MessageBox.Show("数据读取完成!"); } } if (chart2.ChartAreas[0].AxisX.ScaleView.Size > 0) { chart2.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.First); } } } catch (Exception ex) { MessageBox.Show("数据异常"); } finally { if (cmd.Connection.State == ConnectionState.Open) { cmd.Connection.Close(); } } } private void button5_Click(object sender, EventArgs e) { string str3 = Directory.GetCurrentDirectory(); Init_Chart3(); string sdate = "";//dateTimePicker1.Value + " " + dateTimePicker3.Text; string edate = "";// dateTimePicker1.Value + " " + dateTimePicker2.Text; sdate = dateTimePicker6.Value.Year.ToString() + "/" + dateTimePicker6.Value.Month.ToString() + "/" + dateTimePicker6.Value.Day.ToString(); edate = sdate; sdate += " " + dateTimePicker4.Text; edate += " " + dateTimePicker5.Text; int j = 0; listView1.Items.Clear();//清除原来的查询结果 //建立SQL语句 string sqlstr = ""; sqlstr = @"select * from [磁条测试记录] where [磁条编号] like '%" + textBox3.Text + "%' and ([开始时间] between #" + sdate + "# and #" + edate + "#) order by [开始时间] DESC"; //ASC DESC [磁条编号] = '" + textBox3.Text + "' [ID],[磁条编号],[磁条规格].[开始时间],[结束时间] OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open();//打开数据 OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; //建立读取 OleDbDataReader odrReader; odrReader = cmd.ExecuteReader(); while (odrReader.Read()) { ListViewItem lvi = new ListViewItem(); lvi.Text = odrReader[0].ToString(); lvi.SubItems.Add(odrReader[1].ToString()); lvi.SubItems.Add(odrReader[4].ToString()); lvi.SubItems.Add(odrReader[2].ToString()); lvi.SubItems.Add(odrReader[3].ToString()); this.listView1.Items.Add(lvi); j++; } //关闭连接 C#操作Access之读取mdb odrReader.Close(); conn.Close();//关闭数据库 if (j == 0) { MessageBox.Show("该时间段范围内无数据,请重新选择时间!"); } } public struct RE_Data { public double d;//磁条长度 public int v;//采样电压 }; /// /// 利用两点法进行线性拟合 y = kx + b, /// public static void LinearFit(double[] x, double[] y, out double k, out double b) { // Ax+By+C=0 double A = 0; double B = 0; double C = 0; int m = x.Length; A = y[m - 1] - y[0]; B = x[0] - x[m - 1]; C = x[m - 1] * y[0] - x[0] * y[m - 1]; k = -(A / B); b = -(C / B); return; } /// /// 更新数组y,替换为电压理论值 /// /// /// /// /// public static void LinearVal(double[] x, double[] y, double k, double b) { for (int i = 0; i < x.Length; i++) { y[i] = k * x[i] + b; } } public static void LinearIndex(double[] x, double[] y, out double z) { double a = 0; double b = 0; double c = 0; for(int i = 0;i < x.Length;i++) { a += (y[i] - x[i]) * (y[i] - x[i]); b += x[i]; } b = b / x.Length; for (int j = 0; j < x.Length; j++) { c += (x[j] - b) * (x[j] - b); } z = 1 - a / c; } /// /// 数据分析,计算回差和线性度 /// private void analy(DP_Data[] array, int num1, int num2,int a, double c) { int num = Convert.ToUInt16((num2 - num1) / c);//有效数据个数 int Tom = 0; double Jerry = 0; int num_flag = 0; int m1 = 0; //有效数据数组存放起始序号 int m2 = num - 1; //有效数据数组存放末尾序号 double _huicha = 0; //最大差值 double vmin = 9999; //用于确定最小电压 double vmax = 0; //用于确定最小电压 double dmax = 0; //最大磁条长度 double vp = 0; //线性误差值 double _v = 0; //最大线性误差 double r = 0; //最大计数值 double r1 = 0; //正转同一点的差值超出标准计数 double r2 = 0; //反转同一点的差值超出标准计数 double w = 0; double w1 = 0; double w2 = 0; int flag = 0; //数据改变标志 int i1 = 0; //正转数组序号 int i2 = 0; //反转数组序号 Double[] mtdata1 = new Double[num]; //存储正转电压数值 Double[] mtdata2 = new Double[num]; //存储反转电压数值 Array.Clear(mtdata1, 0, mtdata1.Length); //数组每个元素置零 Array.Clear(mtdata2, 0, mtdata2.Length); //数组每个元素置零 Double[] x = new Double[num]; //存储磁条长度 Double[] y = new Double[num]; //存储电压数值 Array.Clear(x, 0, x.Length); //数组每个元素置零 Array.Clear(y, 0, y.Length); //数组每个元素置零 Double[] xx = new Double[num]; //存储磁条长度 Double[] yy = new Double[num]; //存储电压数值 Array.Clear(xx, 0, xx.Length); //数组每个元素置零 Array.Clear(yy, 0, yy.Length); //数组每个元素置零 RE_Data[] redata1 = new RE_Data[a];// RE_Data[] redata2 = new RE_Data[a];// Array.Clear(redata1, 0, redata1.Length); //数组每个元素置零 Array.Clear(redata2, 0, redata2.Length); //数组每个元素置零 //遍历数据 for (int n1 = 0; n1 < a; n1++) { Int16 v = Convert.ToInt16(array[n1].getV1); //电压值v = 0; double d = Convert.ToDouble(array[n1].actd1); //磁条长度d = 0; int s = Convert.ToUInt16(array[n1].state); //状态,3为正转,4为反转s = 0; if (v < vmin) { vmin = v; } if (v > vmax) { vmax = v; } if (d > dmax) dmax = d;//最大磁条长度 //正转重复性偏差 if (s == 3 ) { i2 = 0;//反转数组序号置0,方便后面调用 //存储第一组数据 if (redata1[i1].v == 0 || Math.Abs(redata1[i1].v - v) > 100) { redata1[i1].v = v;//采样电压 redata1[i1].d = d;//磁条长度 i1++; } else { //第一组数据与后续数据对比 if (redata1[i1].d == d) { w1 = System.Math.Abs(redata1[i1].v - v); if (Convert.ToDouble(w1 / ((v + redata1[i1].v) / 2)) > r1) { r1 = Convert.ToDouble(w1 / ((v + redata1[i1].v) / 2)); } } i1++; } } //反转重复性偏差 if (s == 4) { i1 = 0;//正转数组序号置0,方便后面调用 //存储第一组数据 if (redata2[i2].v == 0 || Math.Abs(redata1[i1].v - v) > 100) { redata2[i2].v = v;//采样电压 redata2[i2].d = d;//磁条长度 i2++; } else { //第一组数据与后续数据对比 if (redata2[i2].d == d) { w2 = System.Math.Abs(redata2[i2].v - v); if (Convert.ToDouble(w2 / ((v + redata2[i2].v) / 2)) > r2) { r2 = Convert.ToDouble(w2 / ((v + redata2[i2].v) / 2)); } } i2++; } } //取最大计数值 if (r1 > r2) r = r1; else r= r2; //取最大误差值 if (w1 > w2) w = w1; else w = w2; //分别存储来回有效数据 if (num1 <= d && m1 <= num - 1 && s == 3) { x[m1] = d; y[m1] = v; mtdata1[m1] = v; m1++; } if (0 <= m2 && d < num2 && s == 4) { xx[m2] = d; yy[m2] = v; mtdata2[m2] = v; m2--; } } double re = 1 - r; //拟合直线y = kx + b double k, b; double index = 0; LinearFit(x, y, out k, out b); LinearVal(x, y ,k, b); LinearIndex(mtdata1, y, out index); textBox4.Text = "拟合直线:" + "y = " + k.ToString("F3") + "x + " + b.ToString("F3"); textBox5.Text = "R^2 = " + index.ToString("F5"); //获取最大回差与最大线性误差 for (int n2 = 0; n2 <= num - 1; n2++) { if (mtdata2[n2] > 0) { if (_huicha < System.Math.Abs(mtdata1[n2] - mtdata2[n2])) { _huicha = System.Math.Abs(mtdata1[n2] - mtdata2[n2]);//取最大差值 } } vp = System.Math.Abs(mtdata1[n2] - y[n2]);//计算实际电压与理论电压差值 if (vp > _v) { if (mtdata1[n2] > y[n2]) { num_flag = 1; } else { num_flag = 0; } _v = vp;//取最大差值 Tom = n2; Jerry = x[n2]; } } double huicha = 0; huicha = System.Math.Abs(Convert.ToDouble(_huicha) / (mtdata1[num - 1] - mtdata1[0]));//计算回差 double xianxingdu = 0; xianxingdu = System.Math.Abs(Convert.ToDouble(_v) / (mtdata1[num - 1] - mtdata1[0]));//计算线性度 double chongfuxing = 0; chongfuxing = System.Math.Abs(re);//重复性 double wucha = 0; wucha = System.Math.Abs(w / (vmax-vmin));//误差 if (huicha > 0.5) { label63.Text = "ERROR";//显示回差值 } else { label63.Text = huicha.ToString("P3");//显示回差值 } if (xianxingdu > 0.5) { label67.Text = "ERROR";//显示回差值 } else { label67.Text = xianxingdu.ToString("P3");//显示线性度 } if (chongfuxing < 0.3) { label72.Text = "ERROR";//显示回差值 } else { label72.Text = chongfuxing.ToString("P3");//显示线性度 } label74.Text = wucha.ToString("P3");//显示误差 if (huicha < (Convert.ToDouble(numericUpDown4.Value) / 100) && xianxingdu < (Convert.ToDouble(numericUpDown5.Value) / 100) && chongfuxing > (Convert.ToDouble(numericUpDown6.Value) / 100) && wucha < (Convert.ToDouble(numericUpDown7.Value) / 100)) { label71.Text = "合格"; this.label71.ForeColor = Color.Green; //颜色 } else { label71.Text = "不合格"; this.label71.ForeColor = Color.Red; //颜色 } if(num_flag == 1) textBox9.Text = "最大误差位于磁条长度" + Jerry + "处,误差为" + _v + "mv"; else textBox9.Text = "最大误差位于磁条长度" + Jerry + "处,误差为-" + _v + "mv"; } /// /// 双击 得到某一行的数据 /// /// /// private void listView1_MouseDoubleClick(object sender, MouseEventArgs e) { if (listView1.SelectedIndices.Count > 0) { Init_Chart3(); int j = 0; string iud = ""; string ctid = ""; string sdate = ""; string edate = ""; iud = listView1.SelectedItems[0].Text; ctid = listView1.SelectedItems[0].SubItems[1].Text; sdate = listView1.SelectedItems[0].SubItems[3].Text; edate = listView1.SelectedItems[0].SubItems[4].Text; //建立SQL语句 string sqlstr = ""; sqlstr = @"select [采样电压],[激光电压],[磁条长度],[接收数据时间],[到位开关状态],[磁条规格],[磁条步长] from [磁条数据记录] where [磁条编号] = '" + ctid + "'"; sqlstr += " and ([接收数据时间] between #" + sdate + "# and #" + edate + "#)"; sqlstr += " and [测试编号ID] = " + iud + " order by [接收时间值] asc"; OleDbConnection conn; conn = new OleDbConnection(ConSql); conn.Open();//打开数据 OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; try { DP_Data[] array = new DP_Data[0]; DP_Data[] array1 = new DP_Data[5]; double step = 0; //建立读取 OleDbDataReader odrReader; odrReader = cmd.ExecuteReader(); while (odrReader.Read()) { Array.Resize(ref array, array.Length + 1); array[array.Length - 1].getV1 = Convert.ToUInt16((Convert.ToInt16(odrReader[0])));//转成实际电压 array[array.Length - 1].getV2 = Convert.ToUInt16((Convert.ToInt16(odrReader[1]) * 3300) / 4096);//转成实际电压 array[array.Length - 1].actd1 = Convert.ToDouble(Convert.ToDouble(odrReader[2]));//转成磁条实际长度 array[array.Length - 1].getTimer = odrReader[3].ToString(); array[array.Length - 1].state = Convert.ToUInt16((Convert.ToInt16(odrReader[4])));// array[array.Length - 1].MT_size = Convert.ToInt16(odrReader[5]); j++; step = Convert.ToDouble(odrReader[6]); } //关闭连接 C#操作Access之读取mdb odrReader.Close(); conn.Close();//关闭数据库 if (j == 0) { MessageBox.Show("该时间段范围内无数据,请重新选择时间!"); } else { label51.Text = Convert.ToString(j); int dlen = 0; int size = 0; int flag_01 = 0; int flag_25 = 0; int flag_50 = 0; int flag_110 = 0; int flag_210 = 0; for (dlen = 0; dlen < j; dlen++) { int v1 = 0; v1 = Convert.ToUInt16(array[dlen].getV1);//转成实际电压 * 3300) / 4096 size = Convert.ToUInt16(array[dlen].MT_size); int i = chart3.Series[0].Points.AddXY(Convert.ToDouble(array[dlen].actd1), Convert.ToInt32(array[dlen].getV1)); if(array[dlen].actd1 == 1 && flag_01 == 0) { flag_01 = 1; array1[0].actd1 = array[dlen].actd1; array1[0].getV1 = array[dlen].getV1; } if (array[dlen].actd1 == 25 && flag_25 == 0) { flag_25 = 1; array1[1].actd1 = array[dlen].actd1; array1[1].getV1 = array[dlen].getV1; } if (array[dlen].actd1 == 50 && flag_50 == 0) { flag_50 = 1; array1[2].actd1 = array[dlen].actd1; array1[2].getV1 = array[dlen].getV1; } if (array[dlen].actd1 == 110 && flag_110 == 0) { flag_110 = 1; array1[3].actd1 = array[dlen].actd1; array1[3].getV1 = array[dlen].getV1; } if (array[dlen].actd1 == 210 && flag_210 == 0) { flag_210 = 1; array1[4].actd1 = array[dlen].actd1; array1[4].getV1 = array[dlen].getV1; } if (chart3.ChartAreas[0].AxisX.ScaleView.Size > 0) { chart3.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } chart3.Series[0].Color = Color.Black; chart3.Series[0].Points[i].MarkerStyle = MarkerStyle.Diamond; chart3.Series[0].Points[i].MarkerColor = Color.Red; chart3.Series[0].Points[i].MarkerBorderWidth = 3; chart3.Series[0].Points[i].MarkerSize = 5; chart3.Series[0].Points[i].IsValueShownAsLabel = false; if (dlen == j - 1) { MessageBox.Show("数据获取完成!"); } } label77.Visible = false; label78.Visible = false; numericUpDown8.Visible = false; numericUpDown9.Visible = false; switch (size) { case 0: { label77.Visible = true; label78.Visible = true; numericUpDown8.Visible = true; numericUpDown9.Visible = true; analy(array, Convert.ToUInt16(numericUpDown8.Value), Convert.ToUInt16(numericUpDown9.Value), j, step); } break; case 1: { analy(array, 1, 25, j, step); List xData = new List() { array1[0].actd1, array1[1].actd1}; List yData = new List() { array1[0].getV1, array1[1].getV1 }; chart3.Series[1].Color = Color.MediumBlue; chart3.Series[1].BorderWidth = 1; chart3.Series[1].MarkerSize = 8; chart3.Series[1].Points.DataBindXY(xData, yData); } break; case 2: { analy(array, 1, 50, j, step); List xData = new List() { array1[0].actd1, array1[2].actd1 }; List yData = new List() { array1[0].getV1, array1[2].getV1 }; chart3.Series[1].Color = Color.MediumBlue; chart3.Series[1].BorderWidth = 1; chart3.Series[1].MarkerSize = 5; chart3.Series[1].Points.DataBindXY(xData, yData); } break; case 3: { analy(array, 1, 110, j, step); List xData = new List() { array1[0].actd1, array1[3].actd1 }; List yData = new List() { array1[0].getV1, array1[3].getV1 }; chart3.Series[1].Color = Color.MediumBlue; chart3.Series[1].BorderWidth = 1; chart3.Series[1].MarkerSize = 8; chart3.Series[1].Points.DataBindXY(xData, yData); } break; case 4: { analy(array, 1, 210, j, step); List xData = new List() { array1[0].actd1, array1[4].actd1 }; List yData = new List() { array1[0].getV1, array1[4].getV1 }; chart3.Series[1].Color = Color.MediumBlue; chart3.Series[1].BorderWidth = 1; chart3.Series[1].MarkerSize = 8; chart3.Series[1].Points.DataBindXY(xData, yData); } break; case 5: { label77.Visible = true; label78.Visible = true; numericUpDown8.Visible = true; numericUpDown9.Visible = true; analy(array, Convert.ToUInt16(numericUpDown8.Value), Convert.ToUInt16(numericUpDown9.Value), j, step); } break; default: { label63.Text = "ERROR";//显示回差值 } break; } } } catch (Exception ex) { throw new Exception(ex.Message, ex); MessageBox.Show("数据异常"); } finally { if (cmd.Connection.State == ConnectionState.Open) { cmd.Connection.Close(); } } } } private void SavePic(Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet, string rangename, string filename) { Microsoft.Office.Interop.Excel.Range range = xlWorkSheet.get_Range(rangename, Type.Missing); xlWorkSheet.Activate(); range.Select(); ///////////// float PicLeft, PicTop, PicWidth, PicHeight;//距离左边距离,顶部距离,图片宽度、高度 PicTop = Convert.ToSingle(Convert.ToDouble(range.Top)); PicWidth = Convert.ToSingle(Convert.ToDouble(range.MergeArea.Width)); PicHeight = Convert.ToSingle(Convert.ToDouble(range.Height) * 17); PicWidth = Convert.ToSingle(Convert.ToDouble(range.Width) * 6); PicLeft = Convert.ToSingle(Convert.ToDouble(range.Left)); //////////////////// Microsoft.Office.Interop.Excel.Pictures pict = (Microsoft.Office.Interop.Excel.Pictures)xlWorkSheet.Pictures(Type.Missing); if (filename.IndexOf(".") > 0) { xlWorkSheet.Shapes.AddPicture(filename, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, PicLeft, PicTop, PicWidth, PicHeight);//指定位置显示小图 } } public void ExportToExcel(DataTable dt, string templatePath, string filePath, string picturePath) { string iud = ""; iud = listView1.SelectedItems[0].Text; Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(templatePath); Microsoft.Office.Interop.Excel.Worksheet worksheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1]; Microsoft.Office.Interop.Excel.Worksheet worksheet2 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[2]; try { worksheet1.Cells[3, 4] = dt.Rows[0][0].ToString(); worksheet1.Cells[5, 4] = dt.Rows[0][2].ToString(); worksheet1.Cells[7, 4] = dt.Rows[0][3].ToString(); worksheet1.Cells[9, 4] = dt.Rows[0][6].ToString(); worksheet1.Cells[11, 4] = dt.Rows[0][8].ToString(); worksheet1.Cells[13, 4] = dt.Rows[0][10].ToString(); worksheet1.Cells[15, 4] = dt.Rows[0][12].ToString(); worksheet1.Cells[17, 4] = dt.Rows[0][14].ToString(); worksheet1.Cells[19, 4] = dt.Rows[0][15].ToString(); worksheet1.Cells[3, 7] = dt.Rows[0][1].ToString(); worksheet1.Cells[5, 7] = dt.Rows[0][5].ToString(); worksheet1.Cells[7, 7] = dt.Rows[0][4].ToString(); worksheet1.Cells[9, 7] = dt.Rows[0][7].ToString(); worksheet1.Cells[11, 7] = dt.Rows[0][9].ToString(); worksheet1.Cells[13, 7] = dt.Rows[0][11].ToString(); worksheet1.Cells[15, 7] = dt.Rows[0][13].ToString(); worksheet1.Cells[40, 4] = dt.Rows[0][16].ToString(); worksheet1.Cells[42, 4] = dt.Rows[0][18].ToString(); worksheet1.Cells[40, 7] = dt.Rows[0][17].ToString(); worksheet1.Cells[42, 7] = dt.Rows[0][19].ToString(); worksheet1.Cells[44, 7] = label71.Text; if(label71.Text == "不合格") { Microsoft.Office.Interop.Excel.Range range = worksheet1.get_Range(worksheet1.Cells[44, 7], worksheet1.Cells[45, 8]); range.Font.ColorIndex = 3; } else { Microsoft.Office.Interop.Excel.Range range = worksheet1.get_Range(worksheet1.Cells[44, 7], worksheet1.Cells[45, 8]); range.Font.ColorIndex = 10; } // 插入图片 try { // C19位置插入图片,picturePath为图片路径 SavePic(worksheet1, "C22", picturePath); // 删除本地图片文件,后续可改为使用流,省去删除图片的步骤 System.IO.File.Delete(picturePath); } catch (Exception) { throw; } //建立SQL语句 string cqlstr = ""; cqlstr = @"select * from [磁条数据记录] where [测试编号ID] = " + iud + " order by [接收时间值] asc"; OleDbConnection sonn; sonn = new OleDbConnection(ConSql); sonn.Open();//打开数据 OleDbCommand smd = sonn.CreateCommand(); smd.CommandText = cqlstr; OleDbDataReader Reader; Reader = smd.ExecuteReader(); try { int j = 2; int size = 0; int mstate = 0; while (Reader.Read()) { mstate = Convert.ToInt16(Reader[5]); worksheet2.Cells[j, 5] = Convert.ToInt16(Reader[6]); worksheet2.Cells[j, 4] = Convert.ToDouble(Reader[9]); worksheet2.Cells[j, 1] = Reader[11].ToString(); if(Convert.ToInt16(Reader[5]) != 3 && Convert.ToInt16(Reader[5]) != 4) { worksheet2.Cells[j, 4] = "###"; } switch (mstate) { case 1: { worksheet2.Cells[j, 3] = "始限位"; } break; case 2: { worksheet2.Cells[j, 3] = "终限位"; } break; case 3: { worksheet2.Cells[j, 3] = "正转测量"; } break; case 4: { worksheet2.Cells[j, 3] = "反转测量"; } break; default: { worksheet2.Cells[j, 3] = "无状态"; } break; } size = Convert.ToInt16(Reader[13]); switch (size) { case 0: { worksheet2.Cells[j, 2] = "角行程"; } break; case 1: { worksheet2.Cells[j, 2] = "直行程#25"; } break; case 2: { worksheet2.Cells[j, 2] = "直行程#50"; } break; case 3: { worksheet2.Cells[j, 2] = "直行程#110"; } break; case 4: { worksheet2.Cells[j, 2] = "直行程#210"; } break; case 5: { worksheet2.Cells[j, 2] = "特殊"; } break; default: { worksheet2.Cells[j, 2] = "错误"; } break; } j++; } } catch (Exception) { MessageBox.Show("文件保存失败"); throw; } workbook.SaveAs(filePath); excel.Quit(); } catch (Exception ex) { throw ex; } finally { releaseObject(worksheet1); releaseObject(worksheet2); releaseObject(workbook); releaseObject(excel); } } // 释放导出文件时占用的资源 private void releaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; throw ex; } finally { GC.Collect(); } } private void button7_Click(object sender, EventArgs e) { button7.Text = "保存中..."; string iud = ""; iud = listView1.SelectedItems[0].Text; // 初始化变量 DataTable dt = new DataTable(); // 初始化文件保存地址,当前,模板地址以及导出文件的保存路径均为可执行程序所在文件夹,后续可传参进来 string appPath = Directory.GetCurrentDirectory(); string templatePath = appPath + @"\test_file\temp\Import.xlsx";//D:\桌面\测试记录\模板 string time_str = System.DateTime.Now.ToString("yyyyMMddHHmmss"); string picturePath = appPath + @"\test_file\image\" + time_str + ".jpeg"; chart3.SaveImage(picturePath, System.Windows.Forms.DataVisualization.Charting.ChartImageFormat.Png); //从数据库取数据 OleDbConnection conn;//数据库连接 conn = new OleDbConnection(ConSql); conn.Open(); //建立SQL语句 string sqlstr = ""; sqlstr = @"select [测试人员],[测试时间],[磁条编号],[温度],[天气],[测试地址],[名称],[制造商],[型号规格],[材质],[测试设备],[联系方式],[步长],[运行模式],[注意事项],[备注] from [测试信息] where [测试编号] = " + iud; OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlstr; // 变量定义 String KA = ""; String KB = ""; String KC = ""; String KD = ""; String KE = ""; String KF = ""; String KG = ""; String KH = ""; String KI = ""; String KJ = ""; String KK = ""; String KL = ""; String KM = ""; String KN = ""; String KO = ""; String KP = ""; //建立读取G OleDbDataReader odrReader; odrReader = cmd.ExecuteReader(); while (odrReader.Read()) { KA = odrReader[0].ToString(); KB = odrReader[1].ToString(); KC = odrReader[2].ToString(); KD = odrReader[3].ToString(); KE = odrReader[4].ToString(); KF = odrReader[5].ToString(); KG = odrReader[6].ToString(); KH = odrReader[7].ToString(); KI = odrReader[8].ToString(); KJ = odrReader[9].ToString(); KK = odrReader[10].ToString(); KL = odrReader[11].ToString(); KM = odrReader[12].ToString(); KN = odrReader[13].ToString(); KO = odrReader[14].ToString(); KP = odrReader[15].ToString(); } //关闭连接 C#操作Access之读取mdb odrReader.Close(); conn.Close();//关闭数据库 try { // 添加导出所需的对应字段 dt.Columns.Add("测试人员", typeof(string)); dt.Columns.Add("测试时间", typeof(string)); dt.Columns.Add("磁条编号", typeof(string)); dt.Columns.Add("温度", typeof(string)); dt.Columns.Add("湿度", typeof(string)); dt.Columns.Add("测试地址", typeof(string)); dt.Columns.Add("名称", typeof(string)); dt.Columns.Add("制造商", typeof(string)); dt.Columns.Add("型号规格", typeof(string)); dt.Columns.Add("材质", typeof(string)); dt.Columns.Add("测试设备", typeof(string)); dt.Columns.Add("联系信息", typeof(string)); dt.Columns.Add("步长", typeof(string)); dt.Columns.Add("运行模式", typeof(string)); dt.Columns.Add("注意事项", typeof(string)); dt.Columns.Add("备注", typeof(string)); dt.Columns.Add("线性度", typeof(string)); dt.Columns.Add("回差", typeof(string)); dt.Columns.Add("误差", typeof(string)); dt.Columns.Add("重复性", typeof(string)); // 对应值,需要经过查表以及计算得出 dt.Rows.Add(KA, KB, KC, KD, KE, KF, KG, KH, KI, KJ, KK, KL, KM, KN, KO, KP, label67.Text.ToString(), label63.Text.ToString(), label74.Text.ToString(),label72.Text.ToString()); string filePath = appPath + @"\test_file\" + KP + "报告_" + iud+ time_str + ".xlsx"; // 执行导出 ExportToExcel(dt, templatePath, filePath, picturePath); button7.Text = "导出"; MessageBox.Show("文件已保存至" + filePath); } catch (Exception) { MessageBox.Show("文件保存失败"); } } private void comboBox2_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox2.SelectedIndex == 0) { checkBox1.Enabled = false; label58.Text = "磁条长度="; label59.Text = "毫米"; label29.Text = "毫米"; label11.Text = "停止时长"; label31.Text = "秒"; numericUpDown3.Value = 5; chart1.Series[0].ChartType = SeriesChartType.Line; //设置坐标轴标题 chart1.ChartAreas[0].AxisY.Title = "电压值"; chart1.ChartAreas[0].AxisY.TitleForeColor = System.Drawing.Color.Crimson; chart1.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Horizontal; chart1.ChartAreas[0].AxisY.IsStartedFromZero = false; chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色 chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色 chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条,也可以不关闭,就可以滑动 chart1.Series[0].BorderWidth = 2;//线宽 } if (comboBox2.SelectedIndex == 1) { checkBox1.Enabled = true; label58.Text = "磁条角度="; label59.Text = "度"; label29.Text = "度"; label11.Text = "旋转角度"; label31.Text = "度"; numericUpDown3.Value = 360; chart1.Series[0].ChartType = SeriesChartType.Pie; //是否显示图例 chart1.Series[0].IsVisibleInLegend = true; chart1.Series[0].ShadowOffset = 0; //饼图折线 chart1.Series[0]["PieLineColor"] = "yellow"; //绑定数据 chart1.Series[0].Points.DataBindXY(x, y); chart1.Series[0].Points[0].Color = Color.Yellow; //绑定颜色 chart1.Series[0].Palette = ChartColorPalette.BrightPastel; } checkBox1_CheckedChanged(sender, e); } private void checkBox1_CheckedChanged(object sender, EventArgs e) { if (checkBox1.Checked == true) { chart1.Series[0].ChartType = SeriesChartType.Pie; } else { chart1.Series[0].ChartType = SeriesChartType.Line; Init_Chart1(); } //清除曲线内的数据 foreach (var series in chart1.Series) { series.Points.Clear(); } } private void button6_Click(object sender, EventArgs e) { if (button6.Text == "标准设定") { label69.Visible = true; label70.Visible = true; label73.Visible = true; label76.Visible = true; numericUpDown7.Visible = true; numericUpDown4.Visible = true; numericUpDown5.Visible = true; numericUpDown6.Visible = true; button6.Text = "保存"; } else { label69.Visible = false; label70.Visible = false; label73.Visible = false; label76.Visible = false; numericUpDown7.Visible = false; numericUpDown4.Visible = false; numericUpDown5.Visible = false; numericUpDown6.Visible = false; button6.Text = "标准设定"; } } private void chart3_MouseDown(object sender, MouseEventArgs e) { lastMove = 0; isMouseDown = true; } private void chart3_MouseUp(object sender, MouseEventArgs e) { isMouseDown = false; } private void chart3_MouseMove(object sender, MouseEventArgs e) { var area = chart3.ChartAreas[0]; double yValue = area.AxisY.PixelPositionToValue(e.Y); double xValue = area.AxisX.PixelPositionToValue(e.X); textBox6.Text = string.Format("电压:{0:F0}",yValue); textBox8.Text = string.Format("第{0:F0}个点", xValue); chart3.ChartAreas[0].CursorX.SetCursorPixelPosition(new PointF(e.X, e.Y), true); chart3.ChartAreas[0].CursorY.SetCursorPixelPosition(new PointF(e.X, e.Y), true); } private void chart2_MouseUp(object sender, MouseEventArgs e) { isMouseDown = false; } private void chart2_MouseDown(object sender, MouseEventArgs e) { lastMove = 0; isMouseDown = true; } public void go_begin() { //发送数据 if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //处理完成后需要清除 ClrRecData(); byte[] bytes = new byte[100]; byte[] dstr = new byte[100]; int len = 0; int i = 0; int addr = 0; //测量功能 选择 dstr[0] = 0; len += 1; //控制电机运行 dstr[1] = 2; len += 1; //运行模式 dstr[2] = Convert.ToByte(comboBox3.SelectedIndex); len += 1; //电机运行多少圈为一个步长 i = Convert.ToInt16((Convert.ToDouble(numericUpDown1.Value)) * 10); dstr[3] = (byte)(i >> 8); dstr[4] = (byte)(i); len += 2; //电机运行间隔时长 i = Convert.ToInt16(numericUpDown2.Value); dstr[5] = (byte)(i >> 8); dstr[6] = (byte)(i); len += 2; //到“结束点”后,停止时间 i = Convert.ToInt16(numericUpDown3.Value); dstr[7] = (byte)(i >> 8); dstr[8] = (byte)(i); len += 2; //目标地址 addr = 0x00; addr <<= 8; addr += 0xB1; //整理数据 bytes = GetData(dstr, 0xF001, addr, len); len = len + 0x0b + 1; String str2 = ListbyteToHexStr(bytes, len); sp1.Write(bytes, 0, len); //写入数据 if (txtReceive.Text.Trim() == "") { txtReceive.Text = "发送成功!" + System.Environment.NewLine; } else { txtReceive.Text = txtReceive.Text + System.Environment.NewLine + "发送成功!" + System.Environment.NewLine; } txtReceive.Focus(); txtReceive.SelectionStart = txtReceive.TextLength; } private void stopbutton_Click(object sender, EventArgs e) { //发送数据 if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //处理完成后需要清除 ClrRecData(); byte[] bytes = new byte[100]; byte[] dstr = new byte[100]; int len = 0; int i = 0; int addr = 0; //测量功能 选择 dstr[0] = Convert.ToByte(comboBox2.SelectedIndex); len += 1; //控制电机运行 dstr[1] = 0; len += 1; //运行模式 dstr[2] = Convert.ToByte(comboBox3.SelectedIndex); len += 1; //电机运行多少圈为一个步长 i = Convert.ToInt16((Convert.ToDouble(numericUpDown1.Value)) * 10); dstr[3] = (byte)(i >> 8); dstr[4] = (byte)(i); len += 2; //电机运行间隔时长 i = Convert.ToInt16(numericUpDown2.Value); dstr[5] = (byte)(i >> 8); dstr[6] = (byte)(i); len += 2; //到“结束点”后,停止时间 i = Convert.ToInt16(numericUpDown3.Value); dstr[7] = (byte)(i >> 8); dstr[8] = (byte)(i); len += 2; //目标地址 addr = 0x00; addr <<= 8; addr += 0xB1; //整理数据 bytes = GetData(dstr, 0xF001, addr, len); len = len + 0x0b + 1; String str2 = ListbyteToHexStr(bytes, len); sp1.Write(bytes, 0, len); //写入数据 if (txtReceive.Text.Trim() == "") { txtReceive.Text = "发送成功!" + System.Environment.NewLine; } else { txtReceive.Text = txtReceive.Text + System.Environment.NewLine + "发送成功!" + System.Environment.NewLine; } txtReceive.Focus(); txtReceive.SelectionStart = txtReceive.TextLength; } } }