C# 学习笔记(15)自己的串口助手----波形显示
C# 學(xué)習(xí)筆記(15)自己的串口助手----波形顯示
chart控件
chart控件共有5大集合,最重要的兩個(gè)集合就是繪圖空間和線
坐標(biāo)系
坐標(biāo)系的設(shè)置在繪圖空間集合內(nèi)
設(shè)置坐標(biāo)系樣式
框選放大功能
顯示鼠標(biāo)坐標(biāo)功能
開(kāi)啟游標(biāo)回調(diào)函數(shù)
縮放位置設(shè)置
位置和大小可以在程序中直接通過(guò)代碼控制,Y軸的也是如此
線
一個(gè)坐標(biāo)軸空間可以繪制多條線
顯示線上點(diǎn)數(shù)值
線類型
線的類型一般選FastPoint 或者FastLine 其他的會(huì)影響曲線繪制效率,繪制的點(diǎn)越多,刷新越慢
chart綁定數(shù)據(jù)源
和列表控件一樣,chart控件可以綁定DataTable,綁定分為三步,首先為DataTable創(chuàng)建列,然后將DataTable的列名和線的x,y綁定起來(lái),最后將chart和DataTable綁定起來(lái),接下來(lái)向DataTable添加列數(shù)據(jù),刷新圖表即可顯示曲線
/// <summary>/// chart控件數(shù)據(jù)源類型/// </summary>private DataTable dataTableType = new DataTable("Wave");/// <summary>/// chart控件數(shù)據(jù)源列表/// </summary>List<DataTable> dataTables = new List<DataTable>();/// <summary>/// 圖表刷新線程/// </summary>Thread thread;private void ChartWaveInit(){//1。 創(chuàng)建一個(gè)dataTable 10列 第一列存數(shù)據(jù)點(diǎn)x坐標(biāo) 其它九列存yfor(int i = 0; i < 10; i ++){dataTableType.Columns.Add("Series"+i);dataTableType.Columns["Series" + i].DataType = typeof(int);}//2. 綁定數(shù)據(jù)列 給九條曲線指定x y列名for(int i = 0; i < chartWave.Series.Count; i++){chartWave.Series[i].XValueMember = "Series0";chartWave.Series[i].YValueMembers = "Series"+ (i+1);}dataTables.Add(dataTableType.Clone());//3. 綁定數(shù)據(jù)源chartWave.DataSource = dataTables[0];//刷新圖表chartWave.DataBind(); }實(shí)際使用chart時(shí),發(fā)現(xiàn)當(dāng)數(shù)據(jù)點(diǎn)過(guò)多時(shí),使用 chartWave.DataBind();刷新圖表數(shù)據(jù)點(diǎn)越多越慢,因此程序中1s左右刷新一次圖表。當(dāng)數(shù)據(jù)點(diǎn)超過(guò)1w時(shí),1s刷新一次都不行,因此創(chuàng)建了DataTables 列表,當(dāng)DataTable行數(shù)大于1w后,切換圖表數(shù)據(jù)源到下一個(gè)DataTable,防止數(shù)據(jù)點(diǎn)過(guò)多越來(lái)越卡。
/// <summary> /// 幀頭 /// </summary> byte frameHead = 0xaa; /// <summary> /// 幀長(zhǎng) /// </summary> int frameLen = 38; private void Analysis() {List<byte> listBytes = new List<byte>(1024);int counter = 0;int yValue = int.MaxValue;while (true){Thread.Sleep(50);counter++;if (serialPortCOM.IsOpen){byte[] bytes = new byte[serialPortCOM.BytesToRead];serialPortCOM.Read(bytes, 0, bytes.Length);this.Invoke(new Action(() => RxCounter += bytes.Length));listBytes.AddRange(bytes);while (listBytes.Contains(frameHead) && (listBytes.Count - listBytes.IndexOf(frameHead)) >= frameLen){int Index = listBytes.IndexOf(frameHead);if (listBytes[Index + 1] == 0xFF && listBytes[Index + 2] == 0xF1 && listBytes[Index + 3] == 32){byte[] tempBytes = listBytes.ToArray();int Wave1 = BitConverter.ToInt32(tempBytes, Index + 4);int Wave2 = BitConverter.ToInt32(tempBytes, Index + 8);int Wave3 = BitConverter.ToInt32(tempBytes, Index + 12);int Wave4 = BitConverter.ToInt32(tempBytes, Index + 16);int Wave5 = BitConverter.ToInt32(tempBytes, Index + 20);int Wave6 = BitConverter.ToInt32(tempBytes, Index + 24);int Wave7 = BitConverter.ToInt32(tempBytes, Index + 28);int Wave8 = BitConverter.ToInt32(tempBytes, Index + 32);lock (chartLock){dataTables[dataTables.Count - 1].Rows.Add(WaveXIndex++, Wave1, Wave2, Wave3, Wave4, Wave5, Wave6, Wave7, Wave8);//記錄y值, 后面修改y軸位置for(int i = 1; i < 9; i++){if(chartWave.Series[i].Enabled){ yValue = (int)dataTables[dataTables.Count - 1].Rows[dataTables[dataTables.Count - 1].Rows.Count - 1][i];break;}}//表中超過(guò) MaxSeriesLen 條數(shù)據(jù) 切換下一個(gè)表 一個(gè)表中數(shù)據(jù)越長(zhǎng)則圖表刷新時(shí)間越長(zhǎng)if (dataTables[dataTables.Count - 1].Rows.Count >= MaxSeriesLen){dataTables.Add(dataTableType.Clone());for (int i = MaxSeriesLen/2; i < MaxSeriesLen; i++){dataTables[dataTables.Count - 1].Rows.Add(dataTables[dataTables.Count - 1 - 1].Rows[i].ItemArray);}this.BeginInvoke(new Action(() => trackBar1.Maximum += 10));if (ckbUpdata.Checked){//顯示最新數(shù)據(jù)點(diǎn)chartWave.DataSource = dataTables[dataTables.Count - 1];this.BeginInvoke(new Action(() => { trackBar1.Value = trackBar1.Maximum; }));}}}listBytes.RemoveRange(0, Index + frameLen);}else{listBytes.RemoveRange(0, Index);}}if (counter > 20 && yValue < int.MaxValue){int temp = yValue;counter = 0;yValue = int.MaxValue;this.BeginInvoke(new Action(() => {lock (chartLock){//X軸 滾動(dòng)條位置 保持最新位置 - 99if (ckbUpdata.Checked){if (dataTables[dataTables.Count - 1].Rows.Count > chartWave.ChartAreas[0].AxisX.ScaleView.Size){chartWave.ChartAreas[0].AxisX.ScaleView.Position = WaveXIndex - chartWave.ChartAreas[0].AxisX.ScaleView.Size;}else{chartWave.ChartAreas[0].AxisX.ScaleView.Position = 0;}//Y軸 滾動(dòng)條位置 保持最新位置chartWave.ChartAreas[0].AxisY.ScaleView.Position = temp - chartWave.ChartAreas[0].AxisY.ScaleView.Size/2;}//X軸 數(shù)據(jù)的起始位置和結(jié)束位置 //chart1.ChartAreas[0].AxisX.Minimum = 1000;//chart1.ChartAreas[0].AxisX.Maximum = dataTables[dataTables.Count - 1].Rows.Count;//刷新圖表chartWave.DataBind();}}));}}}}傳輸協(xié)議
傳輸協(xié)議使用匿名上位機(jī)V7的用戶自定義幀F(xiàn)1格式
#include "ANO_DT.h" #include "stm32f1xx.h"#define BYTE3(dwTemp) ( *( (char *)(&dwTemp) ) ) #define BYTE2(dwTemp) ( *( (char *)(&dwTemp) + 1) ) #define BYTE1(dwTemp) ( *( (char *)(&dwTemp) + 2) ) #define BYTE0(dwTemp) ( *( (char *)(&dwTemp) + 3) ) /*!* @brief 發(fā)送底層** @param dataToSend : 發(fā)送數(shù)據(jù)* @param length : 發(fā)送數(shù)據(jù)長(zhǎng)度** @return 無(wú)** @note 移植時(shí),需要自己實(shí)現(xiàn)該發(fā)送函數(shù)** @see ** @date 2019/5/28 ???*/ void ANO_DT_Send_Data(uint8_t *dataToSend , uint8_t length) {extern UART_HandleTypeDef huart1;HAL_UART_Transmit(&huart1, dataToSend, length, 1000); } /** ?????? */ uint8_t data_to_send[50];/*!* @brief 發(fā)送8個(gè)int32 數(shù)據(jù)給上位機(jī)** @param data1 - data8 : 數(shù)據(jù)** @return 無(wú)** @note ** @see ANO_DT_send_int32(1, 2, 3, 0, 0, 0, 0, 0);** @date 2019/5/28 ???*/ void ANO_DT_send_int32(int32_t data1, int32_t data2, int32_t data3,int32_t data4 ,int32_t data5, int32_t data6, int32_t data7, int32_t data8) {uint8_t _cnt=0;data_to_send[_cnt++] = 0xAA; //幀頭 0xAAAAdata_to_send[_cnt++] = 0xFF; data_to_send[_cnt++] = 0xF1; //功能字 0xF1 data_to_send[_cnt++] = 32; //幀長(zhǎng)data_to_send[_cnt++]=BYTE3(data1);data_to_send[_cnt++]=BYTE2(data1);data_to_send[_cnt++]=BYTE1(data1);data_to_send[_cnt++]=BYTE0(data1);data_to_send[_cnt++]=BYTE3(data2);data_to_send[_cnt++]=BYTE2(data2);data_to_send[_cnt++]=BYTE1(data2);data_to_send[_cnt++]=BYTE0(data2);data_to_send[_cnt++]=BYTE3(data3);data_to_send[_cnt++]=BYTE2(data3);data_to_send[_cnt++]=BYTE1(data3);data_to_send[_cnt++]=BYTE0(data3);data_to_send[_cnt++]=BYTE3(data4);data_to_send[_cnt++]=BYTE2(data4);data_to_send[_cnt++]=BYTE1(data4);data_to_send[_cnt++]=BYTE0(data4);data_to_send[_cnt++]=BYTE3(data5);data_to_send[_cnt++]=BYTE2(data5);data_to_send[_cnt++]=BYTE1(data5);data_to_send[_cnt++]=BYTE0(data5);data_to_send[_cnt++]=BYTE3(data6);data_to_send[_cnt++]=BYTE2(data6);data_to_send[_cnt++]=BYTE1(data6);data_to_send[_cnt++]=BYTE0(data6);data_to_send[_cnt++]=BYTE3(data7);data_to_send[_cnt++]=BYTE2(data7);data_to_send[_cnt++]=BYTE1(data7);data_to_send[_cnt++]=BYTE0(data7);data_to_send[_cnt++]=BYTE3(data8);data_to_send[_cnt++]=BYTE2(data8);data_to_send[_cnt++]=BYTE1(data8);data_to_send[_cnt++]=BYTE0(data8);uint8_t sum = 0;uint8_t sumCheck = 0;for(uint8_t i=0;i<_cnt;i++){sum += data_to_send[i];sumCheck+= sum;}data_to_send[_cnt++]=sum;data_to_send[_cnt++]=sumCheck;ANO_DT_Send_Data(data_to_send, _cnt); }最后,說(shuō)實(shí)話這個(gè)串口助手的波形顯示功能還是比較雞肋的,刷新太慢了,后面有時(shí)間會(huì)研究一下github上的開(kāi)源圖表控件 https://github.com/beto-rodriguez/LiveCharts2
總結(jié)
以上是生活随笔為你收集整理的C# 学习笔记(15)自己的串口助手----波形显示的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C# 学习笔记(14)自己的串口助手--
- 下一篇: C# 学习笔记(16)ComboBox下