小菜鸡学习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# 串口+示波+数据存储+截图相关推荐

  1. VMware vSphere 5.1 群集深入解析(二十六)- 数据存储维护模式汇总

    VMware vSphere 5.1 Clustering Deepdive HA.DRS.Storage DRS.Stretched Clusters Duncan Epping &Fran ...

  2. labview GSM上位机监控系统~温度监控,液位监控,粉尘浓度监控,远程遥控~串口通讯~短信远程功能~数据采集,数据存储,报表输出~

    labview GSM上位机监控系统温度监控,液位监控,粉尘浓度监控,远程遥控串口通讯短信远程功能数据采集,数据存储,报表输出~ _:5444669332416953labview十年工控

  3. 嵌入式调试神器-虚拟示波器之JScope

    调试神器-虚拟示波器之JScope 在进行嵌入式开发过程中,需要查看某些实时变化的变量,以MDK为例我们通常都是进入DEBUG模式下去肉眼观察,这种方式不太人性化,也比较容易错失掉许多细节.为此我介绍 ...

  4. Android开发7:简单的数据存储(使用SharedPreferences)和文件操作

    前言 啦啦啦~大家好,又见面啦~ 本篇博文讲和大家一起完成一个需要注册.登录的备忘录的,一起学习 SharedPreferences 的基本使用,学习 Android 中常见的文件操作方法,复习 An ...

  5. zynqsd的读写数据_数据存储结构图 - Zynq7000 FPGA的高速信号采集处理平台的设计搭建以及后续拓展...

    通过FPGA搭建A/D数据高速缓存机制,A/D数据经过FPGA的片上缓存,写入DDR A/D数据区,作为高速缓存,DDR其他空间作为ARM控制系统的运行程序,与A/D转换器进行数据交互.数据存储结构图 ...

  6. [免费专栏] Android安全之数据存储与数据安全「详解」

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  7. 冰河,能不能讲讲如何实现MySQL数据存储的无限扩容?

    写在前面 随着互联网的高速发展,企业中沉淀的数据也越来越多,这就对数据存储层的扩展性要求越来越高.当今互联网企业中,大部分企业使用的是MySQL来存储关系型数据.如何实现MySQL数据存储层的高度可扩 ...

  8. USART向串口助手发送数据(DMA方式)

    目录 一.前言 二.什么是DMA? 1.DMA简介 2.DMA主要特性 3.DMA框图 三.STM32CubeMX工程创建 1.题目要求 2.CubeMX工程配置 四.Keil工程的创建 五.效果展示 ...

  9. iOS本地数据存储安全

    iOS本地数据存储安全 移动APP通常会在设备本地存储一些数据,这可以为程序执行.更良好地性能或离线访问提供支持.由于移动设备使用地越来越广泛,设备失窃的风险也越来越大,因此不安全的本地数据存储已成为 ...

最新文章

  1. CocoaPods原理(一)
  2. 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 二级指针 排序 | 通过 交换指针方式 进行排序 )
  3. 推荐一个非常火爆的电商开源项目!
  4. express-winston 库的学习笔记
  5. UNION JOIN 连接表
  6. 工作168:代码中的删除逻辑处理
  7. Git(7)-Git commit
  8. 综述 | Google团队发布,一文概览Transformer模型的17大高效变种
  9. js 异步执行_JS异步执行机制——事件循环(Event Loop)
  10. mac php5.6 gd 扩展,mac 编译安装php5.6.40
  11. tomcat中多个域名配置
  12. 【细胞分割】基于matlab GUI原子力显微镜图像分析【含Matlab源码 1371期】
  13. 统计学贾俊平第六版pdf下载|贾俊平统计学第六版pdf下载电子书
  14. fanuc系统md和mf区别_fanuc mf系统小技巧汇总
  15. 10、Halcon图像条形码和二维码识别
  16. 深海迷航坐标传送代码_深海迷航代码大全_深海迷航作弊码汇总及代码使用教程_咖绿茵手游站...
  17. Laravel每日一记
  18. tomcat禁止外网访问,允许locat访问
  19. Redis集群的部署
  20. Failed to declare queue(s):[XXX]问题解决

热门文章

  1. linux 无法解析配置文件,Linux无法解析域名的解决办法
  2. 广东移动待遇及详细工作经历 (转)
  3. 数据标注案例分析-足球比赛时间轴打点标注项目
  4. sentencepiece原理与实践
  5. 数字孪生 智慧工厂可视化决策系统
  6. 傅盛认知三部曲后记:到底什么是认知?
  7. Python学习笔记(1)---B站黑马程序员
  8. 终于等到你,最强 IDE Visual Studio 2017 正式版发布
  9. onunload,onbeforeunload,load事件
  10. fmdb的一些基本的用法