寫在前面:
紀念一下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();
}
}
}
