1. 程式人生 > 實用技巧 >c#學習心得(5)資料採集上位機開發

c#學習心得(5)資料採集上位機開發

寫在前面:

紀念一下2020/7/21第一個使用C#開發的上位機專案整體框架成型,具體是採集感測器的力,並計算,實時顯示力曲線,並將資料儲存,

最初使用labview做出大致的效果,但是有一些bug,沒有深入除錯。而後因為visionpro的原因接觸到C#,選擇在.Net框架下開發上位機的Winform

程式,雖然真正用在其中的時間不多,但是也有想法到現在也過去幾個月了。看了很多前輩的部落格,參考了很多MSDN上的案例。非常感謝,特此

貼下原始碼,供其他同學參考,歡迎各位前輩評點。轉載請註明部落格來源

上位機功能:採集感測器力(串列埠通訊),計算強度,實時顯示力曲線,儲存原始資料到表格。

介面如下:

原始碼如下:

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();
        }
    }
}