C#实现串口示波器
作者:weixin_46896829 发布时间:2021-08-26 02:02:32
标签:C#,串口示波器
本文实例为大家分享了C#实现串口示波器的具体代码,供大家参考,具体内容如下
开发工具
visual studio2019
C#串口示波器,实时刷新端口号,动态绘制多条折线,获取串口数据并输出到文本框
之前用Java实现串口示波器对我来说还是比较困难的,而且实现的效果不尽如人意,就用C#开发了。
C#可以自由布置界面,在工具栏直接拖拽控件到窗体,然后双击控件就能添加事件了,很方便
最终效果是实现了,但是有个数据丢失的问题
数据处理到绘图分三个步骤:
1、获取串口发送的数据
2、把数据按需要提取到中间容器集合list1中
3、从集合中提取绘图的y值
测试得出的结果就是数据放进集合前不存在丢失,从集合中拿出数据这一过程也没问题。所以问题就出在第二步了,已解决(按需提取数据的规则要尽可能设置的详细一点就行)。
代码:
namespace CommPortsDesigner
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) //窗体运行完成即为加载,加载完成会触发事件
{
}
//传入原始数据datas及需要匹配的字符串r,得到需要的数据列表list
private List<int> DealData(string datas, Regex r, string split)
{
if (string.IsNullOrEmpty(datas))
{
throw new ArgumentException($"“{nameof(datas)}”不能是 Null 或为空。", nameof(datas));
}
List<int> list1=new List<int> { };
string s1="";
MatchCollection mc = r.Matches(datas); //提取符合要求的字符串
for (int i = 0; i < mc.Count; i++)
{
textBox2.AppendText(mc[i].Value + "\r\n"); //测试数据是否正确输出
s1 = s1 + mc[i].Value;
}
string[] d = s1.Split( new string[]{split}, StringSplitOptions.RemoveEmptyEntries);
for (int i=0;i<d.Length;i++) //将数字存入列表
{
list1.Add( int.Parse(d[i]));
}
//测试画图用的数据是否解析正确
if (split.Equals("LP4:"))
{
foreach (int m in list1)
{
textBox3.AppendText(m + "\r\n");
}
}
return list1;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.BaudRate = int.Parse(comboBox2.SelectedItem.ToString());
}
private void searchPort()
{
string Buffer;
comboBox1.Items.Clear();
for (int i = 1; i < 20; i++)
{
try
{
Buffer = "COM" + i.ToString();
serialPort1.PortName = Buffer;
serialPort1.Open();
comboBox1.Items.Add(Buffer);
comboBox1.SelectedItem = Buffer;
serialPort1.Close();
}
catch
{ }
}
}
private void getDatas()
{
System.Text.RegularExpressions.Regex r1 = new System.Text.RegularExpressions.Regex("LP1:(-?)\\d+");
System.Text.RegularExpressions.Regex r2 = new System.Text.RegularExpressions.Regex("LP2:(-?)\\d+");
System.Text.RegularExpressions.Regex r3 = new System.Text.RegularExpressions.Regex("LP3:(-?)\\d+");
System.Text.RegularExpressions.Regex r4 = new System.Text.RegularExpressions.Regex("LP4:(-?)\\d+");
System.Text.RegularExpressions.Regex r5 = new System.Text.RegularExpressions.Regex("LP5:(-?)\\d+");
System.Text.RegularExpressions.Regex r6 = new System.Text.RegularExpressions.Regex("CC1:(-?)\\d+");
System.Text.RegularExpressions.Regex r7 = new System.Text.RegularExpressions.Regex("CC2:(-?)\\d+");
System.Text.RegularExpressions.Regex r8 = new System.Text.RegularExpressions.Regex("CC3:(-?)\\d+");
System.Text.RegularExpressions.Regex r9 = new System.Text.RegularExpressions.Regex("CC4:(-?)\\d+");
System.Text.RegularExpressions.Regex r10 = new System.Text.RegularExpressions.Regex("CC5:(-?)\\d+");
byte[] inbuffer = null;
//Queue<int> q1 = new Queue<int>();
if (serialPort1.IsOpen && serialPort1.BytesToRead > 0)
{
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "hh:mm:ss.ff";
chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Milliseconds;
chart1.ChartAreas[0].AxisX.MajorGrid.IntervalType = DateTimeIntervalType.Milliseconds;
try
{
inbuffer = new byte[serialPort1.BytesToRead];
serialPort1.Read(inbuffer, 0, serialPort1.BytesToRead);
string strRaad = ASCIIEncoding.ASCII.GetString(inbuffer, 0, inbuffer.Length);
textBox1.AppendText(strRaad);
chart1.ChartAreas[0].AxisX.Minimum = DateTime.Now.AddSeconds(-5).ToOADate();
chart1.ChartAreas[0].AxisX.Maximum = DateTime.Now.ToOADate();
chart1.ChartAreas[0].AxisX.Interval = 500;
if (btn_start.Text.Equals("停止"))
{
//LP1
if (checkBox2.Checked)
{
foreach (int y in DealData(strRaad, r2, "LP2:"))
{
chart1.Series[1].Points.AddXY(DateTime.Now.ToOADate(), y);
//count2 = count2 + 5;
}
}
else
{
chart1.Series[1].Points.Clear();
}
//LP2
if (checkBox2.Checked)
{
foreach (int y in DealData(strRaad, r2, "LP2:"))
{
chart1.Series[1].Points.AddXY(DateTime.Now.ToOADate(), y);
//count2 = count2 + 5;
}
}
else
{
chart1.Series[1].Points.Clear();
}
//LP3
if (checkBox3.Checked)
{
foreach (int y in DealData(strRaad, r3, "LP3:"))
{
chart1.Series[2].Points.AddXY(DateTime.Now.ToOADate(), y);
//count3 = count3 + 5;
}
}
else
{
chart1.Series[2].Points.Clear();
}
//LP4
if (checkBox4.Checked)
{
foreach (int y in DealData(strRaad, r4, "LP4:"))
{
chart1.Series[3].Points.AddXY(DateTime.Now.ToOADate(), y);
//count4 = count4 + 5;
}
}
else
{
chart1.Series[3].Points.Clear();
}
//LP5
if (checkBox5.Checked)
{
foreach (int y in DealData(strRaad, r5, "LP5:"))
{
chart1.Series[4].Points.AddXY(DateTime.Now.ToOADate(), y);
//count5 = count5 + 5;
}
}
else
{
chart1.Series[4].Points.Clear();
}
//CC1
if (checkBox6.Checked)
{
foreach (int y in DealData(strRaad, r6, "CC1:"))
{
chart1.Series[5].Points.AddXY(DateTime.Now.ToOADate(), y);
//count6 = count6 + 5;
}
}
else
{
chart1.Series[5].Points.Clear();
}
//CC2
if (checkBox7.Checked)
{
foreach (int y in DealData(strRaad, r7, "CC2:"))
{
chart1.Series[6].Points.AddXY(DateTime.Now.ToOADate(), y);
//count7 = count7 + 5;
}
}
else
{
chart1.Series[6].Points.Clear();
}
//CC3
if (checkBox8.Checked)
{
foreach (int y in DealData(strRaad, r8, "CC3:"))
{
chart1.Series[7].Points.AddXY(DateTime.Now.ToOADate(), y);
//count8 = count8 + 5;
}
}
else
{
chart1.Series[8].Points.Clear();
}
//CC4
if (checkBox9.Checked)
{
foreach (int y in DealData(strRaad, r9, "CC4:"))
{
chart1.Series[8].Points.AddXY(DateTime.Now.ToOADate(), y);
//count9 = count9 + 5;
}
}
else
{
chart1.Series[8].Points.Clear();
}
//CC5
if (checkBox10.Checked)
{
foreach (int y in DealData(strRaad, r10, "CC5:"))
{
chart1.Series[9].Points.AddXY(DateTime.Now.ToOADate(), y);
//count10 = count10 + 5;
}
}
else
{
chart1.Series[9].Points.Clear();
}
}
}
catch
{
}
}
}
private void btn_open_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen||btn_open.Text.Equals("关闭"))
{
try
{
serialPort1.Close();
btn_open.Text = "打开";
}
catch
{ }
}
else
{
try
{
serialPort1.PortName = comboBox1.Text;
serialPort1.Open();
btn_open.Text = "关闭";
}
catch
{
MessageBox.Show("串口打开失败!", "错误");
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (!serialPort1.IsOpen)
{
searchPort();
}
else{}
getDatas();
}
private void btn_clear_Click(object sender, EventArgs e)
{
textBox1.Clear();
}
private void btn_save_Click(object sender, EventArgs e)
{
if (this.textBox1.TextLength > 0)
{
string path = "D:\\log.txt";
using (StreamWriter sw = new StreamWriter(path, true))
{
String time = DateTime.Now.ToLocalTime().ToString();
sw.WriteLine("\n" + time);
sw.Write(this.textBox1.Text);
}
MessageBox.Show("已保存到 D:\\log.txt!");
}
}
private void btn_start_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
if (btn_start.Text.Equals("开始"))
{
try
{
btn_start.Text = "停止";
}
catch
{ }
}
else
{
try
{
btn_start.Text = "开始";
}
catch
{
}
}
}
else
{
if (btn_start.Text.Equals("停止"))
{
try
{
btn_start.Text = "开始";
}
catch
{ }
}
else
{
MessageBox.Show("串口未打开!");
}
}
}
}
}
因为第一次开发,所以要实现的功能代码都放在一个类里了,大家将就着看吧
最终实现的效果
来源:https://blog.csdn.net/weixin_46896829/article/details/108961398


猜你喜欢
- 1. Java SE(Java Platform,Standard Edition)。Java SE 以前称为 J2SE。它允许开发和部署在
- 我们先来看看公众号发放现金红包的效果:需要调用商户平台的接口,接口发放规则如下:1.发送频率限制——默认1800/min 2.发送个数上限—
- Java并发包的locks包里的锁基本上已经介绍得差不多了,ReentrantLock重入锁是个关键,在清楚的了解了同步器AQS的运行机制后
- 引言:序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创
- 初学java,单个的接触有点迷糊,所以总结下他们的关系一、关系Collection--List:以特定顺序存储--ArrayList、Lin
- 目录一 、EasyExcel简介二、常用注解三、依赖四、监听五、接口导入Excel六、接口 导出Excel (HttpServletResp
- 本文实例为大家分享了Unity3D实现物体旋转缩放移动的具体代码,供大家参考,具体内容如下由于项目运行在安卓上,运用到了插件,比较麻烦。你们
- 本篇博客给大家分享一个效果比较好的侧滑菜单的Demo,实现点击左边菜单切换Fragment。效果如下: 主Activity代码:p
- 一.MyBatis简介1)MyBatis 是一款优秀的持久层框架2)MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结
- 本文实例讲述了C#监控文件夹变化的方法。分享给大家供大家参考。具体实现方法如下:当需要监控某一文件,FileSystemWatcher类提供
- 本文实例为大家分享了JAVASE系统实现抽卡功能的具体代码,供大家参考,具体内容如下先看下文件结构使用到的知识点:看下Client类的实现:
- 一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解。 首先
- 前言Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.
- 前面有文章介绍了使用GridView实现表格的方法,本文就来说说如何用ListView实现自适应的表格。GridView比ListView更
- 本文实例为大家分享了Java手写线程池的实现代码,供大家参考,具体内容如下1.线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在
- 1、properties文件显示乱码问题原因是因为properties默认使用ASCII码,就算在文件中填写了中文,再打开后依然会转换成AS
- 翻译自 John Demetriou 2019年2月17日 的文章 《C# 8 – Introducing Index Struct And
- 本文为大家分享了Android APP编写的简单答题器,此答题器可以通过Next按钮选择下一题,新写题目的类Question,有两个成员变量
- 1、点击【File】->【Project Structure】菜单(或使用Shift+Ctrl+Alt+S快捷键),打开【Projec
- 本文实例讲述了C#图像处理之木刻效果实现方法。分享给大家供大家参考。具体如下://木刻效果public Bitmap PFilterMuKe