C# 串口+示波+数据存储+截图
小菜鸡学习C#一个星期的心得
因学校课设需要,小学期期间花了几天学了一下C#,因为没有人带,纯野生的那种,就算是现在的作品也有不少的Bug,但应付一下答辩什么的还是可以的,费话不多说,先讲讲我的处女作都有些什么功能
整个面板分为三个部分:串口配置和数据接收、波形显示、坐标和数据存储
1、串口数据接收(只有模拟量,无进制转换)
2、接收数据波形显示
3、接收数据的存储(excel)
1.1 数据接收
这部分主要有两件事:配置串口、数据接收
这部分相对简单(如果像我一样只是单纯的拿到采集的数据,不进行进制转换什么的),在你的form1窗体里边加入serialport1控件,选中它,在属性栏中找到一个黄色的闪电图标,在它的下面有一个datareceived,点击两次会在form1.cs文件中产生一个函数
1.2串口接收事件产生
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e){date = serialPort1.ReadExisting();//接收串口的缓存数据list_1.Add(date);textBox2.AppendText(date + "\r\n");}
同时在form1.designer.cs文件中会产生一个事件,这条语句必需要加在form_load(双击form1窗口产生的函数)函数中
private void Form1_Load(object sender, EventArgs e)//初始化窗口数据{this.serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);}
另外还需要配置串口(我这里只设置了串口号和波特率,如果有需要可以自己再添加其他的要求)
1.3配置及打开串口
private void button1_Click(object sender, EventArgs e)//打开串口{try // try...catch可以用来捕获未知的错误,防止程序崩溃{if (comboBox1.Text != "" | comboBox2.Text != ""){serialPort1.PortName = comboBox1.Text;serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);serialPort1.Open();button1.Enabled = false;button2.Enabled = true;}}catch{MessageBox.Show("请配置端口,错误");}}
1.4 关闭串口
private void button2_Click(object sender, EventArgs e)//关闭串口{if (serialPort1.IsOpen){serialPort1.Close();button1.Enabled = true;button2.Enabled = false;}}
到此,串口这部分的工作算是做完了
2.1波形显示
这部分内容主要分为三个部分:画表格、画坐标、画波线
这部分是三个里边不太好理解的一个,代码比较多,涉及的公式也较多,猛地一看脑壳痛,其实如果你能够静下心来,还是比较简单的,主要的思想就是 : 找点+平移
2.2 画网格
private void groupBox3_Paint(object sender, PaintEventArgs e)//网格绘制{for (int i = 0; i <= max_x / gap_x + 1; i++)//Draw y纵向轴绘制{e.Graphics.DrawLine(TablePen, StartPrint_x+d + i * gap_x, StartPrint_y, StartPrint_x+d+ i * gap_x, max_y + 6);//网格}for (int i = 0; i <= (max_y - 10) / gap_y; i++) //Draw X 横向轴绘制{e.Graphics.DrawLine(TablePen, StartPrint_x+d, StartPrint_y + i * gap_y, StartPrint_x+d + max_x, StartPrint_y + i * gap_y);//网格 }}
相信很多人看到这段代码直接自动忽略跳过了吧,哈哈哈,其实就一个函数:
e.Graphics.DrawLine(pen, x1, y1, x2, y2);
意思是:拿着一支名叫 pen 的笔,从点(x1,y1)画到点(x2,y2),里边有几个变量限于篇幅,这里不解释(找点+平移),源文件中有(且有注释),大家可以看看
2.3画坐标轴线
这里很有意思啊,我在网上找了一些画轴线的代码(文末有链接),过于深奥,于是我想了一个很巧妙的办法,将 “ | ” 和 “ — ” 通过 for 循环连续画,并通过字符的形式打印在合适的位置上(这里需要根据自己的情况进行微调),这个方法看起来很 low 不过很好用,如果大家有什么简单的方法别忘记给我讲一下啊
这段代码看起来也不是很友好,其实也就一个函数:
gp.AddString(string, pen, font_style, font_size, text_form(x, y, width, height), null);
意思是:拿着一支名叫 pen 的笔,它的粗细为 font_size ,在名叫 text_form 的文本框中写下风格为 font_style 的 string 字符,这个文本框的高为 height,宽为 width ,文本框的左上点坐标为( x , y )
还要提一点,上面那个函数必需和下面这个函数一同使用,否则字符不生效
e.Graphics.DrawPath(Pens.White, gp);//写文字
private void groupBox3_Paint(object sender, PaintEventArgs e)//网格绘制{string axis_x = "—";// x 轴刻度线(以连续的字符形式出现,取了个巧,若想仔细研究:http://www.cnblogs.com/xf_z1988/archive/2010/05/11/CSharp_WinForm_Waveform.html)string axis_y = "|"; // y 轴刻度线for (int i = 0; i < 75; i++)//画 x 轴轴线{gp.AddString(axis_x, family, fontstyle, 8, new RectangleF(StartPrint_x + d + i * gap_x/2 - 2, StartPrint_y + max_y - 16, 400, 50), null);}for (int i = 0; i < 40; i++)//画 y 轴轴线{gp.AddString(axis_y, family, fontstyle, 8, new RectangleF(47, i * gap_y/2 + 12, 400, 50), null);//}e.Graphics.DrawPath(Pens.White, gp);//写文字}
2.4标记刻度及表头
其实这个和上面讲的画坐标轴轴线原理是一样的,主要涉及 gp.AddString()和 e.Graphics.DrawPath( )两个函数,再将它们通过 for 循环放在合适的位置就好了
private void groupBox3_Paint(object sender, PaintEventArgs e)//网格绘制{for (int i = 0; i <= max_x / gap_x + 1; i++)//Draw y纵向轴绘制{gp.AddString((i).ToString(), family, fontstyle, 8, new RectangleF(StartPrint_x+d + i * gap_x - 7, StartPrint_y+max_y-8, 400, 50), null);//刻度 }for (int i = 0; i <max_y/gap_y; i++)//标记刻度{string Str_y = Convert.ToString((20 - i) * (Max-Min)/20);// y 坐标单位大小=(量程最大值-量程最小值)/20if (i == 0)Str_y = Max.ToString();//量程最大值 if (i == 20)break;gp.AddString(Str_y, family, fontstyle, 8, new RectangleF(23, i * gap_y+12, 400, 50), null);//添加文字}gp.AddString(textBox11.Text, family, fontstyle, 12, new RectangleF(groupBox3.ClientRectangle.Width / 2, StartPrint_y + max_y+5, 400, 50), null);//gp.addstring() 要与此句联用,否则无法显示 e.Graphics.DrawPath()gp.AddString(textBox12.Text, family, fontstyle, 12, new RectangleF(0, groupBox3.ClientRectangle.Height / 2 - StartPrint_y, 10, 50), null);e.Graphics.DrawPath(Pens.White, gp);//写文字}
2.5画波形图
我做的这个波形显示可以将数据分为四个范围,每个范围用不同的颜色绘制,因此在代码中有四个范围的判断,这里涉及的函数和画网格的地方是一样的
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)//波形绘制{if (dstr2 <= Up_a && dstr2 > Dw_a){graphics.DrawLine(LinesPen_a, Origin_x + i * gap_x+d, dstr1, Origin_x + (i + 0.1f) * gap_x+d, (int)(Origin_y - dstr2 / div));}//范围 a 曲线i += step;//X轴投影的步进长度dstr1 =(int)( Origin_y - dstr2 /div);Delay(time);//不延时的话不显示 }
3.1选择存储路径
private void button18_Click(object sender, EventArgs e)//数据存储,路径选择{openFileDialog1.Filter = "excel文件|*.xls";if(openFileDialog1.ShowDialog()==DialogResult.OK){textBox14.Text = openFileDialog1.FileName;}}
3.2创建工作簿及保存
这里要引用一个空间名,具体的方法的文章我忘记了流程是:
using Microsoft.Office.Interop.Excel;
private void button19_Click(object sender, EventArgs e)//开始采集{Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();//实例化Excel对象object missing = System.Reflection.Missing.Value;//获取缺少的object类型值//打开指定的Excel文件Workbook workbook = excel.Application.Workbooks.Open(textBox14.Text, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);Worksheet newWorksheet = (Worksheet)workbook.Worksheets.Add(missing, missing, missing, missing);excel.Application.DisplayAlerts = false;//不显示提示对话框workbook.Save();//保存工作表workbook.Close(false, missing, missing);//关闭工作表}
3.3写入数据
这句的意思是在 excel 的第 1 行第 2
newWorksheet.Cells[1, 1] = "chen";
4.1截图
这是一个完整的函数,
private void button6_Click(object sender, EventArgs e)//截屏{System.Drawing.Point p = groupBox3.PointToScreen(new System.Drawing.Point(0, 0));//得到groupbox3相对于电脑屏幕(绝对坐标、世界坐标)的坐标,不是相对于Form1的坐标Bitmap bit = new Bitmap(this.Width, this.Height);//实例化一个和窗体一样大的bitmapGraphics g = Graphics.FromImage(bit);g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高g.CopyFromScreen(p.X, p.Y, 0, 0, new Size(groupBox3.Width, groupBox3.Height));//以p.x和p.y(这里是groupbox3的绝对坐标,即其左上顶点的坐标)为起点,x偏移量=0,y偏移量=0,截取 宽=groupbox3.width,高=grouup.height的矩形 number += 1;bit.Save("状态" + number.ToString() + ".png");//默认保存格式为PNG,保存成jpg格式质量不是很好,默认存储位置:工程目录下的 WindowsFormsAppx\WindowsFormsAppx\bin\Debug}
[1]: https://www.cnblogs.com/liuxianan/archive/2012/07/29/2613755.html 截图参考
[2]: https://blog.csdn.net/lickilygou/article/details/85102538 界面设置参考
C# 串口+示波+数据存储+截图相关推荐
- VMware vSphere 5.1 群集深入解析(二十六)- 数据存储维护模式汇总
VMware vSphere 5.1 Clustering Deepdive HA.DRS.Storage DRS.Stretched Clusters Duncan Epping &Fran ...
- labview GSM上位机监控系统~温度监控,液位监控,粉尘浓度监控,远程遥控~串口通讯~短信远程功能~数据采集,数据存储,报表输出~
labview GSM上位机监控系统温度监控,液位监控,粉尘浓度监控,远程遥控串口通讯短信远程功能数据采集,数据存储,报表输出~ _:5444669332416953labview十年工控
- 嵌入式调试神器-虚拟示波器之JScope
调试神器-虚拟示波器之JScope 在进行嵌入式开发过程中,需要查看某些实时变化的变量,以MDK为例我们通常都是进入DEBUG模式下去肉眼观察,这种方式不太人性化,也比较容易错失掉许多细节.为此我介绍 ...
- Android开发7:简单的数据存储(使用SharedPreferences)和文件操作
前言 啦啦啦~大家好,又见面啦~ 本篇博文讲和大家一起完成一个需要注册.登录的备忘录的,一起学习 SharedPreferences 的基本使用,学习 Android 中常见的文件操作方法,复习 An ...
- zynqsd的读写数据_数据存储结构图 - Zynq7000 FPGA的高速信号采集处理平台的设计搭建以及后续拓展...
通过FPGA搭建A/D数据高速缓存机制,A/D数据经过FPGA的片上缓存,写入DDR A/D数据区,作为高速缓存,DDR其他空间作为ARM控制系统的运行程序,与A/D转换器进行数据交互.数据存储结构图 ...
- [免费专栏] Android安全之数据存储与数据安全「详解」
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...
- 冰河,能不能讲讲如何实现MySQL数据存储的无限扩容?
写在前面 随着互联网的高速发展,企业中沉淀的数据也越来越多,这就对数据存储层的扩展性要求越来越高.当今互联网企业中,大部分企业使用的是MySQL来存储关系型数据.如何实现MySQL数据存储层的高度可扩 ...
- USART向串口助手发送数据(DMA方式)
目录 一.前言 二.什么是DMA? 1.DMA简介 2.DMA主要特性 3.DMA框图 三.STM32CubeMX工程创建 1.题目要求 2.CubeMX工程配置 四.Keil工程的创建 五.效果展示 ...
- iOS本地数据存储安全
iOS本地数据存储安全 移动APP通常会在设备本地存储一些数据,这可以为程序执行.更良好地性能或离线访问提供支持.由于移动设备使用地越来越广泛,设备失窃的风险也越来越大,因此不安全的本地数据存储已成为 ...
最新文章
- CocoaPods原理(一)
- 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 二级指针 排序 | 通过 交换指针方式 进行排序 )
- 推荐一个非常火爆的电商开源项目!
- express-winston 库的学习笔记
- UNION JOIN 连接表
- 工作168:代码中的删除逻辑处理
- Git(7)-Git commit
- 综述 | Google团队发布,一文概览Transformer模型的17大高效变种
- js 异步执行_JS异步执行机制——事件循环(Event Loop)
- mac php5.6 gd 扩展,mac 编译安装php5.6.40
- tomcat中多个域名配置
- 【细胞分割】基于matlab GUI原子力显微镜图像分析【含Matlab源码 1371期】
- 统计学贾俊平第六版pdf下载|贾俊平统计学第六版pdf下载电子书
- fanuc系统md和mf区别_fanuc mf系统小技巧汇总
- 10、Halcon图像条形码和二维码识别
- 深海迷航坐标传送代码_深海迷航代码大全_深海迷航作弊码汇总及代码使用教程_咖绿茵手游站...
- Laravel每日一记
- tomcat禁止外网访问,允许locat访问
- Redis集群的部署
- Failed to declare queue(s):[XXX]问题解决