C#做的串口示波器,可以实现动态波形显示的效果。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.Text.RegularExpressions; namespace serial1 { public partial class Form1 : Form { int maxRate; //最大比例 private bool listening = false; private bool closing = false; Point lastPoint,nowPoint; List<double> l = new List<double>(); //存储串口接收的值 Graphics g; //生成图形 Pen drawPen=new Pen(Color.Red,1); private StringBuilder builder = new StringBuilder(); private SerialPort comm = new SerialPort(); public Form1() { InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { g = e.Graphics; pictureBox1.Width = l.Count(); g.DrawLine(new Pen(Color.Black, 1), new Point(0, pictureBox1.Height / 2), new Point(pictureBox1.Width, pictureBox1.Height / 2)); lastPoint = new Point(0,pictureBox1.Height/2); //如果发生值大于最大值,则画笔变为黄色 for (int i = 1; i < this.pictureBox1.Width; i++) { if (l[i] > maxRate/2) { drawPen.Color = Color.Yellow; l[i] = maxRate/2; } else { drawPen.Color = Color.Red; } nowPoint.X = i; double tmpY = l[i] / maxRate; tmpY =Math.Abs( (tmpY * pictureBox1.Height)-(pictureBox1.Height/2)); nowPoint.Y =Convert.ToInt32( tmpY); //nowPoint.Y = Math.Abs(l[i] / maxRate * pictureBox1.Height - pictureBox1.Height); g.DrawLine(drawPen, lastPoint, nowPoint); lastPoint = nowPoint; } } private void Form1_Load(object sender, EventArgs e) { } void comm_dataReceived(object sender, SerialDataReceivedEventArgs e) { if (closing) return; //防止关闭时锁死 string tmpS = comm.ReadLine(); builder.Append(tmpS); string s = builder.ToString(); builder.Clear();//清除字符串构造器 string[] arr = s.Split(' ', ' ').Where(t => t.Trim() != "").ToArray(); ////因为要访问ui资源,所以需要使用invoke方式同步ui。 this.Invoke((EventHandler)(delegate { try { int tmpC=0; listening = true; for (int i = 0; i < arr.Length; i++) { int c = Convert.ToInt32(arr[i]); if (Math.Abs(tmpC - c) > 100) Console.Out.WriteLine("错误"); textBox1.AppendText(Convert.ToString(c)+' '); l.Add(c); tmpC = c; } } catch { ; } finally { listening = false; } pictureBox1.Width = l.Count(); })); } private void button1_Click(object sender, EventArgs e) { comm.PortName = comboBox1.SelectedItem.ToString(); comm.BaudRate =Convert.ToInt32( comboBox2.SelectedItem.ToString()); maxRate =Convert.ToInt32( textBox2.Text); comm.Open(); comm.DataReceived += comm_dataReceived; } private void button2_Click(object sender, EventArgs e) { closing = true; while (listening) Application.DoEvents(); MessageBox.Show("ok"); comm.Close(); closing = false; } private void button4_Click(object sender, EventArgs e) { //16进制发送 if (checkBoxHexSend.Checked) { //我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数 MatchCollection mc = Regex.Matches(txSend.Text, @"(?i)[/da-f]{2}"); List<byte> buf = new List<byte>();//填充到这个临时列表中 //依次添加到列表中 foreach (Match m in mc) { buf.Add(byte.Parse(m.Value)); } //转换列表为数组后发送 comm.Write(buf.ToArray(), 0, buf.Count); } else//ascii编码直接发送 { //包含换行符 if (checkBoxNewlineSend.Checked) { comm.WriteLine(txSend.Text); } else//不包含换行符 { comm.Write(txSend.Text); } } } } } |