开发工具
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
)
{
}
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;
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("停止"))
{
if (checkBox2
.Checked
)
{
foreach (int y
in DealData(strRaad
, r2
, "LP2:"))
{
chart1
.Series
[1].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[1].Points
.Clear();
}
if (checkBox2
.Checked
)
{
foreach (int y
in DealData(strRaad
, r2
, "LP2:"))
{
chart1
.Series
[1].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[1].Points
.Clear();
}
if (checkBox3
.Checked
)
{
foreach (int y
in DealData(strRaad
, r3
, "LP3:"))
{
chart1
.Series
[2].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[2].Points
.Clear();
}
if (checkBox4
.Checked
)
{
foreach (int y
in DealData(strRaad
, r4
, "LP4:"))
{
chart1
.Series
[3].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[3].Points
.Clear();
}
if (checkBox5
.Checked
)
{
foreach (int y
in DealData(strRaad
, r5
, "LP5:"))
{
chart1
.Series
[4].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[4].Points
.Clear();
}
if (checkBox6
.Checked
)
{
foreach (int y
in DealData(strRaad
, r6
, "CC1:"))
{
chart1
.Series
[5].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[5].Points
.Clear();
}
if (checkBox7
.Checked
)
{
foreach (int y
in DealData(strRaad
, r7
, "CC2:"))
{
chart1
.Series
[6].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[6].Points
.Clear();
}
if (checkBox8
.Checked
)
{
foreach (int y
in DealData(strRaad
, r8
, "CC3:"))
{
chart1
.Series
[7].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[8].Points
.Clear();
}
if (checkBox9
.Checked
)
{
foreach (int y
in DealData(strRaad
, r9
, "CC4:"))
{
chart1
.Series
[8].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
else
{
chart1
.Series
[8].Points
.Clear();
}
if (checkBox10
.Checked
)
{
foreach (int y
in DealData(strRaad
, r10
, "CC5:"))
{
chart1
.Series
[9].Points
.AddXY(DateTime
.Now
.ToOADate(), y
);
}
}
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("串口未打开!");
}
}
}
}
}
因为第一次开发,所以要实现的功能代码都放在一个类里了,大家将就着看吧
最终实现的效果