c#(winform)通过串口读取并解析数据

1、工具选择

在开发过程中,有时会遇到通过串口读取地磅等数据,但是在真实的环境测试也不方便,这时使用虚拟串口工具就显得非常方便了,虚拟出两个串口,一个模拟发送数据,一个模拟接收数据。

虚拟串口工具:Configure Virtual Serial Port Driver 

串口调试工具:Serial Port Utility

2、程序编写

2.1 winform 中使用串口就需要在左侧工具箱里拖入一个serialPort,如下图所示

                                                

2.2 初始化串口

public SerialPort serialPort;
private bool Listening = false;//是否没有执行完invoke相关操作   
private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke   
#region 初始化串口
        private void InitPort()
        {
            try
            {
                serialPort1.PortName = "COM1";
                serialPort1.BaudRate = 4800;
                serialPort1.DataBits = 8;
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.One;
                serialPort1.WriteTimeout = 3000;
                serialPort1.ReadTimeout = 3000;
                serialPort1.ReceivedBytesThreshold = 1;
                serialPort1.DtrEnable = true;
                serialPort1.RtsEnable = true;
                updateText = new UpdateTextEventHandler(UpdateTextBox);  //实例化委托对象
                serialPort1.Handshake = Handshake.RequestToSend;
                serialPort1.Open();
                //MessageBox.Show("开始");
                button3.Text = "关闭串口";
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

2.3 串口获取数据

我解析这个吊钩秤是通过称一直向外发送数据,程序解析数据,通过截取字符串,获取两个空白之间的数据并显示在文本框上

#region  串口获取数据
        public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
            try
            {
                Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
                Thread.Sleep(600);

                string SDateTemp = "";
                int len = serialPort1.BytesToRead;

                Byte[] readBuffer = new Byte[len];
                serialPort1.Read(readBuffer, 0, len);

                SDateTemp = Encoding.Default.GetString(readBuffer);
                //MessageBox.Show(SDateTemp);


                int L = SDateTemp.IndexOf(" ");
                int length = SDateTemp.Length;
                string str1 = SDateTemp.Substring(L, length - L).Trim();

                int L2 = str1.IndexOf(" ");
                int length2 = str1.Length;
                str2 = str1.Substring(0, L2).Trim();

                if (!string.IsNullOrEmpty(str2))
                {
                    this.BeginInvoke(new UpdateTextEventHandler(UpdateTextBox), new string[] { str2 });
                    //SDateTemp = GetValue(SDateTemp, "@G002", "kg").Trim(); //多少kg
                }

                //this.Invoke(new UpdateTextEventHandler(UpdateTextBox), new string[] { SDateTemp });
                
            }
            finally
            {
                Listening = false;//我用完了,ui可以关闭串口了。   
            }
        }
        #endregion

2.4 到文本框进行显示

private void UpdateTextBox(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                textBox6.Text = text;
            }
        }

3、正则解析

如果串口发送的数据时规范的并且可以用正则解析的话,可以使用下边的方法。

#region 获得字符串中开始和结束字符串之间的值
        /// 
        /// 获得字符串中开始和结束字符串之间的值
        /// 
        /// 字符串
        /// 开始
        /// 结束
        ///  
public static string GetValue(string str, string A, string B)
        {
            Regex rg = new Regex("(?<=(" + A + "))[.\\s\\S]*?(?=(" + B + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            //Regex rg = new Regex("(?<=(" + A + "))[.\\d]*?(?=(" + B + "))", RegexOptions.Multiline | RegexOptions.Singleline);

            return rg.Match(str).Value;
        }
        #endregion

如果采用了上边GetValue方法的话,在serialPort1_DataReceived 方法中,带注释的两行就需要取消注释使用。

你可能感兴趣的:(C#)