C# 学习笔记(15)自己的串口助手----波形显示

chart控件

chart控件共有5大集合,最重要的两个集合就是绘图空间和线

坐标系

坐标系的设置在绘图空间集合内

设置坐标系样式

框选放大功能


显示鼠标坐标功能

开启游标回调函数

private void chartWave_CursorPositionChanged(object sender, System.Windows.Forms.DataVisualization.Charting.CursorEventArgs e)
{if (e.Axis.Name.ToLower().StartsWith("x")){labX.Text = e.NewPosition.ToString();}else if (e.Axis.Name.ToLower().StartsWith("y")){labY.Text = e.NewPosition.ToString();}
}

缩放位置设置



位置和大小可以在程序中直接通过代码控制,Y轴的也是如此

线

一个坐标轴空间可以绘制多条线

显示线上点数值

线类型


线的类型一般选FastPoint 或者FastLine 其他的会影响曲线绘制效率,绘制的点越多,刷新越慢

chart绑定数据源

和列表控件一样,chart控件可以绑定DataTable,绑定分为三步,首先为DataTable创建列,然后将DataTable的列名和线的x,y绑定起来,最后将chart和DataTable绑定起来,接下来向DataTable添加列数据,刷新图表即可显示曲线

 /// <summary>/// chart控件数据源类型/// </summary>private DataTable dataTableType = new DataTable("Wave");/// <summary>/// chart控件数据源列表/// </summary>List<DataTable> dataTables = new List<DataTable>();/// <summary>/// 图表刷新线程/// </summary>Thread thread;private void ChartWaveInit(){//1。 创建一个dataTable 10列 第一列存数据点x坐标 其它九列存yfor(int i = 0; i < 10; i ++){dataTableType.Columns.Add("Series"+i);dataTableType.Columns["Series" + i].DataType = typeof(int);}//2. 绑定数据列 给九条曲线指定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. 绑定数据源chartWave.DataSource = dataTables[0];//刷新图表chartWave.DataBind();
}

实际使用chart时,发现当数据点过多时,使用 chartWave.DataBind();刷新图表数据点越多越慢,因此程序中1s左右刷新一次图表。当数据点超过1w时,1s刷新一次都不行,因此创建了DataTables 列表,当DataTable行数大于1w后,切换图表数据源到下一个DataTable,防止数据点过多越来越卡。

/// <summary>
/// 帧头
/// </summary>
byte frameHead = 0xaa;
/// <summary>
/// 帧长
/// </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;}}//表中超过 MaxSeriesLen 条数据 切换下一个表 一个表中数据越长则图表刷新时间越长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){//显示最新数据点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轴 滚动条位置 保持最新位置 - 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轴 滚动条位置 保持最新位置chartWave.ChartAreas[0].AxisY.ScaleView.Position = temp - chartWave.ChartAreas[0].AxisY.ScaleView.Size/2;}//X轴 数据的起始位置和结束位置 //chart1.ChartAreas[0].AxisX.Minimum = 1000;//chart1.ChartAreas[0].AxisX.Maximum =  dataTables[dataTables.Count - 1].Rows.Count;//刷新图表chartWave.DataBind();}}));}}}}

传输协议

传输协议使用匿名上位机V7的用户自定义帧F1格式

#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    发送底层** @param    dataToSend   :   发送数据* @param    length       :   发送数据长度** @return   无** @note     移植时,需要自己实现该发送函数** @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    发送8个int32 数据给上位机** @param    data1 - data8  : 数据** @return   无** @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;        //帧长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);
}

最后,说实话这个串口助手的波形显示功能还是比较鸡肋的,刷新太慢了,后面有时间会研究一下github上的开源图表控件 https://github.com/beto-rodriguez/LiveCharts2

C# 学习笔记(15)自己的串口助手----波形显示相关推荐

  1. OpenHarmony学习笔记——Hi3861+ASR-01的语音识别助手

    文章目录 前言 Hi3861的UART与PWM简介 UART简介 PWM ASR-01离线语音识别 天问官方介绍 硬件连接 软件部分 ASR-01代码 Hi3861端代码 初始化资源 串口指令识别 效 ...

  2. Hadoop学习笔记—15.HBase框架学习(基础知识篇)

    Hadoop学习笔记-15.HBase框架学习(基础知识篇) HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase ...

  3. 【学习笔记】stm32+openmv串口通信实现颜色识别

    个人笔记.这是之前的一个实验,现在把它整理出来. 本实验用的是stm32h743和openmv作为硬件,实现用openmv识别出我们想要的颜色,将获取的颜色坐标和目标区域的宽.高 通过串口发送给 st ...

  4. C++语言学习笔记15:Clean 垃圾清理插件

    C++语言学习笔记15:Clean 垃圾清理插件 对话框 STET1 图片切换功能 导入位图资源 插入图片控件并修改属性 添加消息处理函数 step2 开发思路及类关系图 step3 添加控件及MFC ...

  5. 区块链学习笔记15——ETH状态树

    区块链学习笔记15--ETH状态树 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 引入 要实现的功 ...

  6. 数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配

    数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配 引入小题:最短路径 最大流问题(maximum flow problem) ...

  7. 点云学习笔记15——PCL常用的基础代码

    点云学习笔记15--PCL基础 命名规范 常用代码 1.时间计算 2.pcl::PointCloud::Ptr和pcl::PointCloud的两个类相互转换 3.如何查找点云的x,y,z的极值? 4 ...

  8. 凸优化学习笔记 15:梯度方法

    前面的章节基本上讲完了凸优化相关的理论部分,在对偶原理以及 KKT 条件那里我们已经体会到了理论之美!接下来我们就要进入求解算法的部分,这也是需要浓墨重彩的一部分,毕竟我们学习凸优化就是为了解决实际当 ...

  9. C++下opencv学习笔记(一)(图像的简单读取丶显示与存储)

    C++下opencv学习笔记(一)(图像的简单读取丶显示与存储) 前言 学习C++ OpenCV,第一需要具备面向对象语言的基础,第二要对图像处理机器学习有基础了解,容易入门.觉得自己基础已经有了可以 ...

最新文章

  1. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数
  2. 小米 Play 发布:CPU+GPU 双 Turbo,每个月送 10 GB 流量
  3. EmEdit选择多行内容
  4. 解决SecureCRT连接GNS3时SecureCRT标签窗口同名的问题
  5. kali安装tools
  6. Python模块 - os
  7. php转换图片为.bin文件
  8. Apache骆驼丝攻示例
  9. webpack那些事儿
  10. 安装SQL2005提示“SQL Server 2005 COM+ 目录要求”警告 解决方法
  11. pandas时间处理操作
  12. java自定义日志_Java 自定义日志写入
  13. 运算放大电路_电工CChap03 集成运算放大电路与应用
  14. 华为od python_华为运维开发-华为OD工资待遇怎么样 - 华为技术有限公司 - 职友集...
  15. POI实现合并单元格
  16. C# MemCached
  17. VMware清理vmdk文件,解决vmdk越来越大的问题
  18. virtualbox与windows共享文件夹
  19. 利用HTML完成用户注册界面设计,以及性别复选框、按钮链接跳转的实现
  20. hdu2822(会双搜后再写次)

热门文章

  1. HDU ACM 1046 Gridland 找规律
  2. GO 输出字符数同时输出这个字符串的字节数
  3. Android平台 Psensor传感器调试方法
  4. MTK+Android编译
  5. 优秀中层必备的十大能力
  6. 6410调试LCD屏AT050TN22遇到的问题
  7. java储存学生档案应该注意事项_档案管理的注意事项有哪些
  8. ug11许可证文件路径安装在哪_Matlab2012a安装教程
  9. python如何做一个数据库_Python创建一个新的Django项目(连接到MySQL数据库),python,新建,mysql...
  10. Git 基础 —— 安装 配置 别名 对象