c#学习心得(5)数据采集上位机开发

写在前面:

纪念一下2020/7/21 第一个使用C#开发的上位机项目整体框架成型,具体是采集传感器的力,并计算,实时显示力曲线,并将数据保存,

最初使用labview做出大致的效果,但是有一些bug,没有深入调试。而后因为visionpro的原因接触到C#,选择在.Net框架下开发上位机的Winform

程序,虽然真正用在其中的时间不多,但是也有想法到现在也过去几个月了。看了很多前辈的博客,参考了很多MSDN上的案例。非常感谢,特此

贴下源码,供其他同学参考,欢迎各位前辈评点。转载请注明博客来源

上位机功能:采集传感器力(串口通讯),计算强度,实时显示力曲线,保存原始数据到表格。

界面如下:

c#学习心得(5)数据采集上位机开发

源码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Windows.Forms.DataVisualization.Charting;
using System.Globalization;
using Excel = Microsoft.Office.Interop.Excel;//不能直接引用和chart冲突
using NPOI.HSSF.UserModel;
using System.IO;


namespace HostCoumputer_edition1
{
    
    public partial class frmDataRecive : Form
    {
        //实例化一个先进先出的队列
        private Queue<double> dataqueue = new Queue<double>(200);
        //每次删除或增加的点?????
        int num = 1;
        //定义一个接收15个字节的数组
        private byte[] receivedData = new byte[15];
        //定义全局变量txt 此处还需要更改如何使图表不更新这个初始值
        string txt;
        //定义一个timer变量?(字段)
      //  private static System.Timers.Timer t;
        private SerialPort sp;
        //定义一个bool变量控制serialport和timer的开启
      //  bool btnstop = false;
   

        public frmDataRecive()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
           
          
                SetSerialPort();
                InitChart();
               
                this.timer1.Start();
            
        }
        /// <summary>
        /// 设置串口参数
        /// </summary>
        private void SetSerialPort()
        {
           // int a = int.Parse(cbBaudateRate.Text);
           // int b = int.Parse(cbDataBits.Text);

            sp = new SerialPort();
            sp.BaudRate = 9600 ;
            sp.PortName = "COM1";
            sp.DataBits = 8;
            sp.Parity = Parity.None;
            sp.StopBits = StopBits.One;
            sp.ReadTimeout = -1;

            sp.DataReceived += new SerialDataReceivedEventHandler (serialPortDatarecived);
            if (sp.IsOpen)
            {
                sp.Close();

            }
         
            //设置 DataReceived 事件发生前内部输入缓冲区中的字节数为13
            sp.ReceivedBytesThreshold = 15;
          
          try
            {
                sp.Open();
            }
           catch (System.Exception ex)
           {
               MessageBox.Show("未能打开串口.\n" + ex.Message);
            }
          
      
        }
        /// <summary>
        /// datarecived方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPortDatarecived(object sender,
                        SerialDataReceivedEventArgs e)
        {

           sp = (SerialPort)sender;
            sp.Read(receivedData, 0, 15);
            //可将鼠标放在函数上查看注释 GetString(Byte[], Int32, Int32) The index of the first byte to decode.
            //选择数据中有用的几位
            txt = Encoding.ASCII.GetString(receivedData, 7, 4);
            sp.DiscardInBuffer();
            
           
        }
       
        private void InitChart()
        {
            //定义图表区域
            this.chart1.ChartAreas.Clear();
            ChartArea chartArea1 = new ChartArea("C1");
            this.chart1.ChartAreas.Add(chartArea1);
            //定义存储和显示点的容器
            this.chart1.Series.Clear();
            Series series1 = new Series("S1");
            series1.ChartArea = "C1";
            this.chart1.Series.Add(series1);
            //设置图表显示样式
            this.chart1.ChartAreas[0].AxisX.Minimum = 0;
            this.chart1.ChartAreas[0].AxisX.Maximum = 150;
            this.chart1.ChartAreas[0].AxisY.Minimum = 0;
            this.chart1.ChartAreas[0].AxisY.Maximum =500;
            this.chart1.ChartAreas[0].AxisX.Interval = 10;
            this.chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver;
            this.chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver;
            //设置标题
            this.chart1.Titles.Clear();
            this.chart1.Titles.Add("S01");
            this.chart1.Titles[0].Text = "力曲线显示";
            this.chart1.Titles[0].ForeColor = Color.RoyalBlue;
            this.chart1.Titles[0].Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
            //设置图表显示样式
            this.chart1.Series[0].Color = Color.Red;
            this.chart1.Titles[0].Text = string.Format("力曲 {0} 显示", "线");
            this.chart1.Series[0].ChartType = SeriesChartType.Spline;
            this.chart1.Series[0].Points.Clear();
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        private void upData(double d)
        {
            if (dataqueue.Count > 100)
            {

                for (int i = 0; i < num; i++)
                {

                    dataqueue.Dequeue();


                }
            }

            for (int i = 0; i < num; i++)
            {
                dataqueue.Enqueue(d);
            }
           

        }
        /// <summary>
        /// 找到最大值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void findMaxValue()
        {
    
                    this.Invoke(new EventHandler(delegate
                    {
                        cbFmaxValue.Text = Convert.ToString(dataqueue.Max ());

                    }));
        }
            
                
        

        private void btnStop_Click(object sender, EventArgs e)
        {
            this.timer1.Stop();
            calculateIFSS();
            saveToXls();
            // Display the list in an Excel spreadsheet.
            DisplayInExcel();

        }
        /// <summary>
        /// 定时器函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            //定义全局变量txt 此处还需要更改如何使图表不更新这个初始值(参数传递)
            if (!(txt == null))
            {
                double dt = double.Parse(txt);
                upData(dt);
            }
           
            
            this.chart1.Series[0].Points.Clear();
            for (int i = 0; i < dataqueue.Count; i++)
            {
                this.chart1.Series[0].Points.AddXY((i + 1), dataqueue.ElementAt(i));
                findMaxValue();
            }
        }
        /// <summary>
        /// 计算强度
        /// </summary>
        private void calculateIFSS()
        {
            try
            {
                double vifss;
                double le = double.Parse(cbLenth.Text);//最好设置默认值或者消息弹出框
                double d = double.Parse(cbDiameter.Text);
                double fmax = double.Parse(cbFmaxValue.Text);

                vifss = fmax / (3.14 * d * le);

                this.Invoke(new EventHandler(delegate
                {
                    cbIfssValue.Text = Convert.ToString(vifss);

                }));
            }
            catch (Exception e)
            {
                MessageBox.Show("出问题了 你自己看着办");
            }
        }
        /// <summary>
        /// 保存数据至表格
        /// </summary>
        private string saveToXls()
        {
            String[] format ={"d","t" };
            CultureInfo cultures = CultureInfo.CreateSpecificCulture("de-DE");
            string y = DateTime.Now.ToString(format[0], cultures );
            string t = DateTime.Now.ToString(format[1], cultures);
           //string.Replace函数去掉影响字符串格式的符号(如“:”)
            textBox1.Text = y.Replace (".","") + t.Replace (":","") ;//设置文件名
            string s = y.Replace(".", "") + t.Replace(":", "");
            return s;
        }
 
        /// <summary>
        /// NPOI写数据到表格
        /// </summary>
        private void DisplayInExcel()
        {
            HSSFWorkbook workbook = new HSSFWorkbook();
            //创建工作表
            var sheet = workbook.CreateSheet();
            //创建标题行(重点)
            var row = sheet.CreateRow(0);
            //创建单元格
            
            var cellnum = row.CreateCell(0);
            cellnum.SetCellValue("序号");
            var celldata = row.CreateCell(1);
            celldata.SetCellValue("F/mN");
            var cellfmax = row.CreateCell(2);
            cellfmax.SetCellValue("Fmax/mN");
            var cellifss = row.CreateCell(4);
            cellifss.SetCellValue("IFSS/Mpa");
            //将力最大值与IFSS写入第二行
         
            var cellfmaxvalue = row.CreateCell(3);
            cellfmaxvalue.SetCellValue(cbFmaxValue .Text );
            var cellifssvalue = row.CreateCell(5);
            cellifssvalue.SetCellValue(cbIfssValue.Text);
            //将数据循环写入表格
            for (int i = 0; i < dataqueue.Count; i++)
            {
                var rowx = sheet.CreateRow(i + 1);
                var cellnumvalue = rowx.CreateCell(0);
                cellnumvalue.SetCellValue(i + 1);
                var celldatavalue = rowx.CreateCell(1);
                celldatavalue.SetCellValue(dataqueue.ElementAt(i));
            }
            string s = saveToXls();
            string path =@"C:\Users\admin\Desktop\"+ s+".xls";//文件格式不能带“:”号
            
            FileStream file = new FileStream(path, FileMode.CreateNew, FileAccess.Write);
            workbook.Write(file);
            file.Dispose();
        }
    }
}

  

上一篇:交互式SQL(数据定义部分)


下一篇:C# WinForm开发系列之chart控件画折线图和柱形图并自定义鼠标移动到数据标记点显示提示信息