c#串列埠seralport接收發送資料,生成chart折線圖,並儲存
阿新 • • 發佈:2019-01-09
剛剛從頭開始學習c#,在查詢資料過程中,感覺各位大神寫的太高深了,這裡是我寫的一個串列埠程式,希望與同我一樣的小白們一同努力,不要放棄,向更深一步加油吧;
程式要求:與兩個串列埠進行通訊,定時發出資料,對返回的資料進行處理(幀頭幀尾識別),經過演算法,得到一組資料,並將其輸出到chart圖表上(折線圖),最後儲存圖表。以下為程式碼:using System;using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Timers;
using System.Windows.Forms.DataVisualization.Charting;
namespace 接收完整版
{
public partial class Form1 : Form
{
private SerialPort sp1 = new SerialPort(); //建立串列埠sp1
private SerialPort sp2 = new SerialPort(); //建立串列埠sp2
public static double shuchu1; //sp1輸出資料
public static double shuchu2; //sp2輸出資料
public static double max0 = 0; //專案演算法中引數
public static double c; //同上
public static double d; //同上 public static int cishu=0; //定時器執行次數 static System.Timers.Timer t; //定時器宣告 Series series = new Series("Spline"); //chart圖示 public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
sp1.ReceivedBytesThreshold = 1; //sp1引數設定,這裡是接收1個數據便促發接收處理程式;接下來是串列埠號,波特率,奇偶位,停止位,資料位數設定;
sp1.PortName = "COM5";
sp1.BaudRate = 115200;
sp1.Parity = Parity.None;
sp1.StopBits = StopBits.One;
sp1.DataBits = 8;
sp1.Open(); //sp1串列埠開啟
sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); //sp1接收資料事件
sp2.ReceivedBytesThreshold = 1; //sp2引數設定
sp2.PortName = "COM6";
sp2.BaudRate = 115200;
sp2.Parity = Parity.None;
sp2.StopBits = StopBits.One;
sp2.DataBits = 8;
sp2.Open();//開啟串列埠
sp2.DataReceived += new SerialDataReceivedEventHandler(sp2_DataReceived);
Control.CheckForIllegalCrossThreadCalls = false; 執行緒間檢測關閉(即跨執行緒呼叫不報錯)
chart1.Series.Clear();
series.ChartType = SeriesChartType.Spline; //圖型別Spline
chart1.Series.Add(series); //新增一個圖表序列
this.chart1.ChartAreas[0].AxisY.Minimum = 0; //設定設定縱座標的最小值0
this.chart1.ChartAreas[0].AxisY.Maximum = 0.2; //設定設定縱座標的最大值0.2
this.chart1.ChartAreas[0].AxisX.Minimum = 0; //設定設定縱座標的最小值0
this.chart1.ChartAreas[0].AxisX.Maximum = 2000; //設定設定縱座標的最大值0.2
this.chart1.ChartAreas[0].AxisX.Interval = 100; //設定橫座標間隔為50,使得每個刻度間均勻分開的
this.chart1.ChartAreas[0].AxisY.Interval = 0.01;
this.chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Green; //背景網格線顏色為銀色
this.chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Green; //背景網格線顏色為銀色
this.chart1.ChartAreas[0].AxisX.Title = "次數/次"; //設定下方橫座標名稱
this.chart1.ChartAreas[0].AxisY.Title = "同軸度/mm"; //設定左邊縱座標的名稱
chart1.ChartAreas[0].Area3DStyle.Enable3D = true; //以3D形式展示
chart1.Series[0].Color = Color.Red; //線條顏色
} private List<byte> buffer = new List<byte>(1048576); //sp1接收事件
void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
(
int n = sp1.BytesToRead;//待讀位元組個數
byte[] buf = new byte[n];//建立n個位元組的快取
byte[] ReceiveBytes = new byte[9];
sp1.Read(buf, 0, n);//讀到在資料儲存到buf //快取資料
buffer.AddRange(buf);//不斷地將接收到的資料加入到buffer連結串列中 while (buffer.Count >= 6) //至少包含幀頭(1位元組)、資料(3位元組)、幀尾(1位元組)、效驗位(1位元組);
{ if (buffer[0] == 0x02) //到幀頭 02H
{ if (buffer.Count < 6) //資料區尚未接收完整,
{
break;//跳出接收函式後之後繼續接收資料
}
//得到完整的資料,複製到ReceiveBytes中進行校驗
buffer.CopyTo(0, ReceiveBytes, 0, 6);//複製資料
byte check; //開始校驗
check = 0x03;//幀尾 if (check != ReceiveBytes[4]) //幀尾驗證位失敗
{
buffer.RemoveRange(0, 6);//從連結串列中移除接收到的校驗失敗的資料, continue; //繼續執行while迴圈程式,
}
buffer.RemoveRange(0, 6); string strRcv = null;
for (int i = 1; i < 4; i++) //窗體顯示
{
strRcv += ReceiveBytes[i].ToString("X2"); //16進位制顯示
} // 專案演算法 //
}
else //幀頭不正確時,清除
{
buffer.RemoveAt(0);//清除第一個位元組,繼續檢測下一個。
}
} } private List<byte> buffer2 = new List<byte>(1048576); //sp2接收事件
void sp2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = sp2.BytesToRead;//待讀位元組個數
byte[] buf2 = new byte[n];//建立n個位元組的快取
byte[] ReceiveBytes2 = new byte[11];
sp2.Read(buf2, 0, n);//讀到在資料儲存到buf //快取資料
buffer2.AddRange(buf2);//不斷地將接收到的資料加入到buffer連結串列中 while (buffer2.Count >= 9) //至少包含幀頭(1位元組)、資料(7位元組)、幀尾(1位元組);
{ if (buffer2[0] == 0x02) //到幀頭 02H
{ if (buffer2.Count < 9) //資料區尚未接收完整,
{
break;//跳出接收函式後之後繼續接收資料
}
//得到完整的資料,複製到ReceiveBytes中進行校驗
buffer2.CopyTo(0, ReceiveBytes2, 0, 9);//
byte check2; //開始校驗
check2 = 0x03; if (check2 != ReceiveBytes2[8]) //幀尾驗證位失敗
{
buffer2.RemoveRange(0, 9);//從連結串列中移除接收到的校驗失敗的資料, continue; //繼續執行while迴圈程式,
} buffer2.RemoveRange(0, 9);
char[] c = new char[9];
int a; for (int i = 1, j = 0; i < 8; i++, j++)
{
a = Convert.ToInt32(ReceiveBytes2[i]);
c[j] = Convert.ToChar(a);
}
string b = new string(c);
txb2.Text = b;
shuchu2 = float.Parse(b);
}
else //幀頭不正確,清除
{
buffer2.RemoveAt(0); //清除第一個位元組,繼續檢測下一個。
}
} } private void button1_Click(object sender, EventArgs e) //點選開始按鈕觸發時間;這裡需要取初值;
{
System.Timers.Timer t0 = new System.Timers.Timer(50); //例項化Timer類,設定間隔時間為50毫秒;
t0.Elapsed += new System.Timers.ElapsedEventHandler(theout0); //到達時間的時候執行事件;
t0.AutoReset = false; //設定是執行一次(false)還是一直執行(true);
t0.Enabled = true; //是否執行System.Timers.Timer.Elapsed事件;
} public void theout0(object source, System.Timers.ElapsedEventArgs e) //到達時間的時候執行事件; {
string strFrame = "024D3F0371"; //sp1 傳送單次讀取指令; byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16); //資料格式轉換
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 傳送單次讀取指令; byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11); t = new System.Timers.Timer(20); //例項化Timer類,設定間隔時間為20毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到達時間的時候執行事件;
t.AutoReset = true; //設定是執行一次(false)還是一直執行(true);
t.Enabled = true; //是否執行System.Timers.Timer.Elapsed事件;
}
public void theout(object source, System.Timers.ElapsedEventArgs e) //到達時間的時候執行事件;
{ cishu = cishu + 1;
string strFrame = "024D3F0371"; //sp1 傳送單次讀取指令; byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 傳送單次讀取指令; byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
double max; //專案需要的演算法,不用管它
max = System.Math.Abs((shuchu1 - c) + (shuchu2 - d));
txb32.Text = max.ToString("0.0000") ;
if (shuchu1 != 0)
{
if(shuchu2 !=0)
{
if (max > max0)
{
max0 = max;
};
txb6.Text = max0.ToString("0.000");
txb31.Text = cishu.ToString("0");
series.Points.AddXY(cishu, max); //生成圖表,因為實時生成會卡,所以這裡接收完資料後,一起生成 }
} } private void button2_Click(object sender, EventArgs e) //暫停鍵
{
t.Stop();
chart1.Series[0].Points.Clear();
Application.Exit();
}
private void button3_Click(object sender, EventArgs e) //停止鍵
{
t.Stop();
sp1.Close();
sp2.Close();
} private void button4_Click(object sender, EventArgs e) //待測品放置完成後,讀取初值
{ string strFrame = "024D3F0371"; //sp1 傳送單次讀取指令; byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 傳送單次讀取指令; byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11); //
專案中輸出顯示到textbox //
} private void button5_Click(object sender, EventArgs e) //重置即停止並清楚現有資料
{ t.Stop();
chart1.Series[0].Points.Clear();
sp1.Close();
sp2.Close();
sp1.Open();
sp2.Open(); max0 = 0;
txb6.Text = max0.ToString("0.000");
cishu = 0;
txb31.Text = cishu.ToString("0");
} private void btn6_Click(object sender, EventArgs e) //儲存影象至C:/Users/Administrator/Desktop/同軸度
{
DateTime d = DateTime.Now; //讀取當前時間,作為影象儲存名稱
string fileName = d.ToString("yyyyMMddHHmmss"); //將時間轉為字串,並去掉空格,冒號等
string GR_Path = @"C:/Users/Administrator/Desktop/同軸度/同軸度影象";
string fullFileName = GR_Path + "\\" + fileName + ".jpeg";
chart1.SaveImage(fullFileName, ChartImageFormat.Jpeg);
chart1.SaveImage("C:/Users/Administrator/Desktop/同軸度/同軸度影象.jpeg", ChartImageFormat.Jpeg); //儲存影象路徑:桌面/同軸度/同軸度影象.jpeg
}
}
}原始碼地址:https://download.csdn.net/download/yunsongblue/10277693